view react_games/public/games/main-KK4JGOCU.js @ 155:3bb45eb67906

[Postdog] Updated variables names and padding sizes. Needs more work.
author June Park <parkjune1995@gmail.com>
date Mon, 12 Jan 2026 09:12:31 -0800
parents fb9bcd3145cb
children
line wrap: on
line source

import {
  __toESM,
  require_jsx_runtime,
  require_react
} from "./chunk-AX5M7HF6.js";

// src/Minesweeper/main.tsx
var import_react = __toESM(require_react());
var import_jsx_runtime = __toESM(require_jsx_runtime());
var MAX_SIZE_LEN = 10;
var N_BOMBS = 10;
var DIRECTION = [
  [0, 1],
  [1, 1],
  [1, 0],
  [1, -1],
  [0, -1],
  [-1, -1],
  [-1, 0],
  [-1, 1]
];
var constructGameState = () => {
  let board = Array.from(
    { length: MAX_SIZE_LEN },
    () => Array.from(
      { length: MAX_SIZE_LEN },
      () => ({
        value: 0 /* EMPTY */,
        numberOfAdjacentBomb: 0,
        isShown: false,
        isFlag: false
      })
    )
  );
  let placedBomb = 0;
  const bombPlacments = [];
  while (placedBomb < N_BOMBS) {
    const bombRowIdx = Math.floor(Math.random() * MAX_SIZE_LEN);
    const bombColIdx = Math.floor(Math.random() * MAX_SIZE_LEN);
    if (board[bombRowIdx][bombColIdx].value === 0 /* EMPTY */) {
      board[bombRowIdx][bombColIdx] = {
        ...board[bombRowIdx][bombColIdx],
        value: 1 /* BOMB */
      };
      placedBomb++;
      bombPlacments.push([bombRowIdx, bombColIdx]);
    }
  }
  for (const [bombR, bombC] of bombPlacments) {
    for (const [dr, dc] of DIRECTION) {
      if (board[bombR + dr]?.[bombC + dc]?.value === 0 /* EMPTY */) {
        board[bombR + dr][bombC + dc] = {
          ...board[bombR + dr][bombC + dc],
          numberOfAdjacentBomb: board[bombR + dr][bombC + dc].numberOfAdjacentBomb + 1
        };
      }
    }
  }
  return {
    board,
    status: "Reveal all the map while not clicking on mine" /* PLAYABLE */
  };
};
var gameStateReducer = (state, action) => {
  switch (action.type) {
    case 0 /* CHECK */:
      const { position } = action;
      const board = state.board.map((row) => row.map((col) => ({ ...col })));
      const start = board[position.row][position.col];
      if (start.value === 1 /* BOMB */) {
        for (const row of board) for (const cell of row) cell.isShown = true;
        return { board, status: "YOU LOST" /* LOST */ };
      }
      if (!start.isShown) start.isShown = true;
      if (start.numberOfAdjacentBomb === 0) {
        const q = [position];
        while (q.length) {
          const { row, col } = q.shift();
          for (const [dr, dc] of DIRECTION) {
            const r = row + dr, c = col + dc;
            const n = board[r]?.[c];
            if (!n || n.isShown || n.value === 1 /* BOMB */) continue;
            n.isShown = true;
            if (n.numberOfAdjacentBomb === 0) q.push({ row: r, col: c });
          }
        }
      }
      const hidden = board.flat().filter((c) => !c.isShown).length;
      const status = hidden === N_BOMBS ? "YOU WON" /* WON */ : "Reveal all the map while not clicking on mine" /* PLAYABLE */;
      return { board, status };
    case 2 /* FLAG */:
      const newBoard = state.board.map(
        (row, rowIdx) => rowIdx === action.position.row ? row.map(
          (col, colIdx) => colIdx === action.position.col ? { ...col, isFlag: true } : col
        ) : row
      );
      console.log(newBoard);
      return {
        ...state,
        board: newBoard
      };
    case 1 /* RESET */:
      return constructGameState();
  }
};
var styles = {
  board: {
    display: "grid",
    gridTemplateColumns: `repeat(${MAX_SIZE_LEN}, 1fr)`,
    width: 400
  },
  cell: {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    width: "100%",
    aspectRatio: "1 / 1",
    border: "1px solid black",
    backgroundColor: "#e6e6e6"
  }
};
var CellComponent = (0, import_react.memo)(({
  cellValue,
  row,
  col,
  placeDispatch,
  flagDispatch
}) => {
  console.log("re-render");
  const handleOnClikck = (0, import_react.useCallback)(() => {
    placeDispatch(row, col);
  }, [row, col, placeDispatch]);
  const handleOnRightClikck = (0, import_react.useCallback)((event) => {
    event.preventDefault();
    flagDispatch(row, col);
  }, [row, col, placeDispatch]);
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      style: {
        ...styles.cell,
        cursor: "pointer",
        backgroundColor: cellValue.isShown ? "#fafafa" : "#e6e6e6"
      },
      onClick: handleOnClikck,
      onContextMenu: handleOnRightClikck,
      children: cellValue.isShown ? cellValue.value === 1 /* BOMB */ ? "\u{1F4A3}" : cellValue.numberOfAdjacentBomb || "" : cellValue.isFlag ? "\u{1F6A9}" : ""
    }
  );
}, (prev, next) => prev.cellValue.isShown === next.cellValue.isShown && prev.cellValue.isFlag === next.cellValue.isFlag);
var Minesweeper = () => {
  const [state, dispatch] = (0, import_react.useReducer)(gameStateReducer, null, constructGameState);
  const placeDispatch = (0, import_react.useCallback)(
    (row, col) => {
      dispatch({ type: 0 /* CHECK */, position: { row, col } });
    },
    [dispatch]
  );
  const flagDispatch = (0, import_react.useCallback)(
    (row, col) => {
      dispatch({ type: 2 /* FLAG */, position: { row, col } });
    },
    [dispatch]
  );
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
    /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h1", { children: [
      " ",
      state.status,
      " "
    ] }),
    /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: styles.board, children: state.board.map(
      (row, rowIdx) => row.map(
        (cell, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          CellComponent,
          {
            cellValue: cell,
            row: rowIdx,
            col: colIdx,
            placeDispatch,
            flagDispatch
          },
          `${rowIdx}-${colIdx}`
        )
      )
    ) })
  ] });
};
export {
  Minesweeper
};
//# sourceMappingURL=main-KK4JGOCU.js.map