五子棋游戏源码和核心算法的讲解(简易五子棋web版)

 <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/018d4e554967920000019ae9df1533.jpg@900w_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("黑棋赢了");
				}
			}
	}

猜你喜欢

转载自blog.csdn.net/s_p_y_s/article/details/79888157