1

I have been converting some Tic Tac Toe code to use bitboard so I can implement an AI opponent. As part of the test code I wanted to conduct a bitwise AND comparison to check if the moves are valid, then later to see available moves.

However I am getting some strange results when logging outputs. The third move in any game does not convert properly and therefore corrupts the AND comparison?

The html "id" tags which cellName is taken from are 0 - 7 from top left to Bottom Right.

Example One

Example Two

window.onload = init();
var playerNought = true;
const wins = [7, 56, 448, 73, 146, 292, 273, 84] // is the bitboard wins represented in decimal
var boardState = 0;
const noughtMoves = [];
const crossMoves = [];
function init(){
  playMove();
  var newGame = document.getElementById("newGame");
  newGame.onclick = function(){location.reload();};
}
function playMove(){
  var cells = document.getElementsByTagName("td");
  for (var i = 0; i < cells.length; i++) {
    cells[i].onclick = function(eventObj){
      var cellName = eventObj.target.id;
      var cell = document.getElementById(cellName);
      if(!cell.getAttribute("class")){
        if(playerNought){
          cell.setAttribute("class", "nought");
          noughtMoves.push(Number(cellName));
          checkMove(noughtMoves, "Nought");
        } else {
          cell.setAttribute("class", "cross");
          crossMoves.push(Number(cellName));
          checkMove(crossMoves, "Crosses");
        }
    }
      return playerNought = !playerNought;
    }
  }
}
function checkMove(moves, player) {
  const pattern = moves.reduce((acc, i) => acc | (1 << i), 0);  // Convert moves to bit board
  var validMove = boardState & pattern;

  console.log("Old Board State is " + boardState.toString(2));
  console.log("Pattern is:        " + pattern.toString(2));
  console.log("Board State &  is: " + validMove.toString(2));

  boardState = boardState | pattern;
  console.log("New Board State is " + boardState.toString(2));
  if(boardState == 511){setTimeout(()  =>  {if(confirm("It's a draw.")){location.reload();}},500)} // Check if game is a Draw


  const winLine = wins.some(win => (win & pattern) === win);  // Overlay each winning line pattern to see if there is a match
  if(winLine){
    var table = document.getElementById("table"); 
    const redLines = ["hLineTop", "hLineMid", "hLineBottom", "vLineLeft", "vLineMid", "vLineRight", "dLineLtoR", "dLineRtoL"]; 
    table.setAttribute("class", redLines[wins.findIndex((win) => win == pattern)]); 
    setTimeout(() => {if(confirm("Congratulations " + player + " wins!")){location.reload();}},500)
  }
}
Dave022
  • 43
  • 3

1 Answers1

2

By using the array.reduce to convert binary I was re-converting old moves, which didn't matter when it was an OR comparison, but did on the and.

const pattern = 1 << moves;

solved the issue

Dave022
  • 43
  • 3