diff react_games/public/games/main-KK4JGOCU.js @ 37:fb9bcd3145cb

[ReactGames] Few games I made using react just to practice few things.
author MrJuneJune <me@mrjunejune.com>
date Mon, 01 Dec 2025 20:22:47 -0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/react_games/public/games/main-KK4JGOCU.js	Mon Dec 01 20:22:47 2025 -0800
@@ -0,0 +1,191 @@
+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