Handling winning game

This commit is contained in:
2024-02-18 18:05:04 +01:00
parent 049110e15e
commit 1377c3a8fa
2 changed files with 60 additions and 9 deletions
+60 -8
View File
@@ -23,19 +23,26 @@ export const useActions = (grid: GridType, setGrid: React.Dispatch<React.SetStat
const handleLeftClick = (ev: MouseEvent, rowIndex: number, colIndex: number) => { const handleLeftClick = (ev: MouseEvent, rowIndex: number, colIndex: number) => {
ev.preventDefault(); ev.preventDefault();
// Only have action if the cell is hidden and has not a flag on it
if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) { if (grid[rowIndex][colIndex].hidden && !grid[rowIndex][colIndex].flag) {
setGrid((prev) => { setGrid((prev) => {
let bombsCount: number | null = null;
// Start the game with making sure the clicked cell will be empty after generation
if (gameState.status === 'idle') { if (gameState.status === 'idle') {
const { grid: newGrid, bombsCount } = startGame(prev, gameState.difficulty as Difficulty, true, rowIndex, colIndex); const { grid: newGrid, bombsCount: _bombsCount } = startGame(prev, gameState.difficulty as Difficulty, true, rowIndex, colIndex);
prev = newGrid; prev = newGrid;
bombsCount = _bombsCount;
setGameState((prevGameState) => ({ setGameState((prevGameState) => ({
...prevGameState, ...prevGameState,
status: 'playing', status: 'playing',
bombs: bombsCount, bombs: _bombsCount,
})); }));
} }
// If the clicked cell hide a bomb, loose immediatly
if (prev[rowIndex][colIndex].value === 'bomb') { if (prev[rowIndex][colIndex].value === 'bomb') {
setGameState((prev) => ({ setGameState((prev) => ({
...prev, ...prev,
@@ -43,14 +50,25 @@ export const useActions = (grid: GridType, setGrid: React.Dispatch<React.SetStat
})); }));
return revealAllGrid(grid, true); return revealAllGrid(grid, true);
} }
// Discover surronding cells if the clicked is empty
else if (prev[rowIndex][colIndex].value === 'empty') {
prev = discoverAroundCell(prev, rowIndex, colIndex);
} else {
prev[rowIndex][colIndex].hidden = false;
}
if (prev[rowIndex][colIndex].value === 'empty') { if (hasWin(prev, bombsCount || gameState.bombs)) {
return discoverAroundCell(prev, rowIndex, colIndex); setGameState((prev) => ({
...prev,
endType: 'win',
}));
return revealAllGrid(grid, true);
} }
prev[rowIndex][colIndex].hidden = false;
return prev; return prev;
}); });
// Since React state cannot see if a large nested object has changed, we need to call a forceUpdate method
forceUpdate(); forceUpdate();
} }
}; };
@@ -58,20 +76,26 @@ export const useActions = (grid: GridType, setGrid: React.Dispatch<React.SetStat
const handleRightClick = (ev: MouseEvent, rowIndex: number, colIndex: number) => { const handleRightClick = (ev: MouseEvent, rowIndex: number, colIndex: number) => {
ev.preventDefault(); ev.preventDefault();
// Only have action if the cell is hidden
if (grid[rowIndex][colIndex].hidden) { if (grid[rowIndex][colIndex].hidden) {
setGrid((prev) => { setGrid((prev) => {
let bombsCount: number | null = null;
// Start the game without making sure the clicked cell will be empty after generation
if (gameState.status === 'idle') { if (gameState.status === 'idle') {
const { grid: newGrid, bombsCount } = startGame(prev, gameState.difficulty as Difficulty, false); const { grid: newGrid, bombsCount: _bombsCount } = startGame(prev, gameState.difficulty as Difficulty, false);
prev = newGrid; prev = newGrid;
bombsCount = _bombsCount;
setGameState((prevGameState) => ({ setGameState((prevGameState) => ({
...prevGameState, ...prevGameState,
status: 'playing', status: 'playing',
bombs: bombsCount, bombs: _bombsCount,
})); }));
} }
return prev.map((row, idx) => { prev = 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) {
@@ -90,6 +114,16 @@ export const useActions = (grid: GridType, setGrid: React.Dispatch<React.SetStat
} }
return row; return row;
}); });
if (hasWin(prev, bombsCount || gameState.bombs)) {
setGameState((prev) => ({
...prev,
endType: 'win',
}));
return revealAllGrid(grid, true);
}
return prev;
}); });
} }
}; };
@@ -99,3 +133,21 @@ export const useActions = (grid: GridType, setGrid: React.Dispatch<React.SetStat
handleRightClick, handleRightClick,
}; };
}; };
const hasWin = (grid: GridType, bombs: number) => {
let bombsFlagged = 0;
grid.map((row) => {
row.map((cell) => {
if (cell.value === 'bomb' && cell.flag === true) {
bombsFlagged++;
}
});
});
if (bombsFlagged === bombs) {
return true;
}
return false;
};
-1
View File
@@ -166,7 +166,6 @@ export const startGame = (grid: GridType, difficulty: Difficulty, needEmpty: boo
} while (grid[rowIndex][colIndex].value !== 'empty'); } while (grid[rowIndex][colIndex].value !== 'empty');
grid = genNumbers(grid); grid = genNumbers(grid);
// console.log(grid, bombsCount);
return { grid, bombsCount }; return { grid, bombsCount };
} }