HTML5 游戏开发实战 | 五子棋
01、五子棋游戏设计的思路
02、关键技术
function judge(x,y, chess)
//判断该局的输赢
//保存当前共有多少相同的黑色棋子相连var count1 =0;var count2 = 0;var count3 = 0;var count4 = 0://左右判断,横向的判断//判断横向是否有 5个棋子相连,特点是纵坐标相同,即 chessData[x][y]中y值是相同的//向左统计for(var i=x;i>=0;i--)[if(chessData[i][y] != chess){
break;
count1++;
for(var i=x+1;<15; i++)!if(chessData[il[y] != chess) {
break;
//向右统计
count1++
//上下判断,纵向的判断
for(var i=y;i>=0;i--)(if(chessData[x][i] != chess)break;
count2++;
for(var i=y+1;i<15;i++) /if(chessData[x][i] != chess)[break;
c懵ou对nt2++;
//左上右下判断for(var i=x,j=y;i>=0,j>=0;i--,j-- ){if(chessDatalilli] != chess)
break;count3++;
for(var i=x+1,j=y+1; < 15,j< 15; i++,j++) (if(chessData[i][j] != chess){
break;
count3++:
//右上左下判断
for(var i=x,j=y;i>=0,j<15;i--,j++){
if(chessDatalili] != chess)!
break;
count4++;
for(var i=x+1,j=y-1; i< 15,j>=0; i++,j-- ) {
if(chessData[][j] != chess){
break;
count4++;
count3
if(count1>=5count2 >
count4
if(chess == 1)
alert("白棋赢了");
else
alert("黑棋赢了");
isWell= true;//设置该局已经赢了,不可以再下棋
//这些 fillStyle 的值均为,橙色
ctx.fillStyle="orange";
ctx.fillStyle="#FFA500";
ctx.fillStyle="rgb(255,165,0)";
ctx.fillStyle ="rgba(255,165,0,1)";
本游戏中棋盘的背景色即是采用“orange”。
context.fillStyle="orange";
context.fillRect(0,0,640,640);
03、五子棋游戏设计的步骤
/head >
<body onload ="drawRect()">
<div>
< canvas width= "640”id = "canvas"onmousedown = "play(event)" height = "640"> </canvas >
</div>
</body>
</htmI>
"text/javascript">script type =c
var canvas ;
var context;
var isWhite = false;
//设置是否该轮到白棋
var isWell = false;
var img b =new Image();
img b.src="images/w.png";
//设置该局棋盘是否赢了,如果赢了就不能再走了
//白棋图片
var img w =new Image();img w.src ="images/b.png";//这个为棋盘的二维数组,用来保存棋盘信息var chessData = new Arrav(15)://初始化 0 为没有走过的,1 为白棋走的,2 为黑棋走的for(var x=0;x<15; x++)chessData[x]= new Array(15);for (var y=0;y<15; y++)chessData[x][y] = 0;
//黑棋图片
function drawRect()
//页面加载完毕调用函数,页面上绘制五子棋棋盘canvas = document.getElementById("canvas");context = canvas.getContext("2d");
context.fillStyle="orange";
context.fillRect(0,0,640,640):
context.fillStyle="#000000":
//绘制棋盘的线for(var i=0;i<=640;i+=40)[
context.beginPath();
context.moveTo(0,i);
context.lineTo(640,i);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(i,0);
context.lineTo(i,640);
context.closePath();
context.stroke();
function play(e)[
//鼠标单击时发生
//从像素坐标换算成棋盘坐标
//计算鼠标单击的位置,如果单击(65,65)位置,那么就是棋盘(1,1)的位置var x = parseInt((e.clientX - 20)/40);
var y= parseInt((e.clientY - 20)/ 40);
//判断该位置是否被下过了
if(chessData[x][y] != 0)[
alert("你不能在这个位置下棋");
return;
if(isWhite)(
//是否是白棋
isWhite= false;
drawChess(1,x,y);
else(
isWhite = true;
drawChess(2,x,y);
//换下一方走棋//绘制白棋
//换下一方走棋
//绘制黑棋
4. 画棋子函数
drawChess(chess,x,y)函数中参数 chess 为棋(1 为白棋,2 为黑棋),(x,y)为棋盘即数组位置。
function drawChess(chess,x,y )//参数 chess 为棋(1 为白棋,2 为黑棋),,为数组位置
function drawChess(chess,x,y)if(isWell== true)
{
alert("已经结束了,如果想要重新玩,请刷新”);
return;
}
if(x>=0&& x<15 && y>=0&& y<15){
if(chess==1){
context.drawImage(img_w,x * 40+20,y * 40+20);//绘制白棋
chessData[x][y] = 1;
else!context.drawImage(img b,x * 40+20,y * 40+20);//绘制黑棋
chessData[x][y] = 2;
judge(x,Y,chess);
}
}
04、人机五子棋游戏的开发
数组中行数越高,表明该行棋谱中 S 位置越重要,电脑走最重要的位置。
例如,棋谱[N,S,B,B,B ]表示玩家(人)的黑棋(B)已有三子连线了,电脑必须在此附近下棋,其中 S 为需要电脑下子的位置,N 为空位置。棋谱[S,B,B,B,B ]表示玩家(人)的黑棋(B)已有四子连线了。当然棋谱[S,B,B,B,B ]级别高于棋谱[N,S,B,B,B ]。
然后,有了棋谱后就是遍历棋盘的信息是否符合某个棋谱,判断时从级别高的棋谱判断到级别低的棋谱(即从数组中行数最高 Chess.length-1 开始判断)。如果符合某个棋谱,则按棋谱指定的位置存储到(m_nCurRow,m_nCurCol),如果所有棋谱都不符合,则随便找一个空位置。
实现人工智能的算法的 coputer.js 脚本如下:
var KONG = 0;
var BLACK = 2;
var WHITE = 1;
var N= 0;
var B= 2;
var W= 1;
this.x = x;
this.y= y;
//获取电脑下子位置
function GetComputerPos()
//返回Point
return new Point(m nCurCol,m nCurRow):
//电脑根据输入参数 grid(棋盘),计算出落子位置(m_nCurRow,m_nCurCol)//grid 是 Arrayfunction Input(qrid)var rowSel,colSel,nLevel;
var index,nLevel;
var j;
m nCurCol=-1;
m nCurRow = -1;
nLevel= -1;
var bFind;
for(var row =0; row < 15; row ++)
{
//遍历棋盘的所有行
//存储临时的选择位置
//存储临时选择的棋谱级别//是否符合棋谱的标志
for(var col= 0;col < 15; col ++)
(//遍历棋盘的所有列
for(var i= Chess.length- 1;i>= 0;i-- )//遍历所有级别的棋谱//查看从当前棋子开始的横向五个棋子是否符合该级别的棋谱if(col+4<15)rowSel= -1;colSel= -1;bFind =使炽鼓 true;for(j=0;j< 5;j++)
index = grid[col + j][row]if( index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S或 Nif(Chess[i][j]== S){//如果是 S,则保存位置rowSel= row;colSel= col+j;
else if(Chess[i][j] != N)
[//不是 S也不是 n,则不符合这个棋谱,结束循环
bFind = false;
break;
if(index == BLACK && Chess i != B){
//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;break;
if(index == WHITE && Chess il != W)[//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;
break;
if(bFind && i> nLevel)
{
//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高
nLevel= i;
m nCurCol=colSel;
//保存级别
//保存位置
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
//查看从当前棋子开始的纵向五个棋子是否符合该级别的棋谱if(row+4<15)
rowSel= -1;colSel= -1;bFind = true;for(j=0;j<5;j++)index = grid[ col][ row + j];if(index == KONG){
//如果该位置没有棋子,对应的棋谱位置上只能是 S 或Nif(Chess[illil== S){//如果是 S,则保存位置rowSel= row + i;colSel = col;else if(Chess[illil != N)
{
//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false:break;if(index == BLACK)[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环if(Chess[il[i] != B)bFind = false;
break;
if(index == WHITE && Chess[illi] != W){
//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;break;
if(bFind && i> nLevel){
//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高nLevel= i;m nCurCol=colSel;m nCurRow = rowSel;
//保存级别
//保存位置
break;
//遍历其他级别的棋谱
}
}
//查看从当前棋子开始的斜 45°向下的五个棋子是否符合该级别的棋谱if(col-4>=0&& rw+4<15)
rowSel= -1;colSel = -1;bFind = true;for(j=0;j< 5;j++)
index = grid[col - j][ row + jl;if(index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S 或 Nif(Chess[i][j]== S)[//如果是 S,则保存位置rowSel = row + j;colSel= col-j;else if(Chess[il[i] != N){//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false;break;
if(index == BLACK && Chess[i][j] != B)
[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;
break;
if(index == WHITE && Chess != W){
//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;
break;
if(bFind && i> nLevel){
//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高
//保存级别
nLevel =i;
//保存位置m nCurCol= colSel;
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
//斜 135度的五个棋子
if(col+4<15 && row+4<15)
{
//查看从当前棋子开始的斜 135向下的五个棋子是否符合该级别棋谱rowSel= -1;
colSel= -1;bFind = true;for(j=0;j<5;j++)
index = grid[col + j][row + jl;if(index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S或Nif(Chess[il[jl== S){//如果是 S,则保存位置rowSel = row + j;
colSel= col+j;
else if(Chess[illi != N){
//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false;
break;
if(index == BLACK && Chessil] != B)[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;
break;if(index == WHITE && Chess[ill] = W)[//如果是白色棋,对应的棋谱位置上应是 w,否则结束循环bFind = false;
break;if(bFind && i> nLevel)
[//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高nLevel=i;m nCurCol= colSel;//保存位置
//保存级别
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
if(m nCurRow != -1)
[//如果选择了一个最佳位置
grid[m nCurCol][m nCurRow] = WHITE;return true;
//如果所有棋谱都不符合,则随便找一个空位置while(true
var col;
var row;
col = int(Math.random()*15);row = int(Math.random()*15)if(grid[ col][row]== KONG)
//随便找一个位置
grid[col][row]= WHITE;
m nCurCol = col;
m nCurRow = row;return true;
return false;
在游戏页面 five.html 中,由于使用上面 coputer.js 脚本,所以需要在中添加:
由于只有玩家(黑棋)需要单击棋盘落子,不再轮流下子,所以对单击事件响应函数 play(e)进行修改,玩家(黑棋)落子后,判断此时玩家(黑棋)是否赢了。如果赢了则游戏结束,否则直接电脑(白方)自动计算落子,电脑(白方)自动落子是调用 Input(chessData)函数实现计算白子位置,GetComputerPos()函数获取电脑落子位置 P,获取电脑落子位置后,在位置 P 显示白子并判断此时电脑是否赢了。
function play(e){
var x = parseInt((e.clientX- 20) / 40);var y= parseInt((e.clientY- 20) / 40);if(chessDatalx][y] != 0) [
//鼠标单击时发生
//计算鼠标单击的区城
//判断该位置是否被下过了
alert("你不能在这个位置下棋");
return;
drawChess(2,x,y);//轮到电脑(白方)走Input(chessData);var p = GetComputerPos();drawChess(1,p.x,p.y);
//获取电脑落子位置 P
}
本文实现经典的五子棋游戏的基本功能,并且能够判断输赢,并把系统改进成人机对战版,使得游戏更具挑战性,从而更吸引玩家。
- 点赞
- 收藏
- 关注作者
评论(0)