五子棋游戏源码和核心算法的讲解(简易五子棋web版)
程序员文章站
2022-05-25 14:22:38
...
<style>
*{margin:0;}/*解决浏览器的兼容问题*/
#canvas{background:#f4f4f4;
margin:100px auto auto auto;
display:block;
border:7px solid #3d3d3d;
box-shadow:0 0 30px;
}
body{
background:url(http://img.zcool.cn/community/aaa@qq.com_1l_2o_100sh.jpg);
background-size:cover;;
}
button{
height:40px;
width:100px;
display:block;
margin:45px auto ;
border-radius: 25px;
}
</style>
</head>
<body>
<canvas id="canvas" height="450" width="450"></canvas>
<button id="restart">重新开始</button>
</body>
一、以上是界面的代码
二、js的部分代码
//获得画板
var chess=document.getElementById("canvas");
//获得画笔(上下文)
var context=chess.getContext("2d");
//true为白棋,false为黑棋
var me=false;
//棋盘数组,0代表没有棋子,1代表白棋,2代表黑棋
var chessBorad=[];
for(var i=0;i<15;i++){
chessBorad[i]=[];
for(var j=0;j<15;j++){
chessBorad[i][j]=0;
}
}
//获得按钮
var restart=document.getElementById("restart");
三、以下的代码将棋盘(的线)画出来
//绘画棋盘的方法
function drawChessBorad(){
context.strokeStyle="#4d4d4d";//改变线条的颜色
for(var i=0;i<15;i++){
//棋盘的竖线
context.moveTo(15+i*30,15);//起点
context.lineTo(15+i*30,435);//终点
context.stroke();//连线
//棋盘的横线
context.moveTo(15,15+i*30);//起点
context.lineTo(435,15+i*30);//终点
context.stroke();
}
}
window.onload=function(){
drawChessBorad();
}
四、以下代码是用来绘画棋子的和重启游戏,以及画板的点击事件 //画棋子
function drawChess(i,j,me){//i纵坐标,j横坐标
context.beginPath();
context.arc(15+j*30,i*30+15,13,0,Math.PI*2,false);
context.closePath();
context.stroke();
//设置渐变色 径向渐变
var grd=context.createRadialGradient(15+j*30+2,i*30+15-2,10,15+j*30+2,i*30+15-2,0);
if(me){//白棋
grd.addColorStop(0,"#d1d1d1");
grd.addColorStop(1,"#f9f9f9");
chessBorad[i][j]=1;
}else{//黑棋
grd.addColorStop(0,"#0a0a0a");
grd.addColorStop(1,"#636767");
chessBorad[i][j]=2;
}
context.fillStyle=grd;//设置填充色
context.fill();
}
//画板的鼠标点击事件
chess.onclick=function(e){
var x=e.offsetX;
var y=e.offsetY;
var i=Math.floor(y/30);
var j=Math.floor(x/30);
if(chessBorad[i][j]==0){
drawChess(i,j,me);//画棋子
win(i,j,me);
me=!me;
}
}
//重新游戏
restart.onclick=function(){
clearChess();
}
//清空棋子
function clearChess(){//当canvas的高度或者宽度重新设置时将清空画布
chess.height=chess.height;
drawChessBorad();
}
五、判断游戏是哪方赢了(核心代码)
之前在网上看的大部分代码的算法大都是遍历了整个棋盘,以此来判断是否有哪一方已经达到赢的条件。个人觉得此算法的性能不是特别好。
以下的代码算法思想是:达成赢得条件时,那五个连成一直线的棋子中必然有一个是最后下的。由此获取最后棋子的坐标,向八方分别计算各个方向与其相同颜色的棋子个数。
统计好以上八个方向上(除了最后一个棋子)与最后一个棋子相同颜色的棋子,并且在遇到另一种颜色棋子时就不再进行统计,一个方向上最多统计4个棋子。
最后判断以下四个方向是否存在五个相同颜色的棋子(颜色为最后一个棋子的颜色),存在则达到了赢的条件,游戏结束。
代码的实现:
//判断赢的方法
function win(i,j,me){//i纵坐标,j横坐标
var count=[0,0,0,0,0,0,0,0];
var state=[1,1,1,1,1,1,1,1];//遇到相同颜色值为1
var color=1;
if(me){color=1;}else{color=2;}
for(var step=1;step<5;step++){
if(state[0]==1&&i-step>=0&&j-step>=0){
if(chessBorad[i-step][j-step]==color){count[0]++;}else{state[0]=2;}//遇到相异的颜色或者没有棋子
}
if(state[1]==1&&i-step>=0){
if(chessBorad[i-step][j]==color){count[1]++;}else{state[1]=2;}
}
if(state[2]==1&&i-step>=0&&j+step<15){
if(chessBorad[i-step][j+step]==color){count[2]++;}else{state[2]=2;}
}
if(state[3]==1&&j+step<15){
if(chessBorad[i][j+step]==color){count[3]++;}else{state[3]=2;}
}
if(state[4]==1&&i+step<15&&j+step<15){
if(chessBorad[i+step][j+step]==color){count[4]++;}else{state[4]=2;}
}
if(state[5]==1&&i+step<15){
if(chessBorad[i+step][j]==color){count[5]++;}else{state[5]=2;}
}
if(state[6]==1&&i+step<15&&j-step>=0){
if(chessBorad[i+step][j-step]==color){count[6]++;}else{state[6]=2;}
}
if(state[7]==1&&j-step>=0){
if(chessBorad[i][j-step]==color){count[7]++;}else{state[7]=2;}
}
}
if((count[0]+count[4]+1)>=5||(count[1]+count[5]+1)>=5||(count[2]+count[6]+1)>=5||(count[3]+count[7]+1)>=5){
if(me){
alert("白棋赢了");
}else{
alert("黑棋赢了");
}
}
}
下一篇: 人机五子棋实现原理