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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск

Описание[править]

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

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

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

Визуализация[править]

Код программы[править]

Код программы на языке JavaScript:
  1 var origBoard;
  2 
  3 
  4 const huPlayer = 'O';
  5 const aiPlayer = 'X';
  6 
  7 const winCombos = [
  8     [0, 1, 2],
  9     [3, 4, 5],
 10     [6, 7, 8],
 11     [0, 3, 6],
 12     [1, 4, 7],
 13     [2, 5, 8],
 14     [0, 4, 8],
 15     [6, 4, 2]
 16 ]
 17 
 18 const cells = document.querySelectorAll('.cell');
 19 startGame();
 20  
 21 
 22 function startGame() {
 23     document.querySelector(".endgame").style.display = "none";
 24     origBoard = Array.from(Array(9).keys());
 25    
 26     for (let index = 0; index < cells.length; index++) {
 27         cells[index].innerText = '';
 28         cells[index].style.removeProperty('background-color');
 29         cells[index].addEventListener('click', turnClick, false);
 30     }
 31 }
 32 
 33 function turnClick(square) {
 34    
 35     if (typeof origBoard[square.target.id] == 'number') {
 36         turn(square.target.id, huPlayer)
 37         if (!checkTie()) turn(bestSpot(), aiPlayer);
 38     }
 39 }
 40 
 41 function turn(squareId, player) {
 42     origBoard[squareId] = player;
 43     document.getElementById(squareId).innerText = player;
 44     let gameWon = checkWin(origBoard, player);
 45     if (gameWon) gameOver(gameWon)
 46 }
 47 
 48 function checkWin(board, player) {
 49     let plays = board.reduce((a, e, i) => 
 50         (e === player) ? a.concat(i) : a, []);
 51     let gameWon = null;
 52     for (let [index, win] of winCombos.entries()) {
 53         if (win.every(elem => plays.indexOf(elem) > -1)) {
 54             gameWon = {index: index, player: player};
 55             break;
 56         }
 57     }
 58 
 59     return gameWon;
 60 	updateStat();
 61 }
 62 
 63 function gameOver(gameWon) {
 64     for (let index of winCombos[gameWon.index]) {
 65         document.getElementById(index).style.backgroundColor =
 66         gameWon.player == huPlayer ? "blue" : "red";
 67     }
 68     for (var i = 0; i < cells.length; i++) {
 69         cells[i].removeEventListener('click', turnClick, false);
 70     }
 71     declareWinner(gameWon.player == huPlayer ? "Вы выиграли!" : "Вы проиграли!")
 72 	updateStat();
 73 }
 74 
 75 function declareWinner(who) {
 76     document.querySelector(".endgame").style.display = "block";
 77     document.querySelector(".endgame .text").innerText = who;
 78 }
 79 
 80 function emptySquares() {
 81     return origBoard.filter(s => typeof s == 'number');
 82 }
 83 
 84 function bestSpot() {
 85    
 86     return minimax(origBoard, aiPlayer).index;
 87 }
 88 
 89 
 90 function checkTie() {
 91     if (emptySquares().length == 0) {
 92         for (var i = 0; i < cells.length; i++) {
 93             cells[i].style.backgroundColor = "green";
 94             cells[i].removeEventListener('click', turnClick, false);
 95         }
 96         declareWinner("Ничья!");
 97         return true;
 98     }
 99     return false;
100 	 updateStat();
101 }
102  
103 
104 
105 function minimax(newBoard, player) {
106     var availSpots = emptySquares(newBoard);
107 
108     if (checkWin(newBoard, player)) {
109         return {score: -10};
110     } else if (checkWin(newBoard, aiPlayer)) {
111         return {score: 10}; 
112     } else if (availSpots.length === 0) {
113         return {score: 0}
114     }
115 
116     var moves = [];
117     for (let index = 0; index < availSpots.length; index++) {
118         var move = {};
119         move.index = newBoard[availSpots[index]];
120         newBoard[availSpots[index]] = player;
121 
122         if (player == aiPlayer) {
123             var result = minimax(newBoard, huPlayer);
124             move.score = result.score;
125         } else {
126             var result = minimax(newBoard, aiPlayer);
127             move.score = result.score;
128         }
129 
130         newBoard[availSpots[index]] = move.index;
131 
132         moves.push(move);
133     }
134 
135     var bestMove;
136     if (player === aiPlayer) {
137         var bestScore = -10000;
138         for(var i = 0; i < moves.length; i++) {
139             if (moves[i].score > bestScore) {
140                 bestScore = moves[i].score;
141                 bestMove = i;
142             }
143         }
144     } else {
145         var bestScore = 10000;
146         for(var i = 0; i < moves.length; i++) {
147             if (moves[i].score < bestScore) {
148                 bestScore = moves[i].score;
149                 bestMove = i;
150             }
151         }
152     }
153 
154     return moves[bestMove];
155 }