Build a Tic-Tac-Toe Game - Build a Tic-Tac-Toe Game

Tell us what’s happening:

I am having problems passing tests 9-10. It looks right on my end so I assume it’s some sort of formatting issue.
Tests:
Failed: 9. Clicking on a button.square element after the game has ended should result in no change.
Failed: 10. The game should display a message indicating the winner to be X or O.
Failed: 11. The game should display a message indicating a draw.

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: index.jsx */
const { useState, useEffect } = React;

export function Board() {
  const [board, setBoard] = useState([[null, null, null], [null, null, null], [null, null, null]]) 
  const [winner, setWinner] = useState(null)
 
  let flattened = board.flat()
  let count = flattened.filter(x => x === null).length
  
  function play(i,j) {
    if (board[i][j] === null) {
      setBoard(prevBoard =>
        prevBoard.map((item, indexCol) =>
         indexCol === i ? 
          (item.map((element, indexRow) => indexRow === j ? ((count % 2 === 0) ? "O":"X") : element)): item
    ))}
  }

  function checkWin(){ 
    let localWinner = null;
    //checking horizontal wins
    for (let i = 0; i < board[0].length; i++) {
      let temp = board[i].filter(x => x === board[i][0])
      if (temp.length == 3 && board[i][0] != null){
        setWinner(board[i][0])
        localWinner = board[i][0]
        break
      }
    }
    //vertical wins
    for (let i = 0; i < board[0].length; i++) { 
      if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != null){
        setWinner(board[0][i])
        localWinner = board[0][i]
        break
      }
    }
    //diagonal wins
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != null){
        setWinner(board[0][0])
        localWinner = board[0][0]
      }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][0] != null){
      setWinner(board[0][0])
      localWinner = board[0][0]
    }
    //checking for tie
    if (count == 0 && winner == null && localWinner == null) {
      setWinner("No one")
    }
  }

   useEffect(() => {
    checkWin();
  }, [board]);

  return <div>
    <h2>{(count % 2 === 0) ? "O" : "X"}'s Turn </h2>
    <div>
      {board.map((row, i) => (<div key={i}>
        {row.map((element, j)  => (<Button key={i+'key'+j} turn={element} winner={winner} onClick={() => play(i,j)}/>)) }</div>)
      )}
    </div>
    <p>{winner ? "Winner: " + winner : ""}</p>
    <button id='reset' onClick={() => {setBoard([[null, null, null], [null, null, null], [null, null, null]])
      setWinner(null)
    }}>Reset</button>
  </div>
}

export function Button(props) {
  return <button className='square' onClick={props.winner ? null : props.onClick}>{props.turn}</button>
}


/* file: styles.css */

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:150.0) Gecko/20100101 Firefox/150.0

Challenge Information:

Build a Tic-Tac-Toe Game - Build a Tic-Tac-Toe Game

not sure what I did, but it doesn’t always work for me:

I made this updates so hopefuly the game works right, but I’m still failing the tests.

const { useState, useEffect } = React;

export function Board() {
  const [board, setBoard] = useState([[null, null, null], [null, null, null], [null, null, null]]) 
  const [winner, setWinner] = useState(null)
 
  let flattened = board.flat()
  let count = flattened.filter(x => x === null).length
  
  function play(i,j) {
    if (board[i][j] === null) {
      setBoard(prevBoard =>
        prevBoard.map((item, indexCol) =>
         indexCol === i ? 
          (item.map((element, indexRow) => indexRow === j ? ((count % 2 === 0) ? "O":"X") : element)): item
    ))}
  }

  function checkWin(){ 
    let localWinner = null;
    //checking horizontal wins
    for (let i = 0; i < board[0].length; i++) {
      let temp = board[i].filter(x => x === board[i][0])
      if (temp.length == 3 && board[i][0] != null){
        setWinner(board[i][0])
        localWinner = board[i][0]
        break
      }
    }
    //vertical wins
    for (let i = 0; i < board[0].length; i++) { 
      if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != null){
        setWinner(board[0][i])
        localWinner = board[0][i]
        break
      }
    }
    //diagonal wins
    if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != null){
        setWinner(board[0][0])
        localWinner = board[0][0]
      }
    if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != null){
      setWinner(board[0][2])
      localWinner = board[0][0]
    }
    //checking for tie
    if (count == 0 && localWinner == null) {
      setWinner("No one")
    }
  }

   useEffect(() => {
    checkWin();
  }, [board]);

  return <div>
    {!winner && <h2>{(count % 2 === 0) ? "O" : "X"}'s Turn </h2>}
    <div>
      {board.map((row, i) => (<div key={i}>
        {row.map((element, j)  => (<Button key={i+'key'+j} turn={element} winner={winner} onClick={() => play(i,j)}/>)) }</div>)
      )}
    </div>
    <p>{winner ? "Winner: " + winner : ""}</p>
    <button id='reset' onClick={() => {setBoard([[null, null, null], [null, null, null], [null, null, null]])
      setWinner(null)
    }}>Reset</button>
  </div>
}

export function Button(props) {
  return <button className='square' onClick={props.winner ? null : props.onClick}>{props.turn}</button>
}