Assignment – Bottom-up Planning

Hi everyone,
I am sharing my code (I am not a developer and I am fully aware it is not the most optimised and the most elegant, still a lot to learn for sure):

function visualizeBoard(gameBoard){
    let boardString=''
    let gameBoardClone=[...gameBoard]
    for (let index in gameBoardClone){
        if (gameBoardClone[index]===null){
            gameBoardClone[index]=parseInt(index)+1;
        }

    }
    for (let i=0;i<=2;i+=1){
        boardString=boardString+`${gameBoardClone[3*i]} ${gameBoardClone[3*i+1]} ${gameBoardClone[3*i+2]}` + '\n';
    }
    return boardString;
}


function getUserInput(gameBoard, nextPlayerSymbol){
    let boardString=visualizeBoard(gameBoard);
    let coordinates=prompt(`User ${nextPlayerSymbol}, make your pick\n ${boardString}`);
    return coordinates;
}

function isMoveValid(coordinates, gameBoard){
    if (gameBoard[coordinates-1] ===null)
    {
        return true
    }
    else 
    {
        return false
    }
}


function makeAMove(gameBoard, nextPlayerSymbol) {
    newgameBoard=[...gameBoard];
    let coordinates='';
    do {
        coordinates = getUserInput(gameBoard,nextPlayerSymbol);
    } while ( isMoveValid(coordinates, gameBoard)===false );
    newgameBoard[coordinates-1]=nextPlayerSymbol;
    return newgameBoard;
}


function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    if (hasLastMoverWon(currentPlayerSymbol, gameBoard) ) 
    {
        // Write a message that last mover has won the game
        alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
        return true;
    }
    else
    {
        // Return: winner/draw OR game is still in progress
        let indic=0;
        for (let index in gameBoard)
        {
            if (gameBoard[index]===null)
            {
            //console.log(gameBoard[index]);
            indic=indic+1;
            }
        }
        if (indic===0)
        {
            alert('That is a draw');
            return true;
        }
        else
        {
            return false;
        }
    }
}

function ticTacToe() {

    let gameBoard = new Array(9).fill(null);
    let players = ['X', 'O'];
    let currentPlayerSymbol=null

   do {
        if (currentPlayerSymbol==='X'){
            currentPlayerSymbol='O'}
            else
            {currentPlayerSymbol='X'}
        gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    } while ( !isGameOver(gameBoard, currentPlayerSymbol) );
    
} 
1 Like
function renderBoard(gameBoard){
    let s = '\n'
    let b = 1
     for(let i=0; i<gameBoard.length; i+=1){
         if(gameBoard[i]===null){
             s += `${i+1}`
         }else{
             s += `${gameBoard[i]}`
         }
         if(b === 3) {
             s += '\n'
             b = 0
         }
         b+=1
     }
    return s
}

function getUserInput(nextPlayerSymbol, gameBoard) {
    return +prompt(`${renderBoard(gameBoard)} place your move 1-9 : `)
}

function isMoveValid(coordinates, gameBoard) {
    if(gameBoard[coordinates-1]===null && 
       coordinates>0 && 10>coordinates)return true
    else return false
}

function makeAMove(gameBoard, nextPlayerSymbol) {
    // clone the game board before placing moves in it
    let newGameBoard = JSON.parse(JSON.stringify(gameBoard))
    let coordinates = 0
    do {
        coordinates = getUserInput(nextPlayerSymbol, gameBoard);
    } while ( !isMoveValid(coordinates, gameBoard) );
    // return newGameBoard;
    newGameBoard[coordinates-1] = nextPlayerSymbol
    return newGameBoard
}

function hasLastMoverWon(lastMove, gameBoard) {
    let winnerCombos = [
        [0, 1, 2], 
        [3, 4, 5], 
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7], 
        [2, 5, 8],
        [0, 4, 8], 
        [2, 4, 6]
    ];
    for (let [i1, i2, i3] of winnerCombos) {
        if (gameBoard[i1] === lastMove &&
            gameBoard[i1] === gameBoard[i2] && 
            gameBoard[i1] === gameBoard[i3] 
           ) {
            return true;
        }
    }
    return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    let lastMove = currentPlayerSymbol
    if (hasLastMoverWon(lastMove, gameBoard) ) {
        // Write a message that last mover has won the game
        alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
        return true;
    }
    // 2. check if the board is full
    if(gameBoard.includes(null)){
        return false
    }else{
        alert('Game ended a Draw!')
        return true
    }
    // Return: winner/draw OR game is still in progress
}

function ticTacToe() {
    // State space 
    let gameBoard = new Array(9).fill(null);
    let players = ['X', 'O'];
    let nextPlayerIndex = 1;
    let currentPlayerSymbol = players[nextPlayerIndex]

    // Computations 
   do {
        if(nextPlayerIndex === 0) nextPlayerIndex = 1
        else nextPlayerIndex = 0
        currentPlayerSymbol = players[nextPlayerIndex]
        gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    } while ( !isGameOver(gameBoard, currentPlayerSymbol) );
    
    // Return value 
    // return undefined;
} 
1 Like
function getBoardString(gameBoard) {                                              
     let boardString = '';                                                                   
 for (let i= 0; i < gameBoard.lenght; i += 1){ boardString += `${gameBoard[i] ?? i+1}`;                                                 
 if (i % 3 === 2) { boardString += '\n'; }
    } return boardString;                                      
}               
 function getUserInput(nextPlayerSymbol, gameBoard) {
 return prompt(`Board:\n${getBoardString(gameBoard)} Enter ${nextPlayerSymbol}'s next move (1-9)`)
}

function isMoveValid(move, coordinates, gameBoard) {
      let boardIndex = move - 1;                                                                                                                                    
    return (                                                                                        
 typeof move === 'number' &&  move >= 1 && move <= 9 &&                                                                
 gameBoard[boardIndex] === null
          );
}

function makeAMove(gameBoard, nextPlayerSymbol) {
    const newGameBoard = [...gameBoard];                                                     
 let move = null;
    do {
        move = getUserInput(nextPlayerSymbol, gameBoard);
    } while ( !isMoveValid(move, gameBoard) );
    const boardIndex = move-1; newGameBoard[boardIndex] = nextPlayerSymbol;                                            
 return newGameBoard;      
}

function hasLastMoverWon(lastMove, gameBoard) {
    let winnerCombos = [
        [0, 1, 2], 
        [3, 4, 5], 
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7], 
        [2, 5, 8],
        [0, 4, 8], 
        [2, 4, 6]
    ];
    for (let [i1, i2, i3] of winnerCombos) {
        if (gameBoard[i1] === lastMove &&
            gameBoard[i1] === gameBoard[i2] && 
            gameBoard[i1] === gameBoard[i3] 
           ) {
            return true;
        }
    }
    return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    if (hasLastMoverWon(lastMove, gameBoard) ) {
        // Write a message that last mover has won the game
        alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
        return true;
    }
    // 2. check if the board is full//                                                    
       if (gameBoard.every(element => element !== null)) {                                
          alert(`Dra. Game over.`);                                                       
          return true;                                                                           }                                                                                                                           
       return false;
}

function ticTacToe() {
    // State space 
    let gameBoard = new Array(9).fill(null);
    let nextPlayerIndex = 0;

    // Computations 
   do {
         nextPlayerIndex = nextPlayerIndex +1;                                                                                 
         gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    } while ( !isGameOver(gameBoard, currentPlayerSymbol) );
    
    // Return value 
    // return undefined;
} type or paste code here
function makeAMove(gameBoard, nextPlayerSymbol) {
    // clone the game board before placing moves in it
    let newGameBoard = JSON.parse(JSON.stringify(gameBoard))

function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    if (hasLastMoverWon(lastMove, gameBoard) ) {
        // Write a message that last mover has won the game
        alert(`Congrats, ${currentPlayerSymbol} has won the game`);
        return true;

I was able to do these 2 parts so far. Very beginner and I will have to watch some more videos to continue :frowning:

2 Likes
function ticTacToe() {
  // State space
  let gameBoard = new Array(9).fill(null);
  let players = ["X", "O"];
  let nextPlayerIndex = 0;

  // Computations
  do {
    gameBoard = makeAMove(gameBoard, players[nextPlayerIndex]);
    nextPlayerIndex === 0 ? (nextPlayerIndex = 1) : (nextPlayerIndex = 0);
    alert(`
    ${gameBoard[0]}|${gameBoard[1]}|${gameBoard[2]}
    ${gameBoard[3]}|${gameBoard[4]}|${gameBoard[5]}
    ${gameBoard[6]}|${gameBoard[7]}|${gameBoard[8]}
  `);
  } while (!isGameOver(gameBoard, players[nextPlayerIndex]));
}

function makeAMove(gameBoard, nextPlayerSymbol) {
  // clone the game board before placing moves in it
  let newGameBoard = [...gameBoard];
  let coordinates = "";

  do {
    coordinates = getUserInput(nextPlayerSymbol);
  } while (!isMoveValid(coordinates, gameBoard));

  newGameBoard[coordinates] = nextPlayerSymbol;

  return newGameBoard;
}

function getUserInput(nextPlayerSymbol) {
  return prompt("Which coordinate would you like to move");
}

function isMoveValid(coordinates, gameBoard) {
  if (
    coordinates >= 0 &&
    coordinates <= 8 &&
    !isSpaceTaken(coordinates, gameBoard)
  ) {
    return true;
  } else {
    return false;
  }
}

function hasLastMoverWon(lastMove, gameBoard) {
  let winnerCombos = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ];

  for (let [i1, i2, i3] of winnerCombos) {
    if (
      gameBoard[i1] === lastMove &&
      gameBoard[i1] === gameBoard[i2] &&
      gameBoard[i1] === gameBoard[i3]
    ) {
      return true;
    }
  }
  return false;
}

function isSpaceTaken(coordinates, gameBoard) {
  if (gameBoard[coordinates] === null) {
    return false;
  } else {
    return true;
  }
}

function isGameOver(gameBoard, currentPlayerSymbol) {
  let isBoardFull = false;
  let lastMove = currentPlayerSymbol === "X" ? "O" : "X";
  // 1. check if there is a winner
  if (hasLastMoverWon(lastMove, gameBoard)) {
    // Write a message that last mover has won the game
    alert(`Congratulations, ${lastMove} has won the game`);
    return true;
  }
  // 2. check if the board is full
  if (!gameBoard.includes(null)) {
    isBoardFull = true;
  }

  if (isBoardFull) {
    alert("It's a Tie!");
    return true;
  }

  return false;
}

// Initialize game

ticTacToe();

2 Likes

About the TICTACTOE program: The small sections seemed fine for me, but the whole thing, with all the sections together does not work well! What is wrong?

function getUserInput(nextPlayerSymbol, gameBoard) {
return +prompt(Board:\n${getBoardString(gameBoard)} Enter ${nextPlayerSymbol}'s next move (1 - 9):);
}

function isMoveValid(move, gameBoard) {
const boardIndex = move - 1;
return (
typeof move === “number” &&
move >= 1 && move <= 9 &&
gameBoard[boardIndex] === null);
}

function makeAMove(gameBoard, nextPlayerSymbol) {
const newGameBoard = […gameBoard];
let move = null;
do { move = getUserInput(nextPlayerSymbol, gameBoard);
} while (!isMoveValid(move, gameBoard) );
const boardIndex = move - 1;
newGameBoard[boardIndex] = nextPlayerSymbol;
return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
let winnerCombinations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ]; for (let [i1, i2, i3] of winnerCombinations) { if (gameBoard[i1] === lastMove &&
gameBoard[i1] === gameBoard[i2] &&
gameBoard[i1] === gameBoard[i3])
{ return true; } } return false; }

function isGameOver(gameBoard, currentPlayerSymbol)
{ if (hasLastMoverWon(currentPlayerSymbol, gameBoard) ) {
alert(Congradtulations ${currentPlayerSymbol} has won the game);
return true;
} if (gameBoard.every(element => element !== null) ) {
alert(Tie. Game over.);
return true; } return false;
}

function getBoardString(gameBoard) {
let boardString = " ";
for (let i = 0; i < gameBoard.length; i += 1) {
boardString += ${gameBoard[i] ?? i+1};
if (i%3 === 2) {
boardString += “\n”; }
return boardString;
}

function ticTacToe() {
let gameBoard = new array(9).fill(null);
let currentPlayerSymbol = null;
do {
currentPlayerSymbol = currentPlayerSymbol === “x” ? “o” : “x”;
gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
} while (!isGameOver(gameBoard, currentPlayerSymbol) );
}

2 Likes

I had a little bit of trouble trying to figure everything out without watching the videos and seeing the full code.

I think if we had a flow chart for this project that showed how everything is tied together and able to see it visually, it would have clicked better. Still being fairly new to Javascript, it can be difficult to visualize how everything is supposed to flow together from scratch without a chart. Things didn’t start clicking until I took the full code and categorized it more into sections with additional comments.

Don’t mind me, I still have a lot to learn lol , but for example:


//Element 1: The Game TicTacToe
//Element 1a: Gameboard
function ticTacToe() {
    //...code...

//Element 1b: Players
    let currentPlayerSymbol //...code...

//Element 1c: computations
do {
    currentPlayerSymbol //...code...
    gameBoard = makeAMove //...code...
} while !isGameOver //...code...
}

//==============================

// Element 2: Rules
// Element 2a: Ways to Win

function hasLastMoverWon //...code...

//Element 2: Rules
//Element 2b: Validating Moves

function isMoveValid //...code...

//==============================

//Element 3: User Actions
//Element 3a: Viewing The Current Board

function getBoardString //...code...

//Element 3: User Actions
//Element 3b: Input Prompts

function getUserInput //...code...

//==============================

//Element 4: Computing
//Element 4a: User Moves

function makeAMove //...code...

//Element 4: Computing
//Element 4b: Winner

function isGameOver //...code...


One thing that I didn’t understand was why the Cancel button wasn’t working with the prompt messages. I tried searching on stack overflow and tried some things, but still couldn’t get the cancel button to work.

While messing around with the full code to breakdown and understand some functions, there were several times that I had to close the browser window to go back and adjust the code lol.

Does anyone know how to adjust the code to where the cancel button on the prompt will work?

1 Like

Hi everybody!
Can anyone explain to me why this code continues repeating the alert box when I call ticTacToe function ??
I can’t figure out where is the mistake.

function printBoard(gameBoard) {
    //state space
    let boardString = '';
 
    for(let i=0; i<gameBoard.length; i += 1) {
        boardString += `${gameBoard[i] ?? i+1}`;
        if( i % 3 === 2) {
            boardString += '\n';
        }
    }
    return boardString;
}

function getUserInput(nextPlayerSymbol, gameBoard) {
    return +prompt(`Board:\n${printBoard(gameBoard)} Enter ${nextPlayerSymbol}'s next move (1-9):`);
}

function isMoveValid(move, gameBoard) {
    const boardIndex = move -1;

    return (
        typeof move === 'number' &&
        move >= 1 && move <= 9 &&
        gameBoard[boardIndex] === null
    );
}

function makeAMove(gameBoard, nextPlayerSymbol) {
    let newGameBoard = [...gameBoard];
    let move = null;

    do {
        move = getUserInput(nextPlayerSymbol, gameBoard);
    } while ( !isMoveValid(move, gameBoard) );
    const boardIndex = move -1;
    newGameBoard[boardIndex] = nextPlayerSymbol;
   
    return newGameBoard;

}

function hasLastMoverWon(lastMove, gameBoard) {

    let winnerCombos = [
        [0, 1, 2], 
        [3, 4, 5], 
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7], 
        [2, 5, 8],
        [0, 4, 8], 
        [2, 4, 6]
    ];

    for (let [i1, i2, i3] of winnerCombos) {
        if (gameBoard[i1] === lastMove &&
            gameBoard[i1] === gameBoard[i2] && 
            gameBoard[i1] === gameBoard[i3] 
           ) {
            return true;
        }
    }

    return false;
}

function IsGameOver(gameBoard, currentPlayerSymbol){
      
        if(hasLastMoverWon(currentPlayerSymbol, gameBoard)) {
            alert(`Congratulations!, ${currentPlayerSymbol} are the winner.`);
            return true;
        }
       
        if(gameBoard.every(element => element != null)) {
            alert('Draw. Game over!');
            return true;
        }
        return false;
}

function ticTacToe() {
    let gameBoard = [
        [null, null, null, 
         null, null, null, 
         null, null, null]
    ];
    let currentPlayerSymbol = null;


    do {
        currentPlayerSymbol = currentPlayerSymbol === 'X' ? 'O' : 'X';
        gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    } while( !IsGameOver(gameBoard, currentPlayerSymbol) );
    
}

I copied the solution which was given under the video ( “Writing Good JavaScript Conclusion”), but it did not work. I just get “undefined”. This is what I copied:

function printBoard(gameBoard) {
let gameString = ‘’;
for (let i = 0; i <= 6; i += 3) {
gameString += ${gameBoard[i] ?? i+1}${gameBoard[i+1] ?? i+2}${gameBoard[i+2] ?? i+3}\n;
}
return gameString;
}

function getUserInput(nextPlayerSymbol, gameBoard) {
return +prompt(Board:\n${printBoard(gameBoard)} Enter your next move (1-9) :);
}

function isMoveValid(coordinates, gameBoard) {
return (
typeof coordinates === ‘number’ &&
coordinates >= 1 &&
coordinates <= 9 &&
gameBoard[coordinates - 1] === null
);
}

function makeAMove(gameBoard, nextPlayerSymbol) {
const newGameBoard = JSON.parse(JSON.stringify(gameBoard));
let coordinates;
do {
coordinates = getUserInput(nextPlayerSymbol, gameBoard);
} while ( !isMoveValid(coordinates, gameBoard) );
newGameBoard[coordinates - 1] = nextPlayerSymbol;
return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
let winnerCombos = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let [i1, i2, i3] of winnerCombos) {
if (gameBoard[i1] === lastMove &&
gameBoard[i1] === gameBoard[i2] &&
gameBoard[i1] === gameBoard[i3]
) {
return true;
}
}
return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
// 1. check if there is a winner
if (hasLastMoverWon(currentPlayerSymbol, gameBoard) ) {
// Write a message that last mover has won the game
alert(Congratulations, ${currentPlayerSymbol} has won the game);
return true;
}
// 2. check if the board is full
const isBoardFull = gameBoard.every(element => element !== null);
if (isBoardFull) {
alert(${printBoard(gameBoard)}\nDraw. Game Over.);
return true;
}
return false;
}

function ticTacToe() {
// State space
let gameBoard = new Array(9).fill(null);
let players = [‘X’, ‘O’];
let nextPlayerIndex = 1;

// Computations

do {
nextPlayerIndex = (nextPlayerIndex + 1) % 2;
currentPlayerSymbol = players[nextPlayerIndex];
gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
} while ( !isGameOver(gameBoard, currentPlayerSymbol) );
}

1 Like

I copied the solution which was given under the video ( “Writing Good JavaScript Conclusion”), but it did not work. I just get “undefined”. This is what I copied:

function printBoard(gameBoard) {
let gameString = ‘’;
for (let i = 0; i <= 6; i += 3) {
gameString += ${gameBoard[i] ?? i+1}${gameBoard[i+1] ?? i+2}${gameBoard[i+2] ?? i+3}\n ;
}
return gameString;
}

function getUserInput(nextPlayerSymbol, gameBoard) {
return +prompt( Board:\n${printBoard(gameBoard)} Enter your next move (1-9) : );
}

function isMoveValid(coordinates, gameBoard) {
return (
typeof coordinates === ‘number’ &&
coordinates >= 1 &&
coordinates <= 9 &&
gameBoard[coordinates - 1] === null
);
}

function makeAMove(gameBoard, nextPlayerSymbol) {
const newGameBoard = JSON.parse(JSON.stringify(gameBoard));
let coordinates;
do {
coordinates = getUserInput(nextPlayerSymbol, gameBoard);
} while ( !isMoveValid(coordinates, gameBoard) );
newGameBoard[coordinates - 1] = nextPlayerSymbol;
return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
let winnerCombos = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let [i1, i2, i3] of winnerCombos) {
if (gameBoard[i1] === lastMove &&
gameBoard[i1] === gameBoard[i2] &&
gameBoard[i1] === gameBoard[i3]
) {
return true;
}
}
return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
// 1. check if there is a winner
if (hasLastMoverWon(currentPlayerSymbol, gameBoard) ) {
// Write a message that last mover has won the game
alert( Congratulations, ${currentPlayerSymbol} has won the game );
return true;
}
// 2. check if the board is full
const isBoardFull = gameBoard.every(element => element !== null);
if (isBoardFull) {
alert( ${printBoard(gameBoard)}\nDraw. Game Over. );
return true;
}
return false;
}

function ticTacToe() {
// State space
let gameBoard = new Array(9).fill(null);
let players = [‘X’, ‘O’];
let nextPlayerIndex = 1;

// Computations

do {
nextPlayerIndex = (nextPlayerIndex + 1) % 2;
currentPlayerSymbol = players[nextPlayerIndex];
gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
} while ( !isGameOver(gameBoard, currentPlayerSymbol) );
}

1 Like

Please share your code in the following way so it can be easily copy/paste from out team :nerd_face:

Carlos Z

1 Like
var lastMove = null;
function getUserInput(nextPlayerSymbol) {
  return prompt(`Put ${nextPlayerSymbol} at coordinate 0-9: `);
}

function isMoveValid(coordinates, gameBoard) {
  return (
    gameBoard[coordinates] === null && Number(coordinates) < gameBoard.length
  );
}

function makeAMove(gameBoard, nextPlayerSymbol) {
  // clone the game board before placing moves in it
  let newGameBoard = [...gameBoard];
  let coordinates = getUserInput(nextPlayerSymbol);
  while (!isMoveValid(coordinates, gameBoard)) {
    coordinates = getUserInput(nextPlayerSymbol);
  }
  // return newGameBoard;
  newGameBoard[coordinates] = nextPlayerSymbol;

  return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
  let winnerCombos = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ];
  for (let [i1, i2, i3] of winnerCombos) {
    if (
      gameBoard[i1] === lastMove &&
      gameBoard[i1] === gameBoard[i2] &&
      gameBoard[i1] === gameBoard[i3]
    ) {
      return true;
    }
  }
  return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
  const lastMove = currentPlayerSymbol;
  // 1. check if there is a winner
  if (hasLastMoverWon(lastMove, gameBoard)) {
    // Write a message that last mover has won the game
    alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
    return true;
  }
  // 2. check if the board is full

  // Return: winner/draw OR game is still in progress
  if (!gameBoard.includes(null)) {
    alert("Game has ended in a draw!");
    return true;
  }
  return false;
}

function ticTacToe() {
  // State space
  let gameBoard = new Array(9).fill(null);
  let players = ["X", "O"];
  let nextPlayerIndex = 0;
  let currentPlayerSymbol = players[nextPlayerIndex];
  // Computations
  do {
    currentPlayerSymbol = players[nextPlayerIndex];
    gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    nextPlayerIndex = nextPlayerIndex % 2 === 0 ? 1 : 0;
    alert(`
      ${gameBoard[0]}|${gameBoard[1]}|${gameBoard[2]}
      ${gameBoard[3]}|${gameBoard[4]}|${gameBoard[5]}
      ${gameBoard[6]}|${gameBoard[7]}|${gameBoard[8]}
    `);
} while (!isGameOver(gameBoard, currentPlayerSymbol));

}

ticTacToe()
1 Like
function ticTacToe() {
    // State space
    let gameBoard = new Array(9).fill(null);
    let players = ["X", "O"];
    let nextPlayerIndex = 0;
  
    // Computations
    do {
      gameBoard = makeAMove(gameBoard, players[nextPlayerIndex]);
      nextPlayerIndex === 0 ? (nextPlayerIndex = 1) : (nextPlayerIndex = 0);
      alert(`
      ${gameBoard[0]}|${gameBoard[1]}|${gameBoard[2]}
      ${gameBoard[3]}|${gameBoard[4]}|${gameBoard[5]}
      ${gameBoard[6]}|${gameBoard[7]}|${gameBoard[8]}
    `);
    } while (!isGameOver(gameBoard, players[nextPlayerIndex]));
  }
  
  function makeAMove(gameBoard, nextPlayerSymbol) {
    // clone the game board before placing moves in it
    let newGameBoard = [...gameBoard];
    let coordinates = "";
  
    do {
      coordinates = getUserInput(nextPlayerSymbol);
    } while (!isMoveValid(coordinates, gameBoard));
  
    newGameBoard[coordinates] = nextPlayerSymbol;
  
    return newGameBoard;
  }
  
  function getUserInput(nextPlayerSymbol) {
    return prompt(`It is your turn ${nextPlayerSymbol}, what is your move 0-9?`);
  }
  
  function isMoveValid(coordinates, gameBoard) {
    if (
      coordinates >= 0 &&
      coordinates <= 8 &&
      !isSpaceTaken(coordinates, gameBoard)
    ) {
      return true;
    } else {
      return false;
    }
  }
  
  function hasLastMoverWon(lastMove, gameBoard) {
    let winnerCombos = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6]
    ];
  
    for (let [i1, i2, i3] of winnerCombos) {
      if (
        gameBoard[i1] === lastMove &&
        gameBoard[i1] === gameBoard[i2] &&
        gameBoard[i1] === gameBoard[i3]
      ) {
        return true;
      }
    }
    return false;
  }
  
  function isSpaceTaken(coordinates, gameBoard) {
    if (gameBoard[coordinates] === null) {
      return false;
    } else {
      return true;
    }
  }
  
  function isGameOver(gameBoard, currentPlayerSymbol) {
    let isBoardFull = false;
    let lastMove = currentPlayerSymbol === "X" ? "O" : "X";
    // 1. check if there is a winner
    if (hasLastMoverWon(lastMove, gameBoard)) {
      // Write a message that last mover has won the game
      alert(`YEET, you won the game ${lastMove}!`);
      return true;
    }
    // 2. check if the board is full
    if (!gameBoard.includes(null)) {
      isBoardFull = true;
    }
  
    if (isBoardFull) {
      alert("That's a tie! Play again?");
      return true;
    }
  
    return false;
  }
  
  // Initialize game
  
  ticTacToe();
  
1 Like

Why would we need to copy the gameboard?

function getUserInput(nextPlayerSymbol) {
  let input = prompt("Please enter your position");
  let position = parseInt(input, 10);
  return position;
}

function isMoveValid(coordinates, gameBoard) {
  if (coordinates > 8 || coordinates < 0 || gameBoard[coordinates] !== null) {
    alert("invalid position");
    return false;
  }
  return true;
}

function makeAMove(gameBoard, nextPlayerSymbol) {
  // clone the game board before placing moves in it

  let coordinates = getUserInput(nextPlayerSymbol);
  while (!isMoveValid(coordinates, gameBoard)) {
    coordinates = getUserInput(nextPlayerSymbol);
  }
  gameBoard[coordinates] = nextPlayerSymbol;
  return gameBoard;
  // return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
  let winnerCombos = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ];
  for (let [i1, i2, i3] of winnerCombos) {
    if (
      gameBoard[i1] === lastMove &&
      gameBoard[i1] === gameBoard[i2] &&
      gameBoard[i1] === gameBoard[i3]
    ) {
      return true;
    }
  }
  return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
  // 1. check if there is a winner
  lastMove = currentPlayerSymbol;
  if (hasLastMoverWon(lastMove, gameBoard)) {
    // Write a message that last mover has won the game
    alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
    return true;
  }
  // 2. check if the board is full
  const isNull = (element) => element === null;
  if (gameBoard.some(isNull)) {
    alert(`Game is still in progress`);
    return false;
  } else {
    alert(`Game is a draw`);
    return true;
  }

  // Return: winner/draw OR game is still in progress
}

function ticTacToe() {
  // State space
  let gameBoard = new Array(9).fill(null);
  let currentPlayerSymbol = "X";
  // Computations
  do {
    if (currentPlayerSymbol === "X") {
      currentPlayerSymbol = "O";
    } else {
      currentPlayerSymbol = "X";
    }
    gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    alert(`
      ${gameBoard[0]}|${gameBoard[1]}|${gameBoard[2]}
      ${gameBoard[3]}|${gameBoard[4]}|${gameBoard[5]}
      ${gameBoard[6]}|${gameBoard[7]}|${gameBoard[8]}
    `);
  } while (!isGameOver(gameBoard, currentPlayerSymbol));

  // Return value
  // return undefined;
}

  • I did my best; obviously I am a newbie here and had to check the answers; but try to do it myselfto understand and plan the same thing over over and over until i get a result on my own; I struggle with multiple minor mistakes, quoting null a misplaced bracket and running memory while testing…
    my jaw fell off when I saw the master exercise with bitwise (^) XOR example…
// tictac toe buttom up
// board status to display in prompt
function displayMatrix(mainBoard){
    let boardDisplay = '';
    for ( let i = 0; i< mainBoard.length; i+=1){
        boardDisplay += `${mainBoard[i] ?? i+1} `;
        if ( i % 3 === 2)
            boardDisplay += '\n';
    } 
    return boardDisplay;
}
// collecting inputs from user
function collectInput(nextPlayerSymbol, mainBoard){
    // grab with + an integer
    return +prompt(
        `Board Status: \n${displayMatrix(mainBoard)} \n
        it is ${nextPlayerSymbol}'s move (1-9)
    `);
}
// validate player move and random x and o's
function validateMove(newPosition, mainBoard){
const mainBoardIndex = newPosition -1 ;
// the board should have a null/empty position to validate move
return (
    typeof newPosition === 'number' && 
    newPosition >= 1 && newPosition <=9 &&
    mainBoard[mainBoardIndex] === null
    );
}
function SelectMove(nextPlayerSymbol, mainBoard){
    // clone the gameboard before placing moves
    const newMainBoard = [...mainBoard];
    // compute the move and check if is or not an empyt positon
    do {
     newPosition = collectInput(nextPlayerSymbol, mainBoard);
    } while (!validateMove(newPosition, mainBoard));
    // positions are 0 - 8 so minus 1 to match in matrix
    const mainBoardIndex = newPosition - 1; 
    newMainBoard[mainBoardIndex] = nextPlayerSymbol;
    return newMainBoard;
}
//check someone won
function someoneWon(lastMove, mainBoard) {
    // check the winning options rows, columns and diagonals
   let winningsequence = [
        [ 0, 1, 2],
        [ 3, 4, 5],
        [ 6, 7, 8],
        [ 0, 3, 6],
        [ 1, 4, 7],
        [ 2, 5, 8],
        [ 0, 4, 8],
        [ 2, 4, 6]

    ];
    for (let [ h1, h2, h3] of winningsequence){
        if (
            mainBoard[h1] === lastMove &&
            mainBoard[h1] === mainBoard[h2] &&
            mainBoard[h1] === mainBoard[h3]
        ) {
            return true;
        }
    }
    return false;
}
// check if game is over
function checkGameOver(playerSymbol, mainBoard){
    // call if the game is someone wins and check if board is full
    if(someoneWon(playerSymbol, mainBoard)){
    alert(`hey ${playerSymbol} dude you have won the game! Congrats`);
    return true;
    }
    if (mainBoard.every(element => element !== 'null')) {
    alert (`ups! I guess it's a draw`);
    return true;
    }
    return false;
}
// wait for next move
// display string
// call tictactoe game
function ticTacToe_own(){
    //initialize the gameboard with arrays and 
    let mainBoard = new Array(9).fill(null);
    let playerSymbol = null;
    // run the game calling function
    do {
        //set x to start and switch 
        playerSymbol = playerSymbol === 'x' ? 'o' : 'x';
        // start and move  then check if game is over
        mainBoard = SelectMove(playerSymbol, mainBoard);
    } while (!checkGameOver(playerSymbol, mainBoard));
}


With little changes to make it work for VsCode

function printBoard(game) {
  let gameArr = JSON.parse(JSON.stringify(game));
  for (let i = 0; i < gameArr.length; i++) {
    process.stdout.write(gameArr[i]);
    if (i % 3 === 2) {
      console.log();
    }
  }
}
//printBoard(["O", "X", "X", "O", "O", "X", "X", "O", "O"]);
//checking for winner
function hasLastMoverWon(lastMove, gameBoard) {
  let winnerCombos = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let [i1, i2, i3] of winnerCombos) {
    if (
      gameBoard[i1] === lastMove &&
      gameBoard[i1] === gameBoard[i2] &&
      gameBoard[i1] === gameBoard[i3]
    ) {
      return true;
    }
  }
  return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
  if (hasLastMoverWon(currentPlayerSymbol, gameBoard)) {
    console.log(`Congratulations, ${currentPlayerSymbol} has won the game`);
    return true;
  }
  for (let i = 0; i < gameBoard.length; i++)
    if (gameBoard[i] !== "X" && gameBoard[i] !== "O") {
      return false;
    }
  console.log(`Congratulations, the game ended in draw!`);
  return true;
}
//making a move
function makeAMove(game, nextPlayerSymbol) {
  let gameBoard = JSON.parse(JSON.stringify(game));
  let coordinates = getUserInput();
  if (isMoveValid(coordinates, gameBoard)) {
    gameBoard[coordinates] = nextPlayerSymbol;
    return gameBoard;
  }
}
function getUserInput() {
  let column = readline.question("Write you move column(1-3): ") - 1;
  let row = readline.question("Write you move row(1-3): ") - 1;
  if (-1 < column < 3 && -1 < row < 3) {
    if (row == 0) return column;
    else if (row == 1) return column + 3;
    else if (row == 2) return column + 6;
  } else {
    console.log("Incorect value!");
  }
}
function isMoveValid(coordinates, game) {
  if (game[coordinates] === "X" || game[coordinates] === "O") {
    console.log("Incorrect Input!");
    return false;
  } else {
    return true;
  }
}

function ticTacToe() {
  let gameBoard = new Array(9).fill("-");
  let players = ["X", "O"];
  let nextPlayerIndex = 0;
  let nextPlayer;

  do {
    printBoard(gameBoard);
    if (nextPlayerIndex % 2 === 0) {
      nextPlayer = players[0];
    } else {
      nextPlayer = players[1];
    }
    gameBoard = makeAMove(gameBoard, nextPlayer);
    nextPlayerIndex++;
    console.log(nextPlayerIndex);
  } while (!isGameOver(gameBoard, nextPlayer));
}
ticTacToe();

1 Like
function getUserInput() {
  coordinates = prompt("Choose your coordinates from 1 to 9")
  return coordinates;
}

function isMoveValid(coordinates, gameBoard) {
  if (coordinates < 1 || coordinates > 9 || gameBoard[coordinates-1] !== "*") {
    return false;
  }
  else {
    return true;
  }
}

function makeAMove(gameBoard, currentPlayerSymbol) {
    // clone the game board before placing moves in it
    let newGameBoard = [...gameBoard];
    do {
        let coordinates = getUserInput();
    } while ( !isMoveValid(coordinates, newGameBoard) );
    // return newGameBoard;
    newGameBoard[coordinates-1] = currentPlayerSymbol;

    return newGameBoard
}

function hasLastMoverWon(currentPlayerSymbol ,gameBoard) {
    let winnerCombos = [
        [0, 1, 2], 
        [3, 4, 5], 
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7], 
        [2, 5, 8],
        [0, 4, 8], 
        [2, 4, 6]
    ];
    for (let combo of winnerCombos) {
        if (gameBoard[combo[0]] === currentPlayerSymbol &&
            gameBoard[combo[1]] === currentPlayerSymbol && 
            gameBoard[combo[2]] === currentPlayerSymbol 
           ) {
            return true;
        }
    }

}

function changePlayer(currentPlayerSymbol, players) {
  if (currentPlayerSymbol === players[0]) {
    currentPlayerSymbol = players[1];
  }
  else {
    currentPlayerSymbol = players[0];
  }
  return currentPlayerSymbol;
}

function boardFull(gameBoard) {
  isFull = true;
  for (let i of gameBoard) {
    if (i !== null) {
      isFull = false
    }
  }
  return isFull;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    if (hasLastMoverWon(currentPlayerSymbol, gameBoard) ) {
        // Write a message that last mover has won the game
        alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
        return true;
    }
    // 2. check if the board is full
    if (boardFull(gameBoard)) {
      alert("Board full! it's a tie")
      return true
    }
    // Return: winner/draw OR game is still in progress
    else {
      alert('Game still in progress')
      return false
    }
    
}

function displayBoard(gameBoard) {
  alert(`
      ${gameBoard[0]}|${gameBoard[1]}|${gameBoard[2]}
      ${gameBoard[3]}|${gameBoard[4]}|${gameBoard[5]}
      ${gameBoard[6]}|${gameBoard[7]}|${gameBoard[8]}
    `);
}

function ticTacToe() {
    // State space 
    let gameBoard = new Array(9).fill("*");
    let isValid = true;
    let players = ['X', 'O'];
    let currentPlayerSymbol = players[1]

    // Computations 
   do {
        currentPlayerSymbol = changePlayer(currentPlayerSymbol, players)
        gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
        displayBoard(gameBoard)  
    } while ( !isGameOver(gameBoard, currentPlayerSymbol) );
    
    // Return value 
    // return undefined;
}

ticTacToe()

Made some adjustments to the code, specially to the hasLastMoveWon algorithm to make the code more readable. I also added a displayBoard function and moved changePlayer into a separate function.

Hope you like it :slight_smile:

const cells = document.querySelectorAll(".cell");
const statusText = document.querySelector("#statusText");
const restartBtn = document.querySelector("#restartBtn");
const winConditions = [
    [0,1,2],
    [3,4,5],
    [6,7,8],
    [0,3,6],
    [1,4,7],
    [2,5,8],
    [0,4,8],
    [2,4,6]
];
let options = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";
let running = false;

initializeGame();
    
function initializeGame(){

    cells.forEach(cell => cell.addEventListener("click",cellClicked))
    restartBtn.addEventListener("click", restartGame);
    statusText.textContent = `${currentPlayer}'s turn`;
    running = true;

}

function cellClicked(){
    const cellIndex = this.dataset.cellIndex;

    if(options[cellIndex] != "" || !running){
        return;
    }

    updateCell(this, cellIndex);
    
    checkWinner();

}

function updateCell(cell, index){
    options[index]= currentPlayer;
    cell.textContent = currentPlayer;

}

function changePlayer(){
    currentPlayer = (currentPlayer == "X") ? "O": "X";
    statusText.textContent =`${currentPlayer}'s turn`;
    

}

function checkWinner(){
    let roundWon = false;

    for(let i = 0 ; i < winConditions.length; i++){
        const condition = winConditions[i];
        const cellA = options[condition[0]];
        const cellB = options[condition[1]];
        const cellC = options[condition[2]];

        if (cellA =="" || cellB == "" || cellC == ""){
            continue;
        }

        if(cellA==cellB && cellB==cellC){
            roundWon = true;
            break;
        }

    }

    if (roundWon){
        statusText.textContent=`${currentPlayer} Wins!`
        running=false;
    }

    else if (!options.includes("")){
        statusText.textContent= `Draw!`
        running = false;
    } else {
        changePlayer();
    }


}

function restartGame(){

    currentPlayer = "X";
    options = ["","","","","","","","",""];
    statusText.textContent = `${currentPlayer}'s turn`;
    cells.forEach(cell => cell.textContent = "");
    running = true;

}
function getUserInput(nextPlayerSymbol, gameBoard) {
    let visualGameBoard = gameBoard.slice();
    for ( let index in visualGameBoard) {
        if ( visualGameBoard[index] === null ) {
            visualGameBoard[index] = index;
        }
    }
    return prompt(`Input integer from 0 to 8 representing next move:\n${visualGameBoard[0]} ${visualGameBoard[1]} ${visualGameBoard[2]}\n${visualGameBoard[3]} ${visualGameBoard[4]} ${visualGameBoard[5]}\n${visualGameBoard[6]} ${visualGameBoard[7]} ${visualGameBoard[8]}`);
}

function isMoveValid(coordinates, gameBoard) {
    return gameBoard[coordinates] === null;
}

function makeAMove(gameBoard, nextPlayerSymbol) {
    // clone the game board before placing moves in it
    let newGameBoard = gameBoard.slice();
    let coordinates = '';
    do {
        coordinates = getUserInput(nextPlayerSymbol, gameBoard);
        console.log(coordinates);
    } while ( !isMoveValid(coordinates, gameBoard) );
    console.log('setting new coordinate');
    newGameBoard[coordinates] = nextPlayerSymbol;

    return newGameBoard;
}

function hasLastMoverWon(lastMove, gameBoard) {
    let winnerCombos = [
        [0, 1, 2], 
        [3, 4, 5], 
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7], 
        [2, 5, 8],
        [0, 4, 8], 
        [2, 4, 6]
    ];
    for (let [i1, i2, i3] of winnerCombos) {
        if (gameBoard[i1] === lastMove &&
            gameBoard[i1] === gameBoard[i2] && 
            gameBoard[i1] === gameBoard[i3] 
           ) {
            return true;
        }
    }
    return false;
}

function isGameOver(gameBoard, currentPlayerSymbol) {
    // 1. check if there is a winner 
    lastMove = currentPlayerSymbol;
    if (hasLastMoverWon(lastMove, gameBoard) ) {
        // Write a message that last mover has won the game
        alert(`Congratulations, ${currentPlayerSymbol} has won the game`);
        return true;
    }
    // 2. check if the board is full
    if (!gameBoard.some(element => element === null)) {
        return true;
    }

    // Return: winner/draw OR game is still in progress
    return false;
}

function ticTacToe() {
    // State space 
    let gameBoard = new Array(9).fill(null);
    let players = ['X', 'O'];
    let nextPlayerIndex = 0;

    // Computations 
   do {
        nextPlayerIndex = 1 - nextPlayerIndex; 
        currentPlayerSymbol = players[nextPlayerIndex];
        gameBoard = makeAMove(gameBoard, currentPlayerSymbol);
    } while ( !isGameOver(gameBoard, currentPlayerSymbol) );
    
    // Return value 
    // return undefined;
} 

I had problems caused by the ‘while’ loop and very inconvenient game-play with ‘prompt’. So instead used html buttons clicakable by mouse as an input, which made for a more linear code execution, and tried to stick to using arrays although objects form might have produced a sleeker code.

const players = ['X', 'O']
const winningArrays = [
    ['A1', 'B1', 'C1'],
    ['A2', 'B2', 'C2'],
    ['A3', 'B3', 'C3'],
    ['A1', 'A2', 'A3'],
    ['B1', 'B2', 'B3'],
    ['C1', 'C2', 'C3'],
    ['A1', 'B2', 'C3'],
    ['A3', 'B2', 'C1'],
]
let playerX = true
let winner
let gameBoard = [[], []]
let nextPlayerIndex = 0


function getBox(coordinates){
    return document.getElementById(coordinates)
}

function writeToBox(coordinates, gameBoard, nextPlayerIndex){
    gameBoard[nextPlayerIndex].push(coordinates)
    return (getBox(coordinates)).value = players[nextPlayerIndex]
}

function isTacTacToe(gameBoard, nextPlayerIndex){
    if( gameBoard === undefined ||
        nextPlayerIndex === undefined 
    ) return false


    const [...gameBoardCopy] = [...gameBoard]
    gameBoardCopy[nextPlayerIndex].sort()

    winningArrays.forEach(array =>{
        let arrayOfInterest = array

        if(
            gameBoardCopy[nextPlayerIndex].includes(arrayOfInterest[0]) &&
            gameBoardCopy[nextPlayerIndex].includes(arrayOfInterest[1]) &&
            gameBoardCopy[nextPlayerIndex].includes(arrayOfInterest[2])         
            ){
                arrayOfInterest.forEach(element =>{
                    const box = document.getElementById(element)
                    box.innerHTML = players[nextPlayerIndex].toLowerCase()
                    winner = players[nextPlayerIndex]
                })
                const message = document.getElementById('message')
                message.innerHTML = `${players[nextPlayerIndex]} WINS!` 
                
            } 

    })

    if (winner !== undefined){
        return true
    } 

    
 
}


function isMoveValid(coordinates, gameBoard){
    if(coordinates === null) return
//check that input is valid
    if(
        coordinates[0] !=='A' && 
        coordinates[0] !=='B' &&
        coordinates[0] !=='C' 
        ) return false
        
    if (coordinates[1] < 0 || coordinates[1] > 3) return false

 //parse gameboard for included coordinates
    if (gameBoard[0].includes(coordinates) ||
    gameBoard[1].includes(coordinates)) return false

    return true   
}

function isGameOver(gameBoard, nextPlayerIndex){
    //1.check for winner
    if(isTacTacToe(gameBoard, nextPlayerIndex) === true){
        return true
    }
    //2. check if board full
    if(gameBoard[0].length + gameBoard[1].length >= 9){ 
        const message = document.getElementById('message')
        message.innerHTML = `DRAW` 
        return true
    } 

    return false

}

function tictactoe(coordinates){

    //is move valid
    if (isMoveValid(coordinates, gameBoard)){
        let post = document.getElementById('message')
        post.innerHTML = '' 

        //write move
        writeToBox(coordinates, gameBoard, nextPlayerIndex)

        //check for win/game over
        if(isGameOver(gameBoard, nextPlayerIndex)){
            alert("Thank You for Playing!")
        }

        //switch player
        playerX = !playerX
        nextPlayerIndex = playerX ? 0 : 1

    } else { 
        let post = document.getElementById('message')
        post.innerHTML = 'Invalid Move' 

}
}

.gameBoardButtons {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    width:50vw;
    height:50vw;
    border: 1px solid black;
}
.buttonBox{
    border: 1px solid black;
    border-radius: 4px;
    width:14vw;
    height:14vw;
    font-size: 10vw;
    translate: 0px;
    cursor: pointer;

}
 
  .buttonBox:hover {
    background-color: #04AA6D;
    color: white;
  }
<body>
    <h1 >TIC TAC TOE</h1>


    <div class="gameBoardButtons">
        <form>
        <input type="button" class='buttonBox' id="A1" value="" onclick="tictactoe('A1')">
        <input type="button" class='buttonBox' id="A2" value="" onclick="tictactoe('A2')">
        <input type="button" class='buttonBox' id="A3" value="" onclick="tictactoe('A3')">
        <input type="button" class='buttonBox' id="B1" value="" onclick="tictactoe('B1')">
        <input type="button" class='buttonBox' id="B2" value="" onclick="tictactoe('B2')">
        <input type="button" class='buttonBox' id="B3" value="" onclick="tictactoe('B3')">
        <input type="button" class='buttonBox' id="C1" value="" onclick="tictactoe('C1')">
        <input type="button" class='buttonBox' id="C2" value="" onclick="tictactoe('C2')">
        <input type="button" class='buttonBox' id="C3" value="" onclick="tictactoe('C3')">

        </form>
    </div>
    <h2 id="message">Message Board</h2>

    
</body>```