前言:说在前面的画
可能,一进来最关心的就是,实现的到底是个啥样,那就来一张动图呗,先声明一下,关于电脑的落子算法,本文只是简单的实现了一下(在玩家周围一格随机获取位置),如果懂机器学习可以引入机器学习的相关算法,来获取电脑应该下载哪(位置)

看过我前几篇关于canvas的相关介绍和用法,你会发现,其实绘制棋盘。在指定的位置绘制棋子都是一件容易的事情(在指定位置绘制棋子,关键是:像素位置和坐标之间的相互转换)
如果上面的程序没有太大问题的话,那么接下来,就要考虑在什么时候绘制玩家棋子,可能,你已经想到了,就是cnavas.click()事件。在这个事件里获取点击的位置然后转换为,棋盘里面的坐标。当然,玩家也不能一直不断的下,必须是你下一下,我下一下的模式。如何实现?我是这样实现的,定义一个类属性this.isMyTurn当这个值为true的时候,就轮到玩家落子,玩家一落完子,就将其值设置为false。然后,就是电脑落子,电脑落子完成后,设置this.isMyTurn为true允许玩家落子。(当this.isMyTurn为false的时候,canvas.click()在获取了坐标后不做任何事情,这里的事情指的是:玩家和电脑的落子和胜负判断)。
下面最关键的部分来了:如何判断胜负
给一个思路:就是遍历棋盘,判断棋盘中的每一个坐标的上下/左右/左对角线/右对角线是否是五个棋子直连。当然这个思路问题不大,但是可以不这样做,只是判断 当前落子的位置的四个方向。因为你前面的棋子肯定不会构成胜利的判断,只有当前下的棋子才有可能。
第一部分:核心类Gobang
属性:
this.box = box;// 存放五子棋的容器this.canvas = null;// 画布this.ctx = null;this.size = 600;// 棋盘大小this.cellNum = 20;// 单行棋格数量this.padding = this.size/this.cellNum;// padding值this.cellSize = (this.size-this.padding*2)/this.cellNum;// 棋格大小this.pieceSize = this.cellSize*3/4;// 棋子大小this.color = ["black", "#aaa"];// 棋子颜色this.myPieceType = null;// 玩家棋子类型this.aiPieceType = null;// 电脑棋子类型this.myPieces = [];// 玩家累计棋子this.aiPieces = [];// 电脑累计棋子this.isMyTurn = true;// 先手this.curPos = [this.cellNum/2-1, this.cellNum/2-1];// 当前点击位置this.timeId = null;// 定时器id
方法:
init// 初始化方法,获取canvas设置宽高,获取ctxcreateChessboard// 创建背景棋盘drawPiece// 画一个棋子clearPiece// 清除棋子registClick// 注册鼠标点击事件,主要的逻辑函数isIn// 判断否在所下的棋子里面isInAll// 判断是否在所有下的棋子里面isFull// 是否下满aiPutPiece// 电脑落子,只是简单的实现了,获取玩家落子位子周围一格的随机位置putPiece// 实现下棋的函数isWin// 胜利判断,个人人为比较男一点点的算法run// 运行,类的入口函数,里面调用了,·init·/createChessBoard/registClick方法
第二部分:源代码
Gobang.js
/** 五子棋 **/
function Gobang(box){
this.box = box; // 存放五子棋的容器
this.canvas = null; // 画布
this.ctx = null;
this.size = 600; // 棋盘大小
this.cellNum = 20; // 单行棋格数量
this.padding = this.size/this.cellNum; // padding值
this.cellSize = (this.size-this.padding*2)/this.cellNum; // 棋格大小
this.pieceSize = this.cellSize*3/4; // 棋子大小
this.color = ["black", "#aaa"]; // 棋子颜色
this.myPieceType = null; // 玩家棋子类型
this.aiPieceType = null; // 电脑棋子类型
this.myPieces = []; // 玩家累计棋子
this.aiPieces = []; // 电脑累计棋子
this.isMyTurn = true; // 先手
this.curPos = [this.cellNum/2-1, this.cellNum/2-1]; // 当前点击位置
this.timeId = null; // 定时器id
// 初始化方法
this.init = function(){
// 创建canvas
this.canvas = document.createElement("canvas");
// 设置宽高
this.canvas.width = this.canvas.height = this.size;
// 加入到容器中
this.box.appendChild(this.canvas);
// 获取ctx
this.ctx = this.canvas.getContext("2d");
};
// 创建背景棋盘
this.createChessboard = function(){
// ----------- 边框 -----------
this.ctx.lineWidth = 10;
this.ctx.lineJoin = "round";
this.ctx.strokeRect(0, 0, this.size, this.size);
// ----------- 创建棋盘 -----------
this.ctx.lineWidth = 1;
for (var i = 0; i <= this.cellNum; i++) {
// 画横线
this.ctx.beginPath();
this.ctx.moveTo(this.padding, this.padding+i*this.cellSize);
this.ctx

最低0.47元/天 解锁文章
660





