Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign uptic-tac-toe-minimax/js/main.js /
Find file
Copy path
Fetching contributors…
| var playerImage = new Image(); | |
| playerImage.src = "images/o.png"; | |
| var computerImage = new Image(); | |
| computerImage.src = "images/x.png"; | |
| var board = new Array(); | |
| var BOARD_SIZE = 9; | |
| var UNOCCUPIED = ' '; | |
| var HUMAN_PLAYER = 'O'; | |
| var COMPUTER_PLAYER = 'X'; | |
| var active_turn = "HUMAN"; | |
| var choice; | |
| var searchTimes = new Array(); | |
| var showAverageTime = true; | |
| function NewGame() | |
| { | |
| for (i = 0; i < BOARD_SIZE; i++) | |
| { | |
| board[i] = UNOCCUPIED; | |
| document.images[i].src = "images/blank.png"; | |
| } | |
| DeleteTimes(); | |
| showAverageTime = true; | |
| var alert = document.getElementById("turnInfo"); | |
| active_turn = "HUMAN"; | |
| alert.innerHTML = "Your turn!"; | |
| } | |
| function MakeMove(pos) | |
| { | |
| if (!GameOver(board) && board[pos] == UNOCCUPIED) | |
| { | |
| board[pos] = HUMAN_PLAYER; | |
| document.images[pos].src = playerImage.src; | |
| if (!GameOver(board)) | |
| { | |
| var alert = document.getElementById("turnInfo"); | |
| active_turn = "COMPUTER"; | |
| alert.innerHTML = "Computer's turn."; | |
| MakeComputerMove(); | |
| } | |
| } | |
| } | |
| function MakeComputerMove() | |
| { | |
| var start, end, time; | |
| start = new Date().getTime() / 1000; | |
| minimax(board, 0); | |
| end = new Date().getTime() / 1000; | |
| time = end - start; | |
| ShowTimes(time); | |
| var move = choice; | |
| board[move] = COMPUTER_PLAYER; | |
| document.images[move].src = computerImage.src; | |
| choice = []; | |
| active_turn = "HUMAN"; | |
| if (!GameOver(board)) | |
| { | |
| var alert = document.getElementById("turnInfo"); | |
| alert.innerHTML = "Your turn!"; | |
| } | |
| } | |
| function score(game, depth) { | |
| var score = CheckForWinner(game); | |
| if (score === 1) | |
| return 0; | |
| else if (score === 2) | |
| return depth-10; | |
| else if (score === 3) | |
| return 10-depth; | |
| } | |
| function minimax(tempBoardGame, depth) { | |
| if (CheckForWinner(tempBoardGame) !== 0) | |
| return score(tempBoardGame, depth); | |
| depth+=1; | |
| var scores = new Array(); | |
| var moves = new Array(); | |
| var availableMoves = GetAvailableMoves(tempBoardGame); | |
| var move, possible_game; | |
| for(var i=0; i < availableMoves.length; i++) { | |
| move = availableMoves[i]; | |
| possible_game = GetNewState(move, tempBoardGame); | |
| scores.push(minimax(possible_game, depth)); | |
| moves.push(move); | |
| tempBoardGame = UndoMove(tempBoardGame, move); | |
| } | |
| var max_score, max_score_index, min_score, | |
| min_score_index; | |
| if (active_turn === "COMPUTER") { | |
| max_score = Math.max.apply(Math, scores); | |
| max_score_index = scores.indexOf(max_score); | |
| choice = moves[max_score_index]; | |
| return scores[max_score_index]; | |
| } else { | |
| min_score = Math.min.apply(Math, scores); | |
| min_score_index = scores.indexOf(min_score); | |
| choice = moves[min_score_index]; | |
| return scores[min_score_index]; | |
| } | |
| } | |
| function UndoMove(game, move) { | |
| game[move] = UNOCCUPIED; | |
| ChangeTurn(); | |
| return game; | |
| } | |
| function GetNewState(move, game) { | |
| var piece = ChangeTurn(); | |
| game[move] = piece; | |
| return game; | |
| } | |
| function ChangeTurn() { | |
| var piece; | |
| if (active_turn === "COMPUTER") { | |
| piece = 'X'; | |
| active_turn = "HUMAN"; | |
| } else { | |
| piece = 'O'; | |
| active_turn = "COMPUTER"; | |
| } | |
| return piece; | |
| } | |
| function GetAvailableMoves(game) { | |
| var possibleMoves = new Array(); | |
| for (var i = 0; i < BOARD_SIZE; i++) | |
| if (game[i] === UNOCCUPIED) | |
| possibleMoves.push(i); | |
| return possibleMoves; | |
| } | |
| // Check for a winner. Return | |
| // 0 if no winner or tie yet | |
| // 1 if it's a tie | |
| // 2 if HUMAN_PLAYER won | |
| // 3 if COMPUTER_PLAYER won | |
| function CheckForWinner(game) { | |
| // Check for horizontal wins | |
| for (i = 0; i <= 6; i += 3) | |
| { | |
| if (game[i] === HUMAN_PLAYER && game[i + 1] === HUMAN_PLAYER && game[i + 2] === HUMAN_PLAYER) | |
| return 2; | |
| if (game[i] === COMPUTER_PLAYER && game[i + 1] === COMPUTER_PLAYER && game[i + 2] === COMPUTER_PLAYER) | |
| return 3; | |
| } | |
| // Check for vertical wins | |
| for (i = 0; i <= 2; i++) | |
| { | |
| if (game[i] === HUMAN_PLAYER && game[i + 3] === HUMAN_PLAYER && game[i + 6] === HUMAN_PLAYER) | |
| return 2; | |
| if (game[i] === COMPUTER_PLAYER && game[i + 3] === COMPUTER_PLAYER && game[i + 6] === COMPUTER_PLAYER) | |
| return 3; | |
| } | |
| // Check for diagonal wins | |
| if ((game[0] === HUMAN_PLAYER && game[4] === HUMAN_PLAYER && game[8] === HUMAN_PLAYER) || | |
| (game[2] === HUMAN_PLAYER && game[4] === HUMAN_PLAYER && game[6] === HUMAN_PLAYER)) | |
| return 2; | |
| if ((game[0] === COMPUTER_PLAYER && game[4] === COMPUTER_PLAYER && game[8] === COMPUTER_PLAYER) || | |
| (game[2] === COMPUTER_PLAYER && game[4] === COMPUTER_PLAYER && game[6] === COMPUTER_PLAYER)) | |
| return 3; | |
| // Check for tie | |
| for (i = 0; i < BOARD_SIZE; i++) | |
| { | |
| if (game[i] !== HUMAN_PLAYER && game[i] !== COMPUTER_PLAYER) | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| function GameOver(game) | |
| { | |
| if (CheckForWinner(game) === 0) | |
| return false; | |
| else if (CheckForWinner(game) === 1) | |
| { | |
| var alert = document.getElementById("turnInfo"); | |
| alert.innerHTML = "It is a tie."; | |
| } | |
| else if (CheckForWinner(game) === 2) | |
| { | |
| var alert = document.getElementById("turnInfo"); | |
| alert.innerHTML = "You have won! Congratulations!"; | |
| } | |
| else | |
| { | |
| var alert = document.getElementById("turnInfo"); | |
| alert.innerHTML = "The computer has won."; | |
| } | |
| ShowAverageTime(); | |
| return true; | |
| } | |
| function ShowTimes(time) { | |
| searchTimes.push(time); | |
| document.getElementById("searchTime").innerHTML = | |
| document.getElementById("searchTime").innerHTML + time + " seconds. <br />"; | |
| } | |
| function DeleteTimes() { | |
| searchTimes = []; | |
| document.getElementById("searchTime").innerHTML = ""; | |
| } | |
| function ShowAverageTime() { | |
| if (showAverageTime) | |
| { | |
| var sum = 0; | |
| var i = 0; | |
| for (i; i < searchTimes.length; i++) | |
| sum += searchTimes[i]; | |
| document.getElementById("searchTime").innerHTML = | |
| document.getElementById("searchTime").innerHTML + "<br />Average search was <strong>" + sum / i + "</strong> seconds. <br />"; | |
| showAverageTime = false; | |
| } | |
| } |