Tell us what’s happening:
Passing all tests except to display the winner.
// running tests
10. The game should display a message indicating the winner to be X or O.
// tests completed
It does display the winner when the condition is right, in the same way it shows a draw (passes that test). “X has won!”
It must have something to do with React state but I’m not really sure.
This thread does indicate there might be a browser issue (I am using Firefox)
https://forum.freecodecamp.org/t/build-a-tic-tac-toe-game-build-a-tic-tac-toe-game/751680/5
Your code so far
<!-- file: index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Tic-Tac-Toe</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
<script
data-plugins="transform-modules-umd"
type="text/babel"
src="index.jsx"
></script>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="root"></div>
<script
data-plugins="transform-modules-umd"
type="text/babel"
data-presets="react"
data-type="module"
>
import { Board } from './index.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(<Board />);
</script>
</body>
</html>
/* file: styles.css */
.board {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 equal columns */
grid-template-rows: repeat(3, 1fr); /* 3 equal rows */
gap: 5px;
width: 300px;
height: 300px;
}
button {
width: 100%;
height: 100%;
font-size: 2rem;
cursor: pointer;
}
#reset {
width: 95px;
}
#finish {
width: 100%;
height: 100%;
font-size: 2rem;
display: none;
}
/* file: index.jsx */
const { useState, useRef } = React;
export function Board() {
const initialGrid = [
["", "", ""],
["", "", ""],
["", "", ""]
];
const [turn, setTurn] = useState("X")
const [grid, setGrid] = useState(initialGrid)
const [winner, setWinner] = useState(false)
const [moves, setMoves] = useState(0)
const fin = useRef(null);
const finish = (result) => {
if (result == "tie") {
fin.current.innerText = "It's a tie!"
} else {
fin.current.innerText = `${result} has won!`
}
fin.current.style.display = "block"
}
const handleClick = (x,y) => {
setMoves(moves + 1)
setGrid(prev => {
let na = [...prev]
na[x][y] = turn
checkWin(na)
return na
})
const checkWin = (array) => {
//check for win
//check row
let win = true;
for (let yy=0; yy<=2; yy++) {
if (array[x][yy] != turn) win = false;
}
if (win) {
setWinner(true)
finish(turn)
return}
//check col
win = true;
for (let xx=0; xx<=2; xx++) {
if (array[xx][y] != turn) win = false;
}
if (win) {
setWinner(true)
finish(turn)
return}
//check diags
if (x == 0 && y == 1) return;
if (x == 2 && y == 1) return;
if (x == 1 && y == 0) return;
if (x == 1 && y == 2) return;
win = true;
let yy = 0;
for (let xx=0; xx<=2; xx++) {
//console.log("checking",xx,yy,array[xx][yy])
if (array[xx][yy] != turn) win = false;
yy++;
}
if (win) {
setWinner(true)
finish(turn)
return}
win = true;
yy = 2;
for (let xx=0; xx<=2; xx++) {
//console.log("checking",xx,yy,array[xx][yy])
if (array[xx][yy] != turn) win = false;
yy--;
}
if (win) {
setWinner(true)
finish(turn)
return}
}
console.log(moves)
if (moves == 8) finish("tie")
}
return (
<>
<div className="board">
{
grid.map((row,x) => {
return row.map((square, y) => {
return <button
onClick={(e) => {
if (e.target.innerText != "") return;
console.log(winner)
if (winner) return;
handleClick(x,y);
setTurn(prev => prev == "X"? "O" : "X")
}}
key={x+y}
className="square">{square}</button>
})
})
}
<button onClick={() => {
setMoves(0)
fin.current.style.display = "none"
setWinner(false)
setGrid(initialGrid);
setTurn("X");
}
} id="reset">Reset</button>
</div>
<p id="finish" ref={fin}></p>
</>
)
}
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0
Challenge Information:
Build a Tic-Tac-Toe Game - Build a Tic-Tac-Toe Game