Untitled

 avatar
unknown
javascript
4 years ago
8.2 kB
8
Indexable
const gameBoard = (function (){
  let board = [
    ['', '', ''],
    ['', '', ''],
    ['', '', '']
  ];
  return {board};
})();

const gameHandler = (function (){
  let player1Name = "";
  let player2Name = "";
  let xRowCount = 0;
  let oRowCount = 0;
  let xColCount = 0;
  let oColCount = 0;
  let scores = {
    X: 1,
    O: -1,
    tie: 0
  };

  const form = document.querySelector("form");
  const boardCells = document.querySelector(".board-cells");
  const player1Input = document.querySelector("#player1-name");
  const player2Input = document.querySelector("#player2-name");
  const submitBtn = document.querySelector(".submit-btn");

  const startGame = () => {
    submitBtn.addEventListener("click", (event) => {
      event.preventDefault();
      if(player1Input.value && player2Input.value){
        form.style.cssText = "display:none";
        boardCells.style.cssText = "display:grid"; 
      }
      player1Name = player1Input.value;
      player2Name = player2Input.value;
      const p = Player();
      p.selectOption();
    });
  }

  const checkWinner = () => {
    for(let i = 0; i < 3; i++){
      xRowCount = 0;
      oRowCount = 0;
      xColCount = 0;
      oColCount = 0;
      for(let j = 0; j < 3; j++){
        // rows
        if(gameBoard.board[i][j] === 'X') xRowCount++;
        if(gameBoard.board[i][j] === 'O') oRowCount++;
      
        // diagonals
        if(gameBoard.board[0][0] === 'X' && gameBoard.board[1][1] === 'X' && gameBoard.board[2][2] === 'X') xRowCount = 3;
        if(gameBoard.board[0][2] === 'X' && gameBoard.board[1][1] === 'X' && gameBoard.board[2][0] === 'X') xRowCount = 3;
        if(gameBoard.board[0][0] === 'O' && gameBoard.board[1][1] === 'O' && gameBoard.board[2][2] === 'O') oRowCount = 3;
        if(gameBoard.board[0][2] === 'O' && gameBoard.board[1][1] === 'O' && gameBoard.board[2][0] === 'O') oRowCount = 3;
      
        // columns
        if(gameBoard.board[j][i] === 'X') xColCount++;
        if(gameBoard.board[j][i] === 'O') oColCount++;
      
        if(xRowCount === 3 || xColCount === 3) return 'X';
        if(oRowCount === 3 || oColCount === 3) return 'O';
      }
    }
  }

  const minixmax = (board, depth, isMaximizing) => {
    let winner = checkWinner();
    if(winner !== undefined){
      return scores[winner];
    }

    if(isMaximizing){
      let bestScore = -Infinity;
      for(let i = 0; i < board.length; i++){
        for(let j = 0; j < board[i].length; j++){
          if(board[i][j] === ''){
            board[i][j] = 'O';
            let score = minixmax(board, depth + 1, false);
            board[i][j] = '';
            bestScore = Math.max(score, bestScore); 
          }
        }
      }
      return bestScore;
    } else {
      let bestScore = Infinity;
      for(let i = 0; i < board.length; i++){
        for(let j = 0; j < board[i].length; j++){
          if(board[i][j] === ''){
            board[i][j] = 'O'
            let score = minixmax(board, depth + 1, true);
            board[i][j] = '';
            bestScore = Math.min(score, bestScore);
          }
        }
      }
      return bestScore;
    }
  }

  return {startGame, checkWinner, minixmax};
})();

const displayController = (function displayController(){

  const {checkWinner, minixmax} = gameHandler;
  let currentPlayer;
  let isAiGame = false;
  let turnCount = 0;

  const cell = document.querySelectorAll(".cell");
  const startBtn = document.querySelector(".start-btn");
  const selectMenu = document.querySelector(".select-menu");
  const playerVsPlayerBtn = document.querySelector("#player-vs-player");
  const playerVsAiBtn = document.querySelector("#player-vs-ai");
  const form = document.querySelector("form");
  const player1Input = document.querySelector("#player1-name");
  const player2Input = document.querySelector("#player2-name");
  const winnerMenu = document.querySelector('.winner-menu');
  const winnerName = document.querySelector('.title3');
  const restartBtn= document.querySelector("#restart-btn");
  const newGameBtn= document.querySelector("#newgame-btn");
  const boardCells = document.querySelector(".board-cells");
  const p2Title = document.querySelector("#p2");

  const render = () => {
    for(let i = 0; i < gameBoard.board.length; i++){
      for(let j = 0; j < gameBoard.board[i].length; j++){
        let span = document.querySelector(`span[data-key="${i},${j}"]`)
        span.innerHTML = gameBoard.board[i][j];
      }
    }
  }
  
  const selectOption = () => {
    currentPlayer = 'X';
    cell.forEach(c => {
      c.addEventListener("click", (event) => {
        turnCount++;
        if(event.target.querySelector("span") === null) return;
        let span = event.target.querySelector("span");
        let dataKey = span.dataset.key;
          if(!span.innerHTML && !isAiGame){
            if(gameBoard.board[dataKey[0]][dataKey[2]] === 'X' || gameBoard.board[dataKey[0]][dataKey[2]] === 'O'){
              currentPlayer = gameBoard.board[dataKey[0]][dataKey[2]];
            }
            gameBoard.board[dataKey[0]][dataKey[2]] = currentPlayer;
            span.innerHTML = currentPlayer;
            if(currentPlayer === 'O'){
              currentPlayer = 'X'
            } else {
              currentPlayer = 'O';
            }
            displayWinner();
        } else if(isAiGame && !span.innerHTML) {
            let bestScore = -Infinity;
            let bestMove;
            gameBoard.board[dataKey[0]][dataKey[2]] = 'X';
            for(let i = 0; i < gameBoard.board.length; i++){
              for(let j = 0; j < gameBoard.board[i].length; j++){
                if(gameBoard.board[i][j] === ''){
                  gameBoard.board[i][j] = 'O';
                  let score = minixmax(gameBoard.board, 0, false);
                  gameBoard.board[i][j] = '';
                  if(score > bestScore){
                    bestScore = score;
                    bestMove = { i, j };
                  }
                }
              }
            }
            gameBoard.board[bestMove.i][bestMove.j] = 'O';
            render();
            displayWinner();
        }
      });
    });
  }

  const restartGame = () => {
    restartBtn.addEventListener("click", (event) => {
      gameBoard.board = [
        ['', '', ''],
        ['', '', ''],
        ['', '', '']
      ];
      render();
      turnCount = 0;
      currentPlayer = 'X';
      winnerMenu.style.cssText = "display:none;";
      selectOption();
    });
  }

  const newGame = () => {
    newGameBtn.addEventListener("click", (event) => {
      gameBoard.board = [
        ['', '', ''],
        ['', '', ''],
        ['', '', '']
      ];
      turnCount = 0;
      restartGame();
      winnerMenu.style.cssText = "display:none;";
      selectMenu.style.cssText = "display:flex";
      boardCells.style.cssText = "display:none";
      render();
    });
  }

  const handleMenus = () => {

    startBtn.addEventListener("click", (event) => {
      startBtn.style.cssText = "display:none;";
      selectMenu.style.cssText = "display:flex";
    });

    playerVsPlayerBtn.addEventListener("click", (event) => {
      form.style.cssText = "display:block";
      selectMenu.style.cssText = "display:none";
      player1Input.value = "";
      player2Input.value = "";
    });

    playerVsAiBtn.addEventListener("click", (event) => {
      p2Title.innerHTML = "AI Name";
      form.style.cssText = "display:block";
      selectMenu.style.cssText = "display:none";
      player1Input.value = "";
      player2Input.value = "";
      isAiGame = true;
    });
  }

  const displayWinner = () => {
    let winner = checkWinner();
    
    if (turnCount === 9 && !winner) {
      winnerMenu.style.cssText = "display:flex";
      winnerName.innerHTML = "It's a tie!";
    } else if (winner){
      winnerMenu.style.cssText = "display:flex";
      winnerName.innerHTML = `${winner} Win's`;
    }
  }

  return {selectOption, handleMenus, restartGame, newGame};
})();

displayController.handleMenus();
gameHandler.startGame();
displayController.restartGame();
displayController.newGame();

function Player(){
  const {selectOption} = displayController;
  
  return {selectOption};
} 
Editor is loading...