Skip to content

Commit

Permalink
fix(UX): improve UX for setting up a new game
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobTheEldest committed Jun 8, 2023
1 parent 7475f17 commit aa29dcb
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 35 deletions.
68 changes: 52 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface AttributeCount {
revealedCount: number;
hiddenCount: number;
}
type numericalInput = number | '';
type GameResult = 'loss' | 'win' | '';
export interface GameboardContextInterface {
gameId: number;
Expand All @@ -17,7 +18,6 @@ export interface GameboardContextInterface {
rows: number;
cols: number;
mines: number;
setCurrentMines: Dispatch<React.SetStateAction<number>>;
}
export const GameboardContext = createContext<
GameboardContextInterface | undefined
Expand All @@ -37,27 +37,64 @@ const App: React.FC = () => {
const [rows, setRows] = useState(10);
const [cols, setCols] = useState(10);
const [mines, setMines] = useState(10);
const [currentMines, setCurrentMines] = useState(10);
const [nextRows, setNextRows] = useState<numericalInput>(10);
const [nextCols, setNextCols] = useState<numericalInput>(10);
const [nextMines, setNextMines] = useState<numericalInput>(10);

const handleColumnsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newCols = parseInt(e.target.value);
setCols(newCols);
setMines(Math.round((newCols * rows) / 10));
const colsInputValue = parseInt(e.target.value);
if (isNaN(colsInputValue)) {
setNextCols('');
setNextMines(Math.round((cols * rows) / 10));
} else {
setNextCols(colsInputValue);
setNextMines(Math.round((colsInputValue * rows) / 10));
}
};

const handleRowsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newRows = parseInt(e.target.value);
setRows(newRows);
setMines(Math.round((newRows * cols) / 10));
const rowsInputValue = parseInt(e.target.value);
if (isNaN(rowsInputValue)) {
setNextRows('');
setNextMines(Math.round((cols * rows) / 10));
} else {
setNextRows(rowsInputValue);
setNextMines(Math.round((rowsInputValue * cols) / 10));
}
};

const handleMinesChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newMines = parseInt(e.target.value);
setMines(newMines);
const minesInputValue = parseInt(e.target.value);
if (isNaN(minesInputValue)) {
setNextMines('');
} else {
setNextMines(minesInputValue);
}
};

const handleNewGameClick = (e: React.FormEvent) => {
e.preventDefault();

if (typeof nextRows === 'number' && nextRows > 0) {
setRows(nextRows);
} else {
setNextRows(rows);
}
if (typeof nextCols === 'number' && nextCols > 0) {
setCols(nextCols);
} else {
setNextCols(cols);
}
if (
typeof nextMines === 'number' &&
nextMines > 0 &&
nextMines < rows * cols
) {
setMines(nextMines);
} else {
setNextMines(mines);
}

setGameResult('');
setGameId(gameId + 1);

Expand Down Expand Up @@ -89,7 +126,6 @@ const App: React.FC = () => {
rows,
cols,
mines,
setCurrentMines,
}}
>
<div className="">
Expand All @@ -98,8 +134,8 @@ const App: React.FC = () => {
Game ID: {gameId}
<br />
Remaining Unflagged Mines:{' '}
{currentMines - attributeCount.flaggedCount >= 0
? currentMines - attributeCount.flaggedCount
{mines - attributeCount.flaggedCount >= 0
? mines - attributeCount.flaggedCount
: 0}
<br />
<form className="game-difficulty" onSubmit={handleNewGameClick}>
Expand All @@ -109,7 +145,7 @@ const App: React.FC = () => {
name="columns"
className="columns"
onChange={handleColumnsChange}
value={cols ? cols : 0}
value={nextCols}
/>

<span className="rows">Rows:</span>
Expand All @@ -118,7 +154,7 @@ const App: React.FC = () => {
name="rows"
className="rows"
onChange={handleRowsChange}
value={rows ? rows : 0}
value={nextRows}
/>

<span className="mines">Mines:</span>
Expand All @@ -127,7 +163,7 @@ const App: React.FC = () => {
name="mines"
className="mines-input"
onChange={handleMinesChange}
value={mines ? mines : 0}
value={nextMines}
/>

<button type="submit">New Game</button>
Expand Down
31 changes: 12 additions & 19 deletions src/components/Gameboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ const Gameboard = () => {
rows,
cols,
mines,
setCurrentMines,
} = useContext(GameboardContext) as GameboardContextInterface;

const [board, setBoard] = useState<Board>([]);
Expand Down Expand Up @@ -98,7 +97,6 @@ const Gameboard = () => {

const placeMines = useCallback(
(rows: number, cols: number, mines: number, board: Board) => {
setCurrentMines(mines);
const updatedBoard = board;

while (mines > 0) {
Expand All @@ -113,25 +111,22 @@ const Gameboard = () => {

return updatedBoard;
},
[setCurrentMines],
[],
);

const buildBoard = useCallback(
(rows: number, cols: number, mines: number) => {
const emptyBoard = generateEmptyBoard(rows, cols);
const buildBoard = useCallback(() => {
const emptyBoard = generateEmptyBoard(rows, cols);

const minedBoard = placeMines(rows, cols, mines, emptyBoard);
const minedBoard = placeMines(rows, cols, mines, emptyBoard);

minedBoard.forEach((row: Array<cell>) => {
row.forEach((cell) => {
cell.queryNeighbors(minedBoard);
});
minedBoard.forEach((row: Array<cell>) => {
row.forEach((cell) => {
cell.queryNeighbors(minedBoard);
});
});

setBoard(minedBoard);
},
[generateEmptyBoard, placeMines],
);
setBoard(minedBoard);
}, [generateEmptyBoard, placeMines, rows, cols, mines]);

const countAttributes = (board: Board) => {
let flaggedCount = 0;
Expand Down Expand Up @@ -224,7 +219,6 @@ const Gameboard = () => {
};

const handleLeftClick = (e: React.MouseEvent, cell: cell) => {
// console.log('left click on:', cell);
e.preventDefault();

// Don't do anything if game is over
Expand All @@ -244,7 +238,6 @@ const Gameboard = () => {
};

const handleRightClick = (e: React.MouseEvent, cell: cell) => {
// console.log('right click on:', cell);
e.preventDefault();

// Don't do anything if game is over
Expand All @@ -265,8 +258,8 @@ const Gameboard = () => {

// Build a new board when the gameId changes
useEffect(() => {
buildBoard(rows, cols, mines);
}, [gameId, buildBoard, rows, cols, mines]);
buildBoard();
}, [gameId, buildBoard]);

let boardCSSClassString = 'board';
if (gameResult !== '') {
Expand Down

0 comments on commit aa29dcb

Please sign in to comment.