skip to Main Content

I am a beginner in programming. I have worked on a basic Tic Tac Toe gameboard, it works successfully. For the second phase of my assignment, I am required to implement an AI opponent however I came across several problems.

As a beginner, I need some help and guidance as to how I can fix and work on my codes of the normal Tic Tac Toe gameboard so that I can have an AI opponent.

I used HTML, CSS, and JS for my basic Tic Tac Toe gameboard. I will list all my codes below:

HTML

`<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Tic Tac Toe</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>Tic Tac Toe</h1>
    <div id="board">
      <div class="square" id="0"></div>
      <div class="square" id="1"></div>
      <div class="square" id="2"></div>
      <div class="square" id="3"></div>
      <div class="square" id="4"></div>
      <div class="square" id="5"></div>
      <div class="square" id="6"></div>
      <div class="square" id="7"></div>
      <div class="square" id="8"></div>
    </div>
    <button id="reset">Reset Game</button>
    <div id="message"></div>
  </div>
  <script src="index.js"></script>
</body>
</html>`

CSS

`.container {
  text-align: center;
}

#board {
  display: flex;
  flex-wrap: wrap;
  width: 300px;
  margin: 0 auto;
}

.square {
  width: 90px;
  height: 90px;
  background-color: black;
  margin: 5px;
  border-radius: 5px;
  font-size: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
}

.square:hover {
  background-color: whitesmoke;
}

.square.X {
  color: #ff5e5e;
}

.square.O {
  color: #0077ff;
}
`

JS

`let board = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";
let gameOver = false;

const winningConditions = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6]
];

const squares = document.querySelectorAll(".square");
const resetButton = document.querySelector("#reset");

// Add click event listener to each square
squares.forEach(square => {
  square.addEventListener("click", handleClick);
});

// Add click event listener to reset button
resetButton.addEventListener("click", resetGame);

function handleClick(event) {
  const square = event.target;
  const index = square.getAttribute("id");

  // If square is already clicked or game is over, return
  if (board[index] !== "" || gameOver) {
    return;
  }

  // Add X or O to board and update UI
  board[index] = currentPlayer;
  square.classList.add(currentPlayer);
  square.innerHTML = currentPlayer;

  // Check for winner or tie game
  checkForWinner();
  checkForTieGame();

  // Switch current player
  currentPlayer = currentPlayer === "X" ? "O" : "X";
}

function checkForWinner() {
  for (let i = 0; i < winningConditions.length; i++) {
    const [a, b, c] = winningConditions[i];
    if (board[a] === board[b] && board[b] === board[c] && board[a] !== "") {
      gameOver = true;
      highlightWinnerSquares(a, b, c);
      displayWinner(board[a]);
      break;
    }
  }
}

function checkForTieGame() {
  if (!board.includes("") && !gameOver) {
    gameOver = true;
    displayTieGame();
  }
}

function highlightWinnerSquares(a, b, c) {
  document.getElementById(a).classList.add("winner");
  document.getElementById(b).classList.add("winner");
  document.getElementById(c).classList.add("winner");
}

function displayWinner(player) {
  const message = document.getElementById("message");
  message.innerHTML = `${player} wins!`;
}

function displayTieGame() {
  const message = document.getElementById("message");
  message.innerHTML = "It's a tie game!";
}

function resetGame() {
  board = ["", "", "", "", "", "", "", "", ""];
  currentPlayer = "X";
  gameOver = false;

  squares.forEach(square => {
    square.classList.remove("X", "O", "winner");
    square.innerHTML = "";
  });

  const message = document.getElementById("message");
  message.innerHTML = "";
}`

2

Answers


  1. I am not sure this is the right place to ask this question as stackoverflow is for solving bugs. GameDev stack exchange could be more appropriate.

    Anyway, a next step to your project could be to create a function AiPlays and to call it in the handleClick function, if the game is not over.

    Then a possible behavior for the ai would be to compare the winningConditions to both players’s pawn and play accordingly.

    Login or Signup to reply.
  2. Extract the contents of handleClick into its own method:

    function handleClick(event) {
      const square = event.target;
      click(square);
    }
    
    function click(square) {
      const index = square.getAttribute("id");
    
      // If square is already clicked or game is over, return
      if (board[index] !== "" || gameOver) {
        return;
      }
    
      // Add X or O to board and update UI
      board[index] = currentPlayer;
      square.classList.add(currentPlayer);
      square.innerHTML = currentPlayer;
    
      // Check for winner or tie game
      checkForWinner();
      checkForTieGame();
    
      // Switch current player
      currentPlayer = currentPlayer === "X" ? "O" : "X";
    }
    

    Now your AI player can use the click method.

    click(document.getElementById("4")); etc.

    I recommend making the AI play its moves in the click event handler (thus, after the player has played their turn)

    function handleClick(event) {
      const playerMove = event.target;
      click(playerMove);
      const computerMove = chooseComputerMove();
      click(chooseComputerMove);
    }
    
    function chooseComputerMove() {
      // TODO: implement this method
      // calculate which square the AI should play on this turn,
      // return that HTML element
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search