Currently, I am using an algorithm that finds the best move based on the existing states of the board. Is there a better way to do it? Is there a data structure that I can use?
I have also considered the MinMax algorithm, but did not want to use it as it checks for every possibility on every turn.
var playerSym;
var computerSym;
var turnCount=0;
var playerWin=0;
var compWin=0;
var whoseTurn;
var grid=[];
var winFlag=false;
function initialiseGrid(){
var k=0;
for(var i=0;i<9;i++){
grid[i]=document.getElementById(k);
k++;
}
}
function enterPlayerChoice(eventSrc){
if(!(document.getElementById("x").checked||document.getElementById("o").checked)){
alert("Choose Your Symbol");
return;
}
var target=eventSrc.target;
if(target.innerText!=="")
return;
turnCount++;
var txtNode=document.createTextNode(playerSym);
target.appendChild(txtNode);
//playerMoves.push(Number(target.id));
whoseTurn="Player";
if(turnCount>3)
checkWin();
if(turnCount>8&&winFlag==false){
if(confirm("Its A Draw!!"))
gameReset();
}
else
computersTurn();
}
function computersTurn(){
whoseTurn="Computer";
if(document.getElementById("easy").checked)
playEasy();
else
playHard();
}
function getRandomNum(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function playEasy(){
turnCount++;
var boxNum=getRandomNum(0,8);
while(document.getElementById(boxNum).innerText!=="")
boxNum=getRandomNum(0,8);
insertCompChoice(boxNum);
if(turnCount>3)
checkWin();
if(turnCount>8&&winFlag==false)
if(confirm("Its A Draw!!"))
gameReset();
}
function insertCompChoice(boxNum){
var txtNode=document.createTextNode(computerSym);
document.getElementById(boxNum).appendChild(txtNode);
}
function checkForWin(){
//diagonal left to right
if((grid[0].innerText==computerSym&&grid[4].innerText==computerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[0].innerText==computerSym&&grid[8].innerText==computerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==computerSym&&grid[8].innerText==computerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
//diagonal right to left
else if((grid[2].innerText==computerSym&&grid[4].innerText==computerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[6].innerText==computerSym&&grid[2].innerText==computerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==computerSym&&grid[6].innerText==computerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
//first row
else if((grid[0].innerText==computerSym&&grid[1].innerText==computerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
else if((grid[1].innerText==computerSym&&grid[2].innerText==computerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
else if((grid[0].innerText==computerSym&&grid[2].innerText==computerSym)&&(document.getElementById(grid[1].id).innerText==="")){
return Number(grid[1].id);}
//second row
else if((grid[3].innerText==computerSym&&grid[5].innerText==computerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[3].innerText==computerSym&&grid[4].innerText==computerSym)&&(document.getElementById(grid[5].id).innerText==="")){
return Number(grid[5].id);}
else if((grid[4].innerText==computerSym&&grid[5].innerText==computerSym)&&(document.getElementById(grid[3].id).innerText==="")){
return Number(grid[3].id);}
//third Row
else if((grid[7].innerText==computerSym&&grid[8].innerText==computerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[6].innerText==computerSym&&grid[7].innerText==computerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[8].innerText==computerSym&&grid[6].innerText==computerSym)&&(document.getElementById(grid[7].id).innerText==="")){
return Number(grid[7].id);}
//first coloumn
else if((grid[0].innerText==computerSym&&grid[3].innerText==computerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[0].innerText==computerSym&&grid[6].innerText==computerSym)&&(document.getElementById(grid[3].id).innerText==="")){
return Number(grid[3].id);}
else if((grid[3].innerText==computerSym&&grid[6].innerText==computerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
//second column
else if((grid[1].innerText==computerSym&&grid[4].innerText==computerSym)&&(document.getElementById(grid[7].id).innerText==="")){
return Number(grid[7].id);}
else if((grid[1].innerText==computerSym&&grid[7].innerText==computerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==computerSym&&grid[7].innerText==computerSym)&&(document.getElementById(grid[1].id).innerText==="")){
return Number(grid[1].id);}
//third column
else if((grid[2].innerText==computerSym&&grid[5].innerText==computerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[8].innerText==computerSym&&grid[2].innerText==computerSym)&&(document.getElementById(grid[5].id).innerText==="")){
return Number(grid[5].id);}
else if((grid[5].innerText==computerSym&&grid[8].innerText==computerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
return -1;
}
function blockOppWin(){
//diagonal left to right
if((grid[0].innerText==playerSym&&grid[4].innerText==playerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[0].innerText==playerSym&&grid[8].innerText==playerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==playerSym&&grid[8].innerText==playerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
//diagonal right to left
else if((grid[2].innerText==playerSym&&grid[4].innerText==playerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[6].innerText==playerSym&&grid[2].innerText==playerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==playerSym&&grid[6].innerText==playerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
//first row
else if((grid[0].innerText==playerSym&&grid[1].innerText==playerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
else if((grid[1].innerText==playerSym&&grid[2].innerText==playerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
else if((grid[0].innerText==playerSym&&grid[2].innerText==playerSym)&&(document.getElementById(grid[1].id).innerText==="")){
return Number(grid[1].id);}
//second row
else if((grid[3].innerText==playerSym&&grid[5].innerText==playerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[3].innerText==playerSym&&grid[4].innerText==playerSym)&&(document.getElementById(grid[5].id).innerText==="")){
return Number(grid[5].id);}
else if((grid[4].innerText==playerSym&&grid[5].innerText==playerSym)&&(document.getElementById(grid[3].id).innerText==="")){
return Number(grid[3].id);}
//third Row
else if((grid[7].innerText==playerSym&&grid[8].innerText==playerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[6].innerText==playerSym&&grid[7].innerText==playerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[8].innerText==playerSym&&grid[6].innerText==playerSym)&&(document.getElementById(grid[7].id).innerText==="")){
return Number(grid[7].id);}
//first coloumn
else if((grid[0].innerText==playerSym&&grid[3].innerText==playerSym)&&(document.getElementById(grid[6].id).innerText==="")){
return Number(grid[6].id);}
else if((grid[0].innerText==playerSym&&grid[6].innerText==playerSym)&&(document.getElementById(grid[3].id).innerText==="")){
return Number(grid[3].id);}
else if((grid[3].innerText==playerSym&&grid[6].innerText==playerSym)&&(document.getElementById(grid[0].id).innerText==="")){
return Number(grid[0].id);}
//second column
else if((grid[1].innerText==playerSym&&grid[4].innerText==playerSym)&&(document.getElementById(grid[7].id).innerText==="")){
return Number(grid[7].id);}
else if((grid[1].innerText==playerSym&&grid[7].innerText==playerSym)&&(document.getElementById(grid[4].id).innerText==="")){
return Number(grid[4].id);}
else if((grid[4].innerText==playerSym&&grid[7].innerText==playerSym)&&(document.getElementById(grid[1].id).innerText==="")){
return Number(grid[1].id);}
//third column
else if((grid[2].innerText==playerSym&&grid[5].innerText==playerSym)&&(document.getElementById(grid[8].id).innerText==="")){
return Number(grid[8].id);}
else if((grid[8].innerText==playerSym&&grid[2].innerText==playerSym)&&(document.getElementById(grid[5].id).innerText==="")){
return Number(grid[5].id);}
else if((grid[5].innerText==playerSym&&grid[8].innerText==playerSym)&&(document.getElementById(grid[2].id).innerText==="")){
return Number(grid[2].id);}
return -1;
}
function blockOppFork(){
if(grid[0].innerText==playerSym&&grid[4].innerText==playerSym&&grid[8].innerText==computerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
else if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[4].innerText==playerSym&&grid[8].innerText==playerSym&&grid[0].innerText==computerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
else if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[0].innerText==playerSym&&grid[8].innerText==playerSym&&grid[4].innerText==computerSym){
if(document.getElementById(grid[1].id).innerText==="")
return Number(grid[1].id);
else if(document.getElementById(grid[3].id).innerText==="")
return Number(grid[3].id);
else if(document.getElementById(grid[5].id).innerText==="")
return Number(grid[5].id);
else if(document.getElementById(grid[7].id).innerText==="")
return Number(grid[7].id);
}
if(grid[4].innerText==computerSym&&grid[3].innerText==playerSym&&grid[7].innerText==playerSym){
if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[4].innerText==computerSym&&grid[3].innerText==playerSym&&grid[1].innerText==playerSym){
if(document.getElementById(grid[0].id).innerText==="")
return Number(grid[0].id);
}
if(grid[4].innerText==computerSym&&grid[1].innerText==playerSym&&grid[5].innerText==playerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
}
if(grid[4].innerText==computerSym&&grid[5].innerText==playerSym&&grid[7].innerText==playerSym){
if(document.getElementById(grid[8].id).innerText==="")
return Number(grid[8].id);
}
return -1;
}
function createFork(){
if(grid[0].innerText==computerSym&&grid[4].innerText==computerSym&&grid[8].innerText==playerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
else if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[4].innerText==computerSym&&grid[8].innerText==computerSym&&grid[0].innerText==playerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
else if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[0].innerText==computerSym&&grid[8].innerText==computerSym&&grid[4].innerText==playerSym){
if(document.getElementById(grid[1].id).innerText==="")
return Number(grid[1].id);
else if(document.getElementById(grid[3].id).innerText==="")
return Number(grid[3].id);
else if(document.getElementById(grid[5].id).innerText==="")
return Number(grid[5].id);
else if(document.getElementById(grid[7].id).innerText==="")
return Number(grid[7].id);
}
if(grid[4].innerText==playerSym&&grid[3].innerText==computerSym&&grid[7].innerText==computerSym){
if(document.getElementById(grid[6].id).innerText==="")
return Number(grid[6].id);
}
if(grid[4].innerText==playerSym&&grid[3].innerText==computerSym&&grid[1].innerText==computerSym){
if(document.getElementById(grid[0].id).innerText==="")
return Number(grid[0].id);
}
if(grid[4].innerText==playerSym&&grid[1].innerText==computerSym&&grid[5].innerText==computerSym){
if(document.getElementById(grid[2].id).innerText==="")
return Number(grid[2].id);
}
if(grid[4].innerText==playerSym&&grid[5].innerText==computerSym&&grid[7].innerText==computerSym){
if(document.getElementById(grid[8].id).innerText==="")
return Number(grid[8].id);
}
return -1;
}
function playHard(){
/*
//////////////////////
The first two turns decide the game.
First Turn:
Take corner or center.
Second Turn:
If Center is empty take it.
If not, take a corner.
From third turn onwards,
1) play for win
2) block opp win
3) block fork
4) create fork to win
5) play center if open
6) play corner
7) If AI reaches this stage, all possible win combinations are gone. Play a random box(mostly line centers) and draw the game.
//////////////////////
*/
turnCount++;
var boxNum;
if((turnCount==1)){
boxNum=getRandomNum(0,8);
while((document.getElementById(boxNum).innerText!=="")||(boxNum==1||boxNum==3||boxNum==5||boxNum==7)){
//alert(boxNum==1||boxNum==3||boxNum==5||boxNum==7);
boxNum=getRandomNum(0,8);
}
insertCompChoice(boxNum);
}
else if(turnCount==2){
if(document.getElementById("4").innerText==="")
boxNum=4;
else{
boxNum=getRandomNum(0,8);
while((document.getElementById(boxNum).innerText!=="")||(boxNum==1||boxNum==3||boxNum==5||boxNum==7))
boxNum=getRandomNum(0,8);
}
insertCompChoice(boxNum);
}
else if(turnCount>2){
//alert("s");
//alert(checkForWin()+"win");
//alert(blockOppWin()+"bloxck");
if(checkForWin()!==-1){
boxNum=checkForWin();
insertCompChoice(boxNum);
checkWin();
}
else if(blockOppWin()!==-1){
boxNum=blockOppWin();
insertCompChoice(boxNum);
}
else if(blockOppFork()!==-1){
boxNum=blockOppFork();
insertCompChoice(boxNum);
}
else if(createFork()!==-1){
boxNum=createFork();
insertCompChoice(boxNum);
}
else if(document.getElementById("4").innerText==="")
insertCompChoice(4);
else if(document.getElementById("0").innerText===""||document.getElementById("2").innerText===""||document.getElementById("8").innerText===""||document.getElementById("6").innerText===""){
boxNum=getRandomNum(0,8);
while((document.getElementById(boxNum).innerText!=="")||(boxNum==1||boxNum==3||boxNum==5||boxNum==7))
boxNum=getRandomNum(0,8);
insertCompChoice(boxNum);
}
else{
boxNum=getRandomNum(0,8);
while(document.getElementById(boxNum).innerText!=="")
boxNum=getRandomNum(0,8);
insertCompChoice(boxNum);
}
}
if(turnCount>3)
checkWin();
if(turnCount>8&&winFlag==false)
if(confirm("Its A Draw!!"))
gameReset();
}
function checkWin(){
var symToCompare;
if(whoseTurn=="Player")
symToCompare=playerSym;
else if(whoseTurn=="Computer")
symToCompare=computerSym;
if(grid[0].innerText==symToCompare&&grid[1].innerText==symToCompare&&grid[2].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[3].innerText==symToCompare&&grid[4].innerText==symToCompare&&grid[5].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[6].innerText==symToCompare&&grid[7].innerText==symToCompare&&grid[8].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[0].innerText==symToCompare&&grid[3].innerText==symToCompare&&grid[6].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[1].innerText==symToCompare&&grid[4].innerText==symToCompare&&grid[7].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[2].innerText==symToCompare&&grid[5].innerText==symToCompare&&grid[8].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[0].innerText==symToCompare&&grid[4].innerText==symToCompare&&grid[8].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
if(grid[2].innerText==symToCompare&&grid[4].innerText==symToCompare&&grid[6].innerText==symToCompare){
winFlag=true;
if(confirm(whoseTurn+" wins. Play Again??"))
gameReset();
}
}
function gameReset(){
var cells=document.getElementsByClassName("box");
var i=0;
while(i<cells.length)
cells[i++].innerText="";
turnCount=0;
whoseTurn="";
winFlag=false;
}
window.addEventListener("load",initialiseGrid);
document.getElementById("x").addEventListener("click",function(){
playerSym="X";
computerSym="O";
});
document.getElementById("o").addEventListener("click",function(){
playerSym="O";
computerSym="X";
});
document.getElementById("reset").addEventListener("click",gameReset);
document.getElementById("0").addEventListener("click",enterPlayerChoice);
document.getElementById("1").addEventListener("click",enterPlayerChoice);
document.getElementById("2").addEventListener("click",enterPlayerChoice);
document.getElementById("3").addEventListener("click",enterPlayerChoice);
document.getElementById("4").addEventListener("click",enterPlayerChoice);
document.getElementById("5").addEventListener("click",enterPlayerChoice);
document.getElementById("6").addEventListener("click",enterPlayerChoice);
document.getElementById("7").addEventListener("click",enterPlayerChoice);
document.getElementById("8").addEventListener("click",enterPlayerChoice);
Full code here.
Also, is there any replacement for the ugly "if-else" that I can implement in the code?