Game cờ caro bằng javascript - simple version

Post Reply
User avatar
stararound
Posts: 22
Joined: Wed Apr 17, 2019 1:29 pm

Game cờ caro bằng javascript - simple version

Post by stararound »

Buồn buồn muốn chơi cờ caro mà không có ai chơi cùng buồn ơi là buồn.

May sao kiếm được cái script trên mạng về sửa lại rồi share cho các bạn thích chơi caro mà không có ai chơi thì tự làm một cái :D

1. Tạo file javascript - caro.js:

Code: Select all

boardSize=20;
userSq= 1;
machSq=-1;
blinkSq="b-1";
myTurn=false;
winningMove=9999999;
openFour   =8888888;
twoThrees  =7777777;

if (document.images) {
 uImg=new Image(16,16); uImg.src='s'+userSq+'.gif';
 mImg=new Image(16,16); mImg.src='s'+machSq+'.gif';
 bImg=new Image(16,16); bImg.src='s0.gif';
}

f=new Array();
s=new Array();
q=new Array();
for (i=0;i<20;i++) {
 f[i]=new Array();
 s[i]=new Array();
 q[i]=new Array();
 for (j=0;j<20;j++) {
  f[i][j]=0;
  s[i][j]=0;
  q[i][j]=0;
 }
}

iLastUserMove=0;
jLastUserMove=0;

function clk(iMove,jMove) {
 if (myTurn) return; 
 if (f[iMove][jMove]!=0) {alert('This square is not empty! Please choose another.'); return; }
 f[iMove][jMove]=userSq;
 drawSquare(iMove,jMove,userSq);
 myTurn=true;
 iLastUserMove=iMove;
 jLastUserMove=jMove;

 dly=(document.images)?10:boardSize*30;

 if (winningPos(iMove,jMove,userSq)==winningMove) setTimeout("alert('You won!');",dly);
 else setTimeout("machineMove(iLastUserMove,jLastUserMove);",dly);
}


function machineMove(iUser,jUser) {
 maxS=evaluatePos(s,userSq);
 maxQ=evaluatePos(q,machSq);

 // alert ('maxS='+maxS+', maxQ='+maxQ);

 if (maxQ>=maxS) {
  maxS=-1;
  for (i=0;i<boardSize;i++) {
   for (j=0;j<boardSize;j++) {
    if (q[i][j]==maxQ && s[i][j]>maxS) {
     maxS=s[i][j]; 
     iMach=i;
     jMach=j;
    }
   }
  }
 }

 else {
  maxQ=-1;
  for (i=0;i<boardSize;i++) {
   for (j=0;j<boardSize;j++) {
    if (s[i][j]==maxS && q[i][j]>maxQ) {
     maxQ=q[i][j]; 
     iMach=i;
     jMach=j;
    }
   }
  }
 }

 f[iMach][jMach]=machSq;
 if (document.images) {
  drawSquare(iMach,jMach,blinkSq);
  setTimeout("drawSquare(iMach,jMach,machSq);",900);
 }
 else {
  drawSquare(iMach,jMach,machSq);
 }
 if (winningPos(iMach,jMach,machSq)==winningMove) setTimeout("alert('I won!')",900);
 else setTimeout("myTurn=false;",950);
}

function hasNeighbors(i,j) {
 if (j>0 && f[i][j-1]!=0) return 1;
 if (j+1<boardSize && f[i][j+1]!=0) return 1; 
 if (i>0) {
  if (f[i-1][j]!=0) return 1;
  if (j>0 && f[i-1][j-1]!=0) return 1;
  if (j+1<boardSize && f[i-1][j+1]!=0) return 1;
 }
 if (i+1<boardSize) {
  if (f[i+1][j]!=0) return 1;
  if (j>0 && f[i+1][j-1]!=0) return 1;
  if (j+1<boardSize && f[i+1][j+1]!=0) return 1;
 }
 return 0;
}

w=new Array(0,20,17,15.4,14,10);
nPos=new Array();
dirA=new Array();


function winningPos(i,j,mySq) {
 test3=0;

 L=1;
 m=1; while (j+m<boardSize  && f[i][j+m]==mySq) {L++; m++} m1=m;
 m=1; while (j-m>=0 && f[i][j-m]==mySq) {L++; m++} m2=m;   
 if (L>4) { return winningMove; }
 side1=(j+m1<boardSize && f[i][j+m1]==0);
 side2=(j-m2>=0 && f[i][j-m2]==0);

 if (L==4 && (side1 || side2)) test3++;
 if (side1 && side2) {
  if (L==4) return openFour;
  if (L==3) test3++;
 }

 L=1;
 m=1; while (i+m<boardSize  && f[i+m][j]==mySq) {L++; m++} m1=m;
 m=1; while (i-m>=0 && f[i-m][j]==mySq) {L++; m++} m2=m;   
 if (L>4) { return winningMove; }
 side1=(i+m1<boardSize && f[i+m1][j]==0);
 side2=(i-m2>=0 && f[i-m2][j]==0);
 if (L==4 && (side1 || side2)) test3++;
 if (side1 && side2) {
  if (L==4) return openFour;
  if (L==3) test3++;
 }
 if (test3==2) return twoThrees;

 L=1;
 m=1; while (i+m<boardSize && j+m<boardSize && f[i+m][j+m]==mySq) {L++; m++} m1=m;
 m=1; while (i-m>=0 && j-m>=0 && f[i-m][j-m]==mySq) {L++; m++} m2=m;   
 if (L>4) { return winningMove; }
 side1=(i+m1<boardSize && j+m1<boardSize && f[i+m1][j+m1]==0);
 side2=(i-m2>=0 && j-m2>=0 && f[i-m2][j-m2]==0);
 if (L==4 && (side1 || side2)) test3++;
 if (side1 && side2) {
  if (L==4) return openFour;
  if (L==3) test3++;
 }
 if (test3==2) return twoThrees;

 L=1;
 m=1; while (i+m<boardSize  && j-m>=0 && f[i+m][j-m]==mySq) {L++; m++} m1=m;
 m=1; while (i-m>=0 && j+m<boardSize && f[i-m][j+m]==mySq) {L++; m++} m2=m; 
 if (L>4) { return winningMove; }
 side1=(i+m1<boardSize && j-m1>=0 && f[i+m1][j-m1]==0);
 side2=(i-m2>=0 && j+m2<boardSize && f[i-m2][j+m2]==0);
 if (L==4 && (side1 || side2)) test3++;
 if (side1 && side2) {
  if (L==4) return openFour;
  if (L==3) test3++;
 }
 if (test3==2) return twoThrees;
 return -1;
}

function evaluatePos(a,mySq) {
 maxA=-1;
 for (i=0;i<boardSize;i++) {
  for (j=0;j<boardSize;j++) {

   // Compute "value" a[i][j] of the (i,j) move

   if (f[i][j]!=0) {a[i][j]=-1; continue;}  
   if (hasNeighbors(i,j)==0) {a[i][j]=-1; continue;}
   wp=winningPos(i,j,mySq);
   if (wp==winningMove) {a[i][j]=winningMove; return winningMove;}
   if (wp>=twoThrees)   {a[i][j]=wp; if (maxA<wp) maxA=wp; continue;}

   minM=i-4; if (minM<0) minM=0;
   minN=j-4; if (minN<0) minN=0;
   maxM=i+5; if (maxM>boardSize) maxM=boardSize;
   maxN=j+5; if (maxN>boardSize) maxN=boardSize;

   nPos[1]=1; A1=0;
   m=1; while (j+m<maxN  && f[i][j+m]!=-mySq) {nPos[1]++; A1+=w[m]*f[i][j+m]; m++}
   if (j+m>=boardSize || f[i][j+m]==-mySq) A1-=(f[i][j+m-1]==mySq)?(w[5]*mySq):0;
   m=1; while (j-m>=minN && f[i][j-m]!=-mySq) {nPos[1]++; A1+=w[m]*f[i][j-m]; m++}   
   if (j-m<0 || f[i][j-m]==-mySq) A1-=(f[i][j-m+1]==mySq)?(w[5]*mySq):0;

   nPos[2]=1; A2=0;
   m=1; while (i+m<maxM  && f[i+m][j]!=-mySq) {nPos[2]++; A2+=w[m]*f[i+m][j]; m++}
   if (i+m>=boardSize || f[i+m][j]==-mySq) A2-=(f[i+m-1][j]==mySq)?(w[5]*mySq):0;
   m=1; while (i-m>=minM && f[i-m][j]!=-mySq) {nPos[2]++; A2+=w[m]*f[i-m][j]; m++}   
   if (i-m<0 || f[i-m][j]==-mySq) A2-=(f[i-m+1][j]==mySq)?(w[5]*mySq):0;

   nPos[3]=1; A3=0;
   m=1; while (i+m<maxM  && j+m<maxN  && f[i+m][j+m]!=-mySq) {nPos[3]++; A3+=w[m]*f[i+m][j+m]; m++}
   if (i+m>=boardSize || j+m>=boardSize || f[i+m][j+m]==-mySq) A3-=(f[i+m-1][j+m-1]==mySq)?(w[5]*mySq):0;
   m=1; while (i-m>=minM && j-m>=minN && f[i-m][j-m]!=-mySq) {nPos[3]++; A3+=w[m]*f[i-m][j-m]; m++}   
   if (i-m<0 || j-m<0 || f[i-m][j-m]==-mySq) A3-=(f[i-m+1][j-m+1]==mySq)?(w[5]*mySq):0;

   nPos[4]=1; A4=0;
   m=1; while (i+m<maxM  && j-m>=minN && f[i+m][j-m]!=-mySq) {nPos[4]++; A4+=w[m]*f[i+m][j-m]; m++;}
   if (i+m>=boardSize || j-m<0 || f[i+m][j-m]==-mySq) A4-=(f[i+m-1][j-m+1]==mySq)?(w[5]*mySq):0;
   m=1; while (i-m>=minM && j+m<maxN  && f[i-m][j+m]!=-mySq) {nPos[4]++; A4+=w[m]*f[i-m][j+m]; m++;} 
   if (i-m<0 || j+m>=boardSize || f[i-m][j+m]==-mySq) A4-=(f[i-m+1][j+m-1]==mySq)?(w[5]*mySq):0;

   dirA[1] = (nPos[1]>4) ? A1*A1 : 0;
   dirA[2] = (nPos[2]>4) ? A2*A2 : 0;
   dirA[3] = (nPos[3]>4) ? A3*A3 : 0;
   dirA[4] = (nPos[4]>4) ? A4*A4 : 0;

   A1=0; A2=0;
   for (k=1;k<5;k++) {
    if (dirA[k]>=A1) {A2=A1; A1=dirA[k]}
   }
   thisA=A1+A2;

   a[i][j]=thisA;
   if (thisA>maxA) {
    maxA=thisA;
   }
  }
 }
 return maxA;
}

function drawSquare(par1,par2,par3) {
 if (document.images) {
  eval('document.s'+par1+'_'+par2+'.src="s'+par3+'.gif"');
 }
 else setTimeout("writeBoard()",50);
}


buf='';

function writeBoard () {
 
 var board = document.getElementById("board");
 
 var a = document.createElement("a");
 var pre = document.createElement("pre");
 a.setAttribute("name","s");
 board.appendChild(a);
 
 for (i=0;i<boardSize;i++) {
  for (j=0;j<boardSize;j++) {
   
   var node = document.createElement("a");
   node.setAttribute("href","#s");
   node.setAttribute("onClick",'clk('+i+','+j+');if(ie4)this.blur();return false;');
   var img = document.createElement("img");
   img.setAttribute("id",'s'+i+'_'+j);
   img.setAttribute("name",'s'+i+'_'+j);
   img.setAttribute("src",'s'+f[i][j]+'.gif');
   img.setAttribute("width",'16');
   img.setAttribute("height",'16');
   img.setAttribute("border",'0');
   
   node.appendChild(img);
   pre.appendChild(node);
  }
  
  var ggif = document.createElement("img");
  ggif.setAttribute("src","g.gif");
  ggif.setAttribute("width","1");
  ggif.setAttribute("height","16");
  pre.appendChild(ggif);
  var br = document.createElement("br");
  pre.appendChild(br);
  
 }
 
 var ggif = document.createElement("img");
 ggif.setAttribute("src","g.gif");
 ggif.setAttribute("width",boardSize*16+1);
 ggif.setAttribute("height","1");
 pre.appendChild(ggif);
 board.appendChild(pre);
 
}

function resetGame() {
 
 for (i=0;i<20;i++) {
  for (j=0;j<20;j++) {
   f[i][j]=0;
  }
 }
 if (document.images) {
  if (!document.s9_9) return;
  for (i=0;i<boardSize;i++) {
   for (j=0;j<boardSize;j++) {
    eval('document.s'+i+'_'+j+'.src=bImg.src');  
   }
  }
 }
 else writeBoard();
 myTurn=false;
}

function init() {
 writeBoard();
 resetGame();
}
2. Tạo file html với nội dung như sau:

Code: Select all

<html>
<head>
	<title>Caro chess</title>
</head>
<body onLoad="init()">

	<div id="board"></div>
	
	<script src="caro.js"></script>
</body>

</html>
3. Chuẩn bị các file gif dùng hiển thị các quân cờ O và X ... như ở file attach nữa nhé.

Vậy là xong, với nhiêu đây code thì có thể chơi được tương đối ổn, nếu bạn không chơi giỏi cờ caro thì có thể thua nó đấy :D
Demo bạn có thể check tạm ở đây: https://nhucvl.com/game/carobasic

Nếu bạn có khả năng cải tiến code này thì chia sẻ bằng cách rep lại vào đây nhá :D
Attachments
sb-1.gif
sb-1.gif (263 Bytes) Viewed 566 times
s-1.gif
s-1.gif (140 Bytes) Viewed 566 times
s1.gif
s1.gif (133 Bytes) Viewed 566 times
s0.gif
s0.gif (108 Bytes) Viewed 566 times
g.gif
g.gif (77 Bytes) Viewed 566 times

Post Reply