Крестики-нолики на js

Материал из Department of Theoretical and Applied Mechanics
Версия от 14:36, 13 июня 2021; 217.66.156.255 (обсуждение) (Код программы)

Перейти к: навигация, поиск

Описание

Реализация компьютерной игры "Крестики-Нолики" на языке программирования JavaScript.

Исполнители: Гаврилов Виталий , Иванов Тимофей , Ионин Александр

Группа 3630103/4 Кафедра Теоретической механики

Визуализация

Код программы

Код программы на языке JavaScript:

<syntaxhighlight lang="javascript" line start="1" enclose="div">

var origBoard;


const huPlayer = 'O'; const aiPlayer = 'X';

const winCombos = [

   [0, 1, 2],
   [3, 4, 5],
   [6, 7, 8],
   [0, 3, 6],
   [1, 4, 7],
   [2, 5, 8],
   [0, 4, 8],
   [6, 4, 2]

]

const cells = document.querySelectorAll('.cell'); startGame();


function startGame() {

   document.querySelector(".endgame").style.display = "none";
   origBoard = Array.from(Array(9).keys());
  
   for (let index = 0; index < cells.length; index++) {
       cells[index].innerText = ;
       cells[index].style.removeProperty('background-color');
       cells[index].addEventListener('click', turnClick, false);
   }

}

function turnClick(square) {

   if (typeof origBoard[square.target.id] == 'number') {
       turn(square.target.id, huPlayer)
       if (!checkTie()) turn(bestSpot(), aiPlayer);
   }

}

function turn(squareId, player) {

   origBoard[squareId] = player;
   document.getElementById(squareId).innerText = player;
   let gameWon = checkWin(origBoard, player);
   if (gameWon) gameOver(gameWon)

}

function checkWin(board, player) {

   let plays = board.reduce((a, e, i) => 
       (e === player) ? a.concat(i) : a, []);
   let gameWon = null;
   for (let [index, win] of winCombos.entries()) {
       if (win.every(elem => plays.indexOf(elem) > -1)) {
           gameWon = {index: index, player: player};
           break;
       }
   }
   return gameWon;

updateStat(); }

function gameOver(gameWon) {

   for (let index of winCombos[gameWon.index]) {
       document.getElementById(index).style.backgroundColor =
       gameWon.player == huPlayer ? "blue" : "red";
   }
   for (var i = 0; i < cells.length; i++) {
       cells[i].removeEventListener('click', turnClick, false);
   }
   declareWinner(gameWon.player == huPlayer ? "Вы выиграли!" : "Вы проиграли!")

updateStat(); }

function declareWinner(who) {

   document.querySelector(".endgame").style.display = "block";
   document.querySelector(".endgame .text").innerText = who;

}

function emptySquares() {

   return origBoard.filter(s => typeof s == 'number');

}

function bestSpot() {

   return minimax(origBoard, aiPlayer).index;

}


function checkTie() {

   if (emptySquares().length == 0) {
       for (var i = 0; i < cells.length; i++) {
           cells[i].style.backgroundColor = "green";
           cells[i].removeEventListener('click', turnClick, false);
       }
       declareWinner("Ничья!");
       return true;
   }
   return false;

updateStat(); }


function minimax(newBoard, player) {

   var availSpots = emptySquares(newBoard);
   if (checkWin(newBoard, player)) {
       return {score: -10};
   } else if (checkWin(newBoard, aiPlayer)) {
       return {score: 10}; 
   } else if (availSpots.length === 0) {
       return {score: 0}
   }
   var moves = [];
   for (let index = 0; index < availSpots.length; index++) {
       var move = {};
       move.index = newBoard[availSpots[index]];
       newBoard[availSpots[index]] = player;
       if (player == aiPlayer) {
           var result = minimax(newBoard, huPlayer);
           move.score = result.score;
       } else {
           var result = minimax(newBoard, aiPlayer);
           move.score = result.score;
       }
       newBoard[availSpots[index]] = move.index;
       moves.push(move);
   }
   var bestMove;
   if (player === aiPlayer) {
       var bestScore = -10000;
       for(var i = 0; i < moves.length; i++) {
           if (moves[i].score > bestScore) {
               bestScore = moves[i].score;
               bestMove = i;
           }
       }
   } else {
       var bestScore = 10000;
       for(var i = 0; i < moves.length; i++) {
           if (moves[i].score < bestScore) {
               bestScore = moves[i].score;
               bestMove = i;
           }
       }
   }
   return moves[bestMove];
}