因为之前用c#的winform中的gdi+,java图形包做过五子棋,所以做这个逻辑思路也就驾轻就熟,然而最近想温故html5的canvas绘图功能(公司一般不用这些),所以做了个五子棋,当然没参考之前的客户端代码,只用使用之前计算输赢判断算法和电脑AI(网络借取)的算法,当然现在html5做的五子棋百度一下非常多,但是自己实现一边总归是好事情,好了废话不多说了进入正题。^_^
界面功能介绍与后续可增加功能
目前界面功能:
主界面包含
1:人人、人机对战选项 2:棋子外观选择 3:棋盘背景选择 4:棋盘线条颜色选择
游戏界面包含
1:玩家名称 2:玩家棋子 3:当前由谁下棋背景定位 4:玩家比分 5:功能菜单区域(重新开始和无限悔棋) 6:棋盘区域 7.胜利后连环棋子连接 8.最后下棋位置闪烁显示 9.光标定位
游戏结束界面
1:胜利背景图 2:胜利玩家姓名 3:继续下一把按钮
可增加功能
1.返回主界面 2.保存棋局和相关数据 3.读取棋局和相关数据 4.交换角色 5.网络对战(2台机器)6.双方思考总时间记录
界面截图赏析(没花时间美化,比较丑)


整体设计和主代码介绍
整体设计
下棋流程:玩家or电脑AI下棋 ---> 绘制棋子 ---> 设定棋子二维坐标值 ----> logic(逻辑判断) ----> (玩家)一方五子连环 ---> 获胜界面
↑ |
| ↓
<--------------------------------------------------------------------------------------------没有五子
悔棋流程(人人对战):一方玩家悔棋 ----> 弹出下棋记录堆栈并设定为它是最后一枚棋 ---> 清除最后一枚棋子图像 ---> 清除棋子二维坐标值---> 重新定位显示最后下棋位置并闪烁
悔棋流程(人机对战):玩方悔棋 ----> 弹出下棋记录堆栈2次,设定上一次电脑为最后一枚棋 ---> 清除弹出的2次记录图像 ---> 清除棋子2个棋子二维坐标值---> 重新定位显示最后下棋位置并闪烁
主代码介绍
主代码分为二块: 1.界面逻辑块 2.游戏主体块 (界面与游戏代码分离,逻辑清晰,分工明确)
模拟事件通知:游戏主体逻辑块,每次结果都会通知到界面层来进行交互(类似于c#或者java的委托或事件)
界面逻辑代码
<script type="text/javascript">
var gb = null;
var infoboj = document.getElementsByClassName("info")[0];
var pl1obj = document.getElementById("pl1");
var pl2obj = document.getElementById("pl2");
var plname1obj = document.getElementById("plname1");
var plname2obj = document.getElementById("plname2");
var chesstypeobj = document.getElementsByName("chesstype");
var chesscolorobj = document.getElementsByName("chesscolor");
var chessbgObj = document.getElementsByName("chessbg");
var winerpnl = document.getElementById("winer");
document.getElementById("startgame").addEventListener("click", function() {
function initParams() {
var chessTypeValue = 1;
if (chesstypeobj.length > 0) {
for (var i = 0; i < chesstypeobj.length; i++) {
if (chesstypeobj[i].checked) {
chessTypeValue = chesstypeobj[i].value;
break;
}
}
}
var linevalue = "";
if (chesscolorobj.length > 0) {
for (var i = 0; i < chesscolorobj.length; i++) {
if (chesscolorobj[i].checked) {
linevalue = chesscolorobj[i].value;
break;
}
}
}
var bcorimgvalue = "";
if (chessbgObj.length > 0) {
for (var i = 0; i < chessbgObj.length; i++) {
if (chessbgObj[i].checked) {
bcorimgvalue = chessbgObj[i].value;
break;
}
}
}
return {
lineColor: linevalue,
chessType: chessTypeValue, //1 色彩棋子 2 仿真棋子
playAName: plname1Input.value,
playBName: plname2Input.value,
backColorORImg: bcorimgvalue,
playAImg: "http://sandbox.runjs.cn/uploads/rs/62/nbqodq5i/playA.png",
playBImg: "http://sandbox.runjs.cn/uploads/rs/62/nbqodq5i/playB.png",
playerBIsComputer:openComputer.checked
};
}
document.getElementById("cc").style.display = "block";
gb = new gobang(initParams());
/**
* 设置一些界面信息
* @param {Object} opt
*/
gb.info = function(opt) {
infoboj.style.visibility = "visible";
document.getElementsByClassName("startpnl")[0].style.visibility = "hidden";
plname1obj.innerHTML = opt.playAName;
plname2obj.innerHTML = opt.playBName;
if (opt.chessType == 1) {
var span1 = document.createElement("span");
pl1obj.insertBefore(span1, plname1obj);
var span2 = document.createElement("span");
pl2obj.insertBefore(span2, plname2obj);
} else {
var img1 = document.createElement("img");
img1.src = opt.playAImg;
pl1obj.insertBefore(img1, plname1obj);
var img2 = document.createElement("img");
img2.src = opt.playBImg;
pl2obj.insertBefore(img2, plname2obj);
}
}
/**
* 每次下棋后触发事件
* @param {Object} c2d
*/
gb.operate = function(opt, c2d) {
if (!c2d.winer || c2d.winer <= 0) {
pl1obj.removeAttribute("class", "curr");
pl2obj.removeAttribute("class", "curr");
if (c2d.player == 1) {
pl2obj.setAttribute

