Skip to content

Instantly share code, notes, and snippets.

@Oscarz90
Last active August 22, 2018 16:35
Show Gist options
  • Save Oscarz90/10d870b49d86e18e9fa899bc7db14e8f to your computer and use it in GitHub Desktop.
Save Oscarz90/10d870b49d86e18e9fa899bc7db14e8f to your computer and use it in GitHub Desktop.
Implementation of Tic Tac Toe Game with certain level of AI.
/**
* OMS
* August 2018
**/
/**
* Executes the move for a tic tac toe game given a player who plays the turn.
* @param {array} board The Board Game of tic tac toe with a state
* @param {string} player The player who plays the turn.
* @returns {array} board Returns the board with the move of the player
*/
function game(board,player){
// Tipes of players
const aPlayer="X", bPlayer="O";
// Defines the opponent in base of the player input
let opponent = player==aPlayer?bPlayer:aPlayer;
/**
* Find all the empty cells of a boardGame
* @param {array} boardGame A game board with or without empty cells
* @returns {array} emptyIndexes Returns an array with the indexes of the emtpy cells of a given game board
*/
function emtpyIndexes(boardGame){
return boardGame.reduce((spots,cell,index)=>{
if(cell!=aPlayer && cell!=bPlayer)
spots.push(index)
return spots
},[])
}
/**
* Validates a game board to check if a player with a given role has won the game
* @param {array} boardGame A game board
* @param {string} temporalPlayer The player who plays the turn
* @returns {boolean} won Returns a boolean value, true if the player win, false on the contrary case
*/
function validateGameBoardWinner(boardGame,temporalPlayer){
// Valid scenarios for a player to win the game
const scenarios=[
[0,1,2]
, [3,4,5]
, [6,7,8]
, [0,3,6]
, [1,4,7]
, [2,5,8]
, [0,4,8]
, [2,4,6]
]
//Validates all scenarios and returns the response.
return !!scenarios.find(scenario=>boardGame[scenario[0]]==temporalPlayer && boardGame[scenario[1]]==temporalPlayer && boardGame[scenario[2]]==temporalPlayer)
}
/**
* Find the best move for a given player and game board
* @param {*} boardGame The Board Game of tic tac toe with a state
* @param {*} temporalPlayer The player who plays the turn.
* @returns {object} bestMove Returns the best move for the given player
*/
function findBestSpot(boardGame,temporalPlayer){
// Obtains the available spots for the given game board
const availableSpots = emtpyIndexes(boardGame);
// Validates if the game ended
if(availableSpots.length==0){
return {score:0};
}else if(validateGameBoardWinner(boardGame,opponent)){
return {score:-10};
}else if(validateGameBoardWinner(boardGame,player)){
return {score:10};
}
const plays=[];
// Evaluates the best moves for the emtpy cells
const moves = availableSpots.map((emtpyCellIndex,index)=>{
let play ={index:emtpyCellIndex}, result;
boardGame[emtpyCellIndex] = temporalPlayer
if(temporalPlayer===player){
play.score = findBestSpot(boardGame,opponent).score;
}else{
play.score = findBestSpot(boardGame,player).score;
}
plays.push(play)
boardGame[emtpyCellIndex] = '-'
})
// Find the best move of the move list
let findBest = plays.reduce((total,play)=>{
if(play.score>total.bestScore){
total.bestScore = play.score;
total.best = play
}
return total;
},{bestScore:-100000,best:undefined})
// Returns the best move
return findBest.best
}
// Finds the best move for the given game board
const findTheBestMove = findBestSpot(board,player);
// Makes the move on the game board
board[findTheBestMove.index] = player;
// Returns the new board game's state
return board;
}
/**
* Examples
* Board Game Tic Tac Toe
* O | X | X
* X | - | -
* X | O | O
* Symbol "-" means emtpy
* The algorithm decides the best move for its turn
* The turn is for the player who is playin with "O"
*
* After execute the function it will return the board as this.
* O | X | X
* X | O | -
* X | O | O
*/
const board = ["O","X","X","X","-","-","X","O","O"]
console.log(game(board,"O"))
/**
* Examples
* Board Game Tic Tac Toe
* X | - | O
* - | - | -
* - | X | -
* Symbol "-" means emtpy
* The algorithm decides the best move for its turn
* The turn is for the player who is playin with "X"
*
* After execute the function it will return the board as this.
* X | X | O
* - | - | -
* - | X | -
*/
const boardTwo = ["X","-","O","-","-","-","-","X","-"]
console.log(game(boardTwo,"X"))
@Oscarz90
Copy link
Author

Oscarz90 commented Aug 22, 2018

TODO : Implement difficulty easy, medium and hard, it should decide using a difficulty preset that will affect directly in the way that the algorithm choose the best move, maybe not choosing the best move, an "alternative move", emulating a "mistake" due to is the only way of a player to win against the AI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment