✨ (game): Added Bombs & Flags count
Added placed flags by bombs count. Fix timer startng only when first click is triggered
This commit is contained in:
Generated
+25
@@ -15,6 +15,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
"recoil": "^0.7.7",
|
||||||
"sass": "^1.70.0",
|
"sass": "^1.70.0",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
@@ -8963,6 +8964,11 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hamt_plus": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hamt_plus/-/hamt_plus-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
|
||||||
|
},
|
||||||
"node_modules/handle-thing": {
|
"node_modules/handle-thing": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
||||||
@@ -15337,6 +15343,25 @@
|
|||||||
"node": ">=8.10.0"
|
"node": ">=8.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/recoil": {
|
||||||
|
"version": "0.7.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/recoil/-/recoil-0.7.7.tgz",
|
||||||
|
"integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"hamt_plus": "1.0.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.13.1"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react-dom": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/recursive-readdir": {
|
"node_modules/recursive-readdir": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "5.0.1",
|
||||||
|
"recoil": "^0.7.7",
|
||||||
"sass": "^1.70.0",
|
"sass": "^1.70.0",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
|
|||||||
+13
-2
@@ -4,6 +4,17 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
& > .stats {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& > .logo {
|
||||||
|
width: 75px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-4
@@ -1,12 +1,33 @@
|
|||||||
import './App.scss';
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Context -------------------------------------------------------
|
||||||
|
import { RecoilRoot } from 'recoil';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// --------------------------------------------------- Components ------------------------------------------------------
|
||||||
import Grid from './components/Grid/Grid';
|
import Grid from './components/Grid/Grid';
|
||||||
import Timer from './components/Timer/Timer';
|
import Timer from './components/Stats/Timer/Timer';
|
||||||
|
import MinesCounter from './components/Stats/MinesCounter/MinesCounter';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Styles --------------------------------------------------------
|
||||||
|
import './App.scss';
|
||||||
|
import Logo from './assets/logo';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<div className='App'>
|
<div className='App'>
|
||||||
<Timer />
|
<RecoilRoot>
|
||||||
<Grid />
|
<div className='stats'>
|
||||||
|
<Timer />
|
||||||
|
<Logo className={'logo'} />
|
||||||
|
<MinesCounter />
|
||||||
|
</div>
|
||||||
|
<Grid />
|
||||||
|
</RecoilRoot>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const Flag = (props: any) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d='M80 464V68.14a8 8 0 014-6.9C91.81 56.66 112.92 48 160 48c64 0 145 48 192 48a199.53 199.53 0 0077.23-15.77 2 2 0 012.77 1.85v219.36a4 4 0 01-2.39 3.65C421.37 308.7 392.33 320 352 320c-48 0-128-32-192-32s-80 16-80 16'
|
||||||
|
fill='none'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeMiterlimit='10'
|
||||||
|
strokeWidth='32'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Flag;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
const Logo = (props: any) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
viewBox='0 0 512 512'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{/* Edges */}
|
||||||
|
<path
|
||||||
|
d='M256 32 l0 448 M32 256 l448 0 M112 112 l286 286 M400 112 L112 400'
|
||||||
|
stroke='currentColor'
|
||||||
|
strokeLinecap='round'
|
||||||
|
strokeMiterlimit='10'
|
||||||
|
strokeWidth={32}
|
||||||
|
/>
|
||||||
|
{/* Main circle */}
|
||||||
|
<circle
|
||||||
|
cx={256}
|
||||||
|
cy={256}
|
||||||
|
r={150}
|
||||||
|
fill='currentColor'
|
||||||
|
/>
|
||||||
|
{/* Light on main circle */}
|
||||||
|
<circle
|
||||||
|
cx={206}
|
||||||
|
cy={206}
|
||||||
|
r={40}
|
||||||
|
fill='#ffffff'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Logo;
|
||||||
@@ -3,12 +3,17 @@
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------------ React --------------------------------------------------------
|
// ------------------------------------------------------ React --------------------------------------------------------
|
||||||
import { MouseEvent, useCallback, useEffect, useState } from 'react';
|
import { MouseEvent, useCallback, useState } from 'react';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Context -------------------------------------------------------
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { gameStateAtom } from '../../contexts/gameState';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ------------------------------------------------------ Utils --------------------------------------------------------
|
// ------------------------------------------------------ Utils --------------------------------------------------------
|
||||||
import { Difficulty } from '../../types/game';
|
import { Difficulty } from '../../types/game';
|
||||||
import { discoverAroundCell, genBombs, genGrid, genNumbers } from '../../utils/game';
|
import { discoverAroundCell, genGrid, startGame } from '../../utils/game';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ----------------------------------------------------- Assets --------------------------------------------------------
|
// ----------------------------------------------------- Assets --------------------------------------------------------
|
||||||
@@ -18,8 +23,9 @@ import './styles.scss';
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const Grid = ({ size = 12, difficulty = 'beginner' }) => {
|
const Grid = ({ size = 12, difficulty = 'beginner' }) => {
|
||||||
|
const [gameState, setGameState] = useRecoilState(gameStateAtom);
|
||||||
|
|
||||||
const [grid, setGrid] = useState(genGrid(size));
|
const [grid, setGrid] = useState(genGrid(size));
|
||||||
const [gameStatus, setGameStatus] = useState('idle');
|
|
||||||
|
|
||||||
const [, updateGrid] = useState({});
|
const [, updateGrid] = useState({});
|
||||||
const forceUpdate = useCallback(() => updateGrid({}), []);
|
const forceUpdate = useCallback(() => updateGrid({}), []);
|
||||||
@@ -30,11 +36,15 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
|
|||||||
|
|
||||||
if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) {
|
if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) {
|
||||||
setGrid((prev) => {
|
setGrid((prev) => {
|
||||||
if (gameStatus === 'idle') {
|
if (gameState.status === 'idle') {
|
||||||
do {
|
const { grid: newGrid, bombsCount } = startGame(prev, difficulty as Difficulty, true, rowIndex, colIndex);
|
||||||
prev = genNumbers(genBombs(prev, difficulty as Difficulty));
|
prev = newGrid;
|
||||||
} while (prev[rowIndex][colIndex].value !== 'empty');
|
|
||||||
setGameStatus('started');
|
setGameState((prevGameState) => ({
|
||||||
|
...prevGameState,
|
||||||
|
status: 'playing',
|
||||||
|
bombs: bombsCount,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return discoverAroundCell(prev, rowIndex, colIndex);
|
return discoverAroundCell(prev, rowIndex, colIndex);
|
||||||
@@ -48,10 +58,26 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
|
|||||||
|
|
||||||
if (grid[rowIndex][colIndex].hidden) {
|
if (grid[rowIndex][colIndex].hidden) {
|
||||||
setGrid((prev) => {
|
setGrid((prev) => {
|
||||||
|
if (gameState.status === 'idle') {
|
||||||
|
const { grid: newGrid, bombsCount } = startGame(prev, difficulty as Difficulty, false);
|
||||||
|
prev = newGrid;
|
||||||
|
|
||||||
|
setGameState((prevGameState) => ({
|
||||||
|
...prevGameState,
|
||||||
|
status: 'playing',
|
||||||
|
bombs: bombsCount,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
return prev.map((row, idx) => {
|
return prev.map((row, idx) => {
|
||||||
if (idx === rowIndex) {
|
if (idx === rowIndex) {
|
||||||
return row.map((col, idy) => {
|
return row.map((col, idy) => {
|
||||||
if (idy === colIndex) {
|
if (idy === colIndex) {
|
||||||
|
setGameState((prevGameState) => ({
|
||||||
|
...prevGameState,
|
||||||
|
placedFlags: col.flag ? prevGameState.placedFlags - 1 : prevGameState.placedFlags + 1,
|
||||||
|
}));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...col,
|
...col,
|
||||||
flag: !col.flag,
|
flag: !col.flag,
|
||||||
@@ -65,21 +91,6 @@ const Grid = ({ size = 12, difficulty = 'beginner' }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Development
|
|
||||||
useEffect(() => {
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
document.addEventListener('keyup', (ev) => {
|
|
||||||
if (ev.key === 'v') {
|
|
||||||
setGrid(() => {
|
|
||||||
let newGrid = genGrid(size);
|
|
||||||
|
|
||||||
return genNumbers(genBombs(newGrid, difficulty as Difficulty));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [size, difficulty]);
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
//! Imports
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Recoil --------------------------------------------------------
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { gameStateAtom } from '../../../contexts/gameState';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// ----------------------------------------------------- Assets --------------------------------------------------------
|
||||||
|
import Flag from '../../../assets/flag';
|
||||||
|
import '../styles.scss';
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const MinesCounter = () => {
|
||||||
|
const [{ bombs, placedFlags }] = useRecoilState(gameStateAtom);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='statContainer'>
|
||||||
|
<Flag />
|
||||||
|
<p>
|
||||||
|
{placedFlags} / {bombs}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MinesCounter;
|
||||||
@@ -7,32 +7,46 @@ import { useEffect, useState } from 'react';
|
|||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// ----------------------------------------------------- Assets --------------------------------------------------------
|
// ----------------------------------------------------- Assets --------------------------------------------------------
|
||||||
import Clock from '../../assets/clock';
|
import Clock from '../../../assets/clock';
|
||||||
import './styles.scss';
|
import '../styles.scss';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { gameStateAtom } from '../../../contexts/gameState';
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
const Timer = () => {
|
const Timer = () => {
|
||||||
const [startedTime] = useState<number>(Date.now());
|
const [{ status }] = useRecoilState(gameStateAtom);
|
||||||
|
|
||||||
|
const [startedTime, setStartedTime] = useState<number | null>(null);
|
||||||
const [displayedTime, setDisplayedTime] = useState<string>('00:00');
|
const [displayedTime, setDisplayedTime] = useState<string>('00:00');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(() => {
|
if (status === 'playing') {
|
||||||
const elapsedTime = (Date.now() - startedTime) / 1000;
|
setStartedTime(Date.now());
|
||||||
|
} else if (status === 'win' || status === 'loose') {
|
||||||
|
setStartedTime(null);
|
||||||
|
}
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
const seconds = Math.floor(elapsedTime % 60);
|
useEffect(() => {
|
||||||
const strSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
|
if (startedTime) {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
const elapsedTime = (Date.now() - startedTime) / 1000;
|
||||||
|
|
||||||
const minutes = Math.floor(elapsedTime / 60);
|
const seconds = Math.floor(elapsedTime % 60);
|
||||||
const strMinute = minutes < 10 ? `0${minutes}` : `${minutes}`;
|
const strSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
|
||||||
|
|
||||||
setDisplayedTime(`${strMinute}:${strSeconds}`);
|
const minutes = Math.floor(elapsedTime / 60);
|
||||||
}, 500);
|
const strMinute = minutes < 10 ? `0${minutes}` : `${minutes}`;
|
||||||
|
|
||||||
return () => clearInterval(interval);
|
setDisplayedTime(`${strMinute}:${strSeconds}`);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}
|
||||||
}, [startedTime]);
|
}, [startedTime]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='timer'>
|
<div className='statContainer'>
|
||||||
<Clock />
|
<Clock />
|
||||||
<p>{displayedTime}</p>
|
<p>{displayedTime}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
.timer {
|
.statContainer {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 25px 40px;
|
grid-template-columns: 25px 40px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
export const gameStateAtom = atom({
|
||||||
|
key: 'gameState',
|
||||||
|
default: {
|
||||||
|
bombs: 0,
|
||||||
|
placedFlags: 0,
|
||||||
|
status: 'idle',
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -9,6 +9,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
#root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
width: 100svw;
|
width: 100svw;
|
||||||
height: 100svh;
|
height: 100svh;
|
||||||
background: #598b8e;
|
background: #598b8e;
|
||||||
|
|||||||
+36
-3
@@ -5,6 +5,7 @@ export const genGrid = (size: number): GridType => {
|
|||||||
let grid: GridType = Array.apply(null, Array(size)).map(() => {
|
let grid: GridType = Array.apply(null, Array(size)).map(() => {
|
||||||
return Array.apply(null, Array(size)).map(() => {
|
return Array.apply(null, Array(size)).map(() => {
|
||||||
return {
|
return {
|
||||||
|
// hidden: false,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
value: 'empty',
|
value: 'empty',
|
||||||
flag: false,
|
flag: false,
|
||||||
@@ -12,6 +13,9 @@ export const genGrid = (size: number): GridType => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// grid = genBombs(grid, 'beginner');
|
||||||
|
// grid = genNumbers(grid);
|
||||||
|
|
||||||
return grid;
|
return grid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,11 +32,11 @@ export const genBombs = (grid: GridType, difficulty: Difficulty) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bombs = Math.floor(bombs);
|
bombs = Math.floor(bombs);
|
||||||
|
for (let i = 1; i <= bombs; i++) {
|
||||||
for (let i = 0; i <= bombs; i++) {
|
|
||||||
let needRegenerate = false;
|
let needRegenerate = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
needRegenerate = false;
|
||||||
const row = getRandomArbitrary(0, grid.length);
|
const row = getRandomArbitrary(0, grid.length);
|
||||||
const col = getRandomArbitrary(0, grid.length);
|
const col = getRandomArbitrary(0, grid.length);
|
||||||
let bombsArounds = 0;
|
let bombsArounds = 0;
|
||||||
@@ -69,7 +73,7 @@ export const genBombs = (grid: GridType, difficulty: Difficulty) => {
|
|||||||
} while (needRegenerate);
|
} while (needRegenerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
return grid;
|
return { grid: grid, bombsCount: bombs };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const genNumbers = (grid: GridType): GridType => {
|
export const genNumbers = (grid: GridType): GridType => {
|
||||||
@@ -141,3 +145,32 @@ export const revealAllGrid = (grid: GridType, excludeGoodFlags: boolean = true)
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const startGame = (grid: GridType, difficulty: Difficulty, needEmpty: boolean = true, rowIndex?: number, colIndex?: number): { grid: GridType; bombsCount: number } => {
|
||||||
|
if (needEmpty) {
|
||||||
|
if (rowIndex === undefined || rowIndex < 0 || rowIndex >= grid.length) {
|
||||||
|
throw Error('Missing rowIndex and/or colIndex parameters.');
|
||||||
|
} else if (colIndex === undefined || colIndex < 0 || colIndex >= grid[rowIndex].length) {
|
||||||
|
throw Error('Missing rowIndex and/or colIndex parameters.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let bombsCount = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const { grid: bombsGrid, bombsCount: bombsCountFromGen } = genBombs(grid, difficulty as Difficulty);
|
||||||
|
grid = bombsGrid;
|
||||||
|
|
||||||
|
bombsCount = bombsCountFromGen;
|
||||||
|
} while (grid[rowIndex][colIndex].value !== 'empty');
|
||||||
|
|
||||||
|
grid = genNumbers(grid);
|
||||||
|
return { grid, bombsCount };
|
||||||
|
}
|
||||||
|
|
||||||
|
const { grid: bombsGrid, bombsCount } = genBombs(grid, difficulty);
|
||||||
|
grid = bombsGrid;
|
||||||
|
|
||||||
|
grid = genNumbers(grid);
|
||||||
|
|
||||||
|
return { grid, bombsCount };
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user