要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思。

当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃的,就再随机走一个棋子(要想让电脑成为下棋高手就不能随机下棋,要考虑下棋后会不会再被对方吃掉等等,这里只简单做随机下子了)。

完整《五子飞》游戏人机对战:http://www.lyout.com/projects/fiveflychess/FiveflyChess8.htm

// 查找是否有可挑的棋子
for (i = 0; i < this.lines.length; i++) {
for (j = 0; j < this.lines[i].length; j++) {
if (this.chesses[this.lines[i][j]].player == p1 && j < this.lines[i].length - 2) {
if ((j + 2) < this.lines[i].length && this.chesses[this.lines[i][j + 1]].player == Player.None) {
if (this.chesses[this.lines[i][j + 2]].player == p1) {

找到可以挑的两个棋子后,还要判断这条线上不能有其他的棋子:

isfind = true;
for (k = j + 3; k < this.lines[i].length; k++) {
if (this.chesses[this.lines[i][k]].player != Player.None) {
isfind = false;
break;
}
}

确定这条线上只有对方两个棋子并且能被挑之后,再查找电脑方有没有可以去挑这两个棋子的棋子:

var result;
for (k = 0; k < this.lines.length; k++) {
pos = $.inArray(this.lines[i][j + 1], this.lines[k]);
if (pos != -1) {
for (n = pos - 1; n >= 0; n--) {
p2 = this.chesses[this.lines[k][n]].player;
if (p2 == Player.None) continue;
if (p2 == p1) break;
// 被挑的棋子1,被挑的棋子2,挑棋子的位置,用来挑的棋子
result = [this.lines[i][j], this.lines[i][j + 2], this.lines[i][j + 1], this.lines[k][n]];
break;
}
for (n = pos + 1; n < this.lines[k].length; n++) {
p2 = this.chesses[this.lines[k][n]].player;
if (p2 == Player.None) continue;
if (p2 == p1) break;
// 被挑的棋子1,被挑的棋子2,挑棋子的位置,用来挑的棋子
result = [this.lines[i][j], this.lines[i][j + 2], this.lines[i][j + 1], this.lines[k][n]];
break;
}
}
}

如果没有找到可挑的棋子,再查找可夹的棋子(夹棋子的时候有左右两方可能用来夹,这里只分析左方):

// 查找是否有可夹的棋子
for (i = 0; i < this.lines.length; i++) {
for (j = 0; j < this.lines[i].length; j++) {
if (this.chesses[this.lines[i][j]].player == p1 && j > 0 && j < (this.lines[i].length - 1)) {// 找到了
if (this.chesses[this.lines[i][j - 1]].player == player) {// 左边是否有对方棋子

找到被夹的后,要判断一下这条线上只能有已方的一个棋子和对方的一个棋子并且挨着:

isfind = true;
// 其他的位置只能是空
for (k = 0; k < j - 1; k++) {
if (this.chesses[this.lines[i][k]].player != Player.None) { isfind = false; break; }
}
if (isfind) {
for (k = j + 1; k < this.lines[i].length; k++) {
if (this.chesses[this.lines[i][k]].player != Player.None) { isfind = false; break; }
}
}

最后再找已方可以用来执行“夹”的棋子:

var result;
for (k = 0; k < this.lines.length; k++) {
pos = $.inArray(this.lines[i][j + 1], this.lines[k]);
if (pos != -1) {
for (n = pos - 1; n >= 0; n--) {
p2 = this.chesses[this.lines[k][n]].player;
if (p2 == Player.None) continue;
if (p2 == p1) break;
// 被夹的棋子,可用来夹的位置,夹棋子的棋子
result = [this.lines[i][j], this.lines[i][j + 1], this.lines[k][n]];
break;
}
for (n = pos + 1; n < this.lines[k].length; n++) {
p2 = this.chesses[this.lines[k][n]].player;
if (p2 == Player.None) continue;
if (p2 == p1) break;
// 被夹的棋子,可用来夹的位置,夹棋子的棋子
result = [this.lines[i][j], this.lines[i][j + 1], this.lines[k][n]];
break;
}
}
}

找了可以被挑或被夹的棋子后,就直接执行 moveChess 函数,然后再判断一下执行完后游戏是否结束就可以了。

如果没有找到合适的棋子,就需要自动下棋。我们暂时做最初级别的,随机下一个棋子:

var i, j, k, index, moved, mover;
var items = [];
// 可以下棋的棋子
for(i=0; i<this.chesses.length; i++){
if(this.chesses[i].player==this.currentPlayer) items.push(i);
}
if(items.length==0) return; k = 0;
moved = 0;
while(k<20){
// 随机得到一个棋子用于移动
var movec = items.length==1?0:Math.floor(Math.random() * ( items.length-1 + 1)); var dirs = [];
for(i=0; i<this.lines.length; i++){
index = $.inArray(items[movec], this.lines[i]);
if(index!=-1) dirs.push(i);
}
// 随机得到一条可移动的路线
var linec = Math.floor(Math.random() * ( dirs.length-1 + 1));
// 移动棋子
index = $.inArray(items[movec], this.lines[dirs[linec]]); mover = 0;
if(index==0||index==(this.lines[dirs[linec]].length-1)){
if(index==0) mover = 1;
}else{// 随机下棋方向
var dirc = Math.floor(Math.random() * ( 1 + 1));
if(dirc==0) mover = 1;
}
if(mover){
if(this.moveChess(this.lines[dirs[linec]][index+1], items[movec])){
this.currentIndex = this.lines[dirs[linec]][index+1];
console.log(this.currentIndex);
moved = 1;
break;
}
}else{
if(this.moveChess(this.lines[dirs[linec]][index-1], items[movec])){
this.currentIndex = this.lines[dirs[linec]][index-1];
console.log(this.currentIndex);
moved = 1;
break;
}
}
k++;
}
if(moved){
if (!this.chessarray) {
var player = this.currentPlayer;
this.currentPlayer = this.getAnotherPlayer(player);
this.changePlayer();
if (this.isGameOver(this.currentPlayer)) { this.winner = player; this.isover = true; }
}
}else{
this.winner = player; this.isover = true;
}

好的,《五子飞》游戏就到此结束了。

代码中都有相关注释了,里沃特就简单跟小伙伴们说下,不清楚的可以留言。要源码的可以直接查看网页源代码。

还有一点点小BUG,游戏结束时也没有提示,要想重新开始游戏,需要刷新页面。

里沃特旨在跟大家分享怎么从写个小游戏入手,代码考虑得不周全,伙伴们互相交流。高手们也请指教下:)

HTML5+JS 《五子飞》游戏实现(一)规则

HTML5+JS 《五子飞》游戏实现(二)路线分析和资源准备

HTML5+JS 《五子飞》游戏实现(三)页面和棋盘棋子

HTML5+JS 《五子飞》游戏实现(四)夹一个和挑一对

HTML5+JS 《五子飞》游戏实现(五)移动棋子

HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择

HTML5+JS 《五子飞》游戏实现(七)游戏试玩

最新文章

  1. 用java开发微信公众号:接收和被动回复普通消息(三)
  2. excel手机号码归属地批量公式查询 vlookup函数
  3. 运维工作中sed常规操作命令梳理
  4. socket设置为非阻塞方式(windows和linux)
  5. 直接引用windows命名空间
  6. CSS样式总结
  7. pcl1.7.2_vs2013_x64工程配置
  8. DotNetBar怎样控制窗口样式
  9. 维吉尼亚密码java代码实现根据密钥长度计算IC值过程
  10. yesno孤立词识别kaldi脚本
  11. apache工作模式总结及网站访问缓慢处理记录
  12. Python 将图片转化为 HTML 页面
  13. asp.net 发送电子邮件本地测试正常,但服务器上异常的解决办法
  14. python输出格式对齐问题
  15. css命名管理混乱?不妨试试BEM
  16. 如何使用 Java 删除 ArrayList 中的重复元素
  17. tabs 标签样式
  18. 题目1457:非常可乐(广度优先遍历BFS)
  19. struts2 的 ServletActionContext 和 actionContext,服务器代码测试, redirect 、dispatcher、chain、redirectAction
  20. 修改Linux SSH连接端口和禁用IP,安装DDoS deflate

热门文章

  1. SharePoint2010新特性:InfoPath定义创建列表的界面
  2. SQL Server调优系列基础篇(子查询运算总结)
  3. 烂泥:nginx同时支持asp.net与php
  4. 002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)
  5. java 重载、重写、构造函数详解
  6. 微信小程序开发初体验--教你开发小程序
  7. Java修饰符public,private,protected及默认的区别
  8. PHP加载另一个文件类的方法
  9. code blocks 如何实现一键代码格式化
  10. 《ASP.NET MVC 5 高级编程(第5版)》