Mercurial
view react_games/public/games/main-QNFKFAB2.js @ 149:f41ac17926d2
[Config] Added ctags scripts and actual tags.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Sat, 10 Jan 2026 07:07:10 -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}` ) ) ) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { onClick: () => { dispatch({ type: 1 /* RESET */ }); }, children: " reset " }) ] }); }; export { Minesweeper }; //# sourceMappingURL=main-QNFKFAB2.js.map