TicTacToe(alpha-beta pruning)

In this example below you will see how to do a TicTacToe(alpha-beta pruning) with some HTML / CSS and Javascript

FreeCodeCamp AI Algorithm - alpha-beta pruning

Thumbnail
This awesome code was written by 1Moosey1, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright 1Moosey1 ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>TicTacToe(alpha-beta pruning)</title>
  
  
  <link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  <head>
  <link href='//fonts.googleapis.com/css?family=Andika' rel='stylesheet'>
</head>

<body>
  
  <!-- Container -->
  <div class="container-fluid">
    
    <header>
      <h1> Tic Tac Toe </h1>
      <h4> (Free Code Camp) </h4>
    </header>
    
    <!-- X/O Selection -->
    <div class="text-center" id="selection">
      
      <h3>
        Select X's or O's
      </h3>
      
      <button class="btn btn-primary" id="X">
        X </button>
      <button class="btn btn-primary" id="O">
        O </button>
      
    </div>
    <!-- X/O Selection -->
     
    <!-- Winner Display -->
    <div class="alert alert-info" id="msgdisplay">
      <h3 id="message"></h3>
      <a class="btn btn-danger" id="replay"> Play Again </a>
    </div>
    <!-- Winner Display -->
    
    <!-- Tic Tac Toe Board -->
    <div id="board">
      
      <table>
        <tbody>
          <tr>
            <td class="cell" data-id="0"></td>
            <td class="cell" data-id="1"></td>
            <td class="cell" data-id="2"></td>
          </tr>
          <tr>
            <td class="cell" data-id="3"></td>
            <td class="cell" data-id="4"></td>
            <td class="cell" data-id="5"></td>
          </tr>
          <tr>
            <td class="cell" data-id="6"></td>
            <td class="cell" data-id="7"></td>
            <td class="cell" data-id="8"></td>
          </tr>
        </tbody>
      </table>
      
    </div>
    <!-- Tic Tac Toe Board -->
    
  </div>
  <!-- Container -->
  
  <footer class="text-center">
    Design and Code by Juan Gonzalez
  </footer>
  
</body>
  <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/1Moosey1/tictactoealpha-beta-pruning-bqyGRX */
html, body {
  background-color: #C3CCCC;
}

header {
  
  color: #191919;
  text-align: center;
  margin: 30px 0 60px 0;
}

table {
  
  table-layout: fixed;
  margin: auto;
  
  box-shadow: 0px 0px 18px 4px #888888;
  vertical-align: middle;
  text-align: center;
}

td {
  
  border: 2px solid #191919;
  width: 20vh;
  height: 20vh;
  
  background-color: #859595;
  color: #191919;
  font-family: 'Andika';
  font-size: 5em;
}

footer {
  
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 25px;
}

.hover {
  background-color: #A9B4B4;
}

#msgdisplay {
  
  display: none;
  position: absolute;
  
  top: 10px;
  right: 10px;
  text-align: center;
}

#selection {
  display: none;
}

#board {
  display: none;
}

/*Downloaded from https://www.codeseek.co/1Moosey1/tictactoealpha-beta-pruning-bqyGRX */
var playerMark, computerMark;
var computerChoice;

var boardSize, gameBoard, gameOver;
var blankSpace = "_";

$("document").ready(function () {

  $("#selection").show();
  $("#X").click(selectX);
  $("#O").click(selectO);
  $(".cell").hover(hoverHandler);
  $(".cell").click(markCell);
  $("#msgdisplay").click(resetGame);
  
  boardSize = 9;
  initalizeGame();
});

// selectX - selectY
// Setup up game variables when user selects a marker
// 0 = O & 1 = X
function selectX(eventObj) {
  
  playerMark = 1;
  computerMark = 0;
  $("#selection").hide();
  $("#board").show();
}

function selectO(eventObj) {
  
  playerMark = 0;
  computerMark = 1;
  $("#selection").hide();
  $("#board").show();
}

// Handles the event when a user hovers over a cell
function hoverHandler(eventObj) {
  
  var cell = $(eventObj.target);
  cell.toggleClass("hover");
}

// Meant to initalize or reinitalize game board
function initalizeGame() {
  
  gameOver = false;
  gameBoard = new Array(boardSize);
  for (var i = 0; i < boardSize; i++)
    gameBoard[i] = blankSpace;
}

function resetGame() {
  
  $("#msgdisplay").hide();
  $(".cell").text("");
  initalizeGame();
  
  $("#board").hide();
  $("#selection").show();
}

function getXO(mark) {
  
  if(mark == 0)
    return "O";
  else
    return "X";
}

// Handles the event when a user clicks a cell
function markCell(eventObj) {
  
  var cell = $(eventObj.target);
  var index = parseInt(cell.attr("data-id"));
  
  if(!gameOver && gameBoard[index] == blankSpace) {
    
    cell.text(getXO(playerMark));
    gameBoard[index] = playerMark; 
    markAI();
  }
}

function markAI() {
  
  minimax(gameBoard, computerMark, -Infinity, Infinity);
  
  var cell = $("[data-id=" + computerChoice + "]");    
  cell.text(getXO(computerMark));
  gameBoard[computerChoice] = computerMark;
  
  var result = checkWin(gameBoard);
  if(result != 2) {
    
    gameOver = true;
    $("#msgdisplay").show();
    
    if(result == 1)
      $("#message").text("You are the Winner!");
    
    else if(result == -1)
      $("#message").text("Computer Wins!");
    
    else if(result == 0)
      $("#message").text("Game is a Draw!");
  }
}

// Determine the best move to make to minimize players score
function minimax(board, mark, alpha, beta) {
  
  var scores = [];
  var moves = [];
  var index, result, newBoard;
  
  result = checkWin(board);
  if(result != 2)
    return result;
  
  for(index = 0; index < boardSize; index++) {
    
    if(alpha >= beta)
      break;
    
    if(board[index] == blankSpace) {
      
      newBoard = board.slice(0);
      newBoard[index] = mark;
      
      result = minimax(newBoard, 1 - mark, alpha, beta);
      if(mark == playerMark && result > alpha)
        alpha = result;
  
      else if(mark == computerMark && result < beta)
        beta = result;
      
      moves.push(index);
      scores.push(result);
    }
  }
  
  if(mark == playerMark) {
    
    result = scores.reduce(function(a, b) {
      return Math.max(a, b); });
    index = scores.indexOf(result);
  }    
  
  else {
    
    result = scores.reduce(function(a, b) {
      return Math.min(a, b); });
    index = scores.indexOf(result);
  }
      
  computerChoice = moves[index];
  return scores[index];
}

// Check whether the game is a win, loss or draw
// -1 = Computer Win
//  0 = Draw
//  1 = Player Win
//  2 = Incomplete Game
function checkWin(board) {
  
  var winExps = [
	  "^(\\d)\\1\\1......$",
	  "^...(\\d)\\1\\1...$",
	  "^......(\\d)\\1\\1$",
	  "^(\\d)..\\1..\\1..$",
	  "^.(\\d)..\\1..\\1.$",
	  "^..(\\d)..\\1..\\1$",
	  "^(\\d)...\\1...\\1$",
	  "^..(\\d).\\1.\\1..$"
  ];

  var winRegex, matchArray;
  for(var i = 0; i < winExps.length; i++) {

	  winRegex = new RegExp(winExps[i]);
	  matchArray = winRegex.exec(board.join(""));
	  if(matchArray) break;
  }
  
  if(!matchArray) {
  
    if(board.includes(blankSpace))
      return 2;
    
    return 0;
  }
  
  else if(parseInt(matchArray[1]) == playerMark)
    return 1;
    
  else  
    return -1;
}

Comments