✨ Handling winning game
This commit is contained in:
@@ -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;
|
||||||
|
};
|
||||||
|
|||||||
@@ -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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user