Tell us what’s happening:
I cannot pass test 9, I’ve tried different ways to disable the buttons but all of them make me fail test 8, 9, 10 and 11.
Test 9 says:
9. Clicking on a button.square element after the game has ended should result in no change.
I tried the following solutions:
- inside
handleClickI added an if statement to check ifwinOrDrawis true, if it is return; - Making the if statement in
handleClickbeif (!squares[row][col] && !winOrDraw)so the buttons would only work if the button’s textContent is empty AND there was no win/draw; - Adding the disabled attribute in each of the nine buttons and setting it to
{winOrDraw}so whenever there was a win or a draw all buttons would be disabled.
In each of these tries the same thing happened, it went from only test no. 9 failing to tests 8 to 11 failing even though the preview window looked fine.
I don’t know which other approaches I could use to make the buttons not do anything after the game is ended except maybe setting up a condition in the onClick attribute of each button, but that would likely have the same result, what am I missing here?
I should add that looking in the console there is an Error object with the following properties, not sure what they mean:
actual: "O"
expected: undefined
message: "expected 'O' to not include 'O'"
operator: "notStrictEqual"
showDiff: false
stack: "@https://www.freecodecamp.org/js/test-runner/9.0.0/dom-test-evaluator.js line 2 > eval:16:16\n"
Your code so far
<!-- file: index.html -->
/* file: styles.css */
#container {
display: flex;
flex-direction: column;
align-items: center;
}
.square {
width: 50px;
height: 50px;
}
/* file: index.jsx */
const { useState } = React;
export function Board() {
const [squares, setSquares] = useState([['', '', ''], ['', '', ''], ['', '', '']])
const [currPlayer, setCurrPlayer] = useState('X');
const [winOrDraw, setWinOrDraw] = useState(false);
const [msg, setMsg] = useState('');
function handleClick(row, col) {
//if (winOrDraw) return;
if (!squares[row][col]) {
const copyArr = squares.map(r => [...r]);
copyArr[row][col] = currPlayer;
setSquares(copyArr);
setCurrPlayer(() => currPlayer === 'X' ? 'O' : 'X');
handleWinnerOrTie(copyArr)
}
}
function handleReset() {
setSquares([['', '', ''], ['', '', ''], ['', '', '']]);
setCurrPlayer('X');
}
function handleWinnerOrTie(board = squares) {
let winner = '';
for (let i = 0; i <= 2; i++) {
const xRowCheck = board[i].every(col => col === 'X');
const xColCheck = [board[0][i], board[1][i], board[2][i]].every(col => col === 'X');
const oRowCheck = board[i].every(col => col === 'O');
const oColCheck = [board[0][i], board[1][i], board[2][i]].every(col => col === 'O');
if (xRowCheck || xColCheck) {
winner = 'X';
}
else if (oRowCheck || oColCheck) {
winner = 'O';
}
}
if (!winner.length) {
const xDiagCheck1 = [board[0][0], board[1][1], board[2][2]].every(col => col === 'X');
const xDiagCheck2 = [board[2][0], board[1][1], board[0][2]].every(col => col === 'X');
const oDiagCheck1 = [board[0][0], board[1][1], board[2][2]].every(col => col === 'O');
const oDiagCheck2 = [board[2][0], board[1][1], board[0][2]].every(col => col === 'O');
if (xDiagCheck1 || xDiagCheck2) {
winner = 'X';
}
else if (oDiagCheck1 || oDiagCheck2) {
winner = 'O';
}
}
if (winner) {
setWinOrDraw(true);
setMsg(`Winner: ${winner}!`);
}
else {
let allChecked = board[0].every(c => c) && board[1].every(c => c) && board[2].every(c => c);
if (allChecked) {
setWinOrDraw(true);
setMsg('It was a Tie!');
}
}
}
return (
<div id="container">
<h1>Tic-Tac-Toe</h1>
<h3>{!winOrDraw ? `Next Player: ${currPlayer}` : msg}</h3>
<div className="row">
<button onClick={() => handleClick(0, 0)} className="square">{squares[0][0]}</button>
<button onClick={() => handleClick(0, 1)} className="square">{squares[0][1]}</button>
<button onClick={() => handleClick(0, 2)} className="square">{squares[0][2]}</button>
</div>
<div className="row">
<button onClick={() => handleClick(1, 0)} className="square">{squares[1][0]}</button>
<button onClick={() => handleClick(1, 1)} className="square">{squares[1][1]}</button>
<button onClick={() => handleClick(1, 2)} className="square">{squares[1][2]}</button>
</div>
<div className="row">
<button onClick={() => handleClick(2, 0)} className="square">{squares[2][0]}</button>
<button onClick={() => handleClick(2, 1)} className="square">{squares[2][1]}</button>
<button onClick={() => handleClick(2, 2)} className="square">{squares[2][2]}</button>
</div>
<button id="reset" onClick={handleReset}>RESET</button>
</div>
)
}
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0
Challenge Information:
Build a Tic-Tac-Toe Game - Build a Tic-Tac-Toe Game
