一、 结束界面的搭建
1、界面结构
显示效果:
关键代码
let resultNode = cc.find("Canvas/result");
// 获取title和content两个节点
let titleNode = resultNode.getChildByName("title");
let contentNode = resultNode.getChildByName("content");
// 展示分数
titleNode.getComponent(cc.Label).string = "最终结果 " ; //+ this.scoreNum;
// 获取组件
let contentLabel = contentNode.getComponent(cc.Label);
resultNode.active=true;
cc.director.pause();
二、五子棋AI算法
1、算法思想
主要参考“评分表法”(或者称“五元组法”)实现五子棋的人机对战。
对战问题:
如何选择下棋位置是关键,例如当玩家下了连续一条线上的3个黑棋,而机器下的白棋没有3个连在一起,这个时候机器需要想办法堵住玩家的黑棋,不能让玩家有4个连续的黑棋且两头没有堵住,否则机器必输。类似这样的攻防也是需要考虑在内的。因此采用“评分表法”来确定棋盘中哪个位置是最合适的。
1)五元组
那么一个“五元组”指的是连续的5个下棋位置作为一组,
2)“评分表法”
评分表法”就是为棋盘中每一个“五元组”进行评分,并将分值赋给该“五元组”中的5个下棋位置。显然,棋盘中的某个下棋位置不可能只在一个“五元组”中,因此该下棋位置的分数需要它所在的“五元组”分数之和。
3)“评分表法”具体实现
下面展示一些 内联代码片
。
constructor(private pieceMap: Piece[][]) {
//添加五元数组
//横向
// 横向
for (let y = 0; y < 15; y++) {
for (let x = 0; x < 11; x++) {
this.fiveGroup.push([
cc.v2(x, y),
cc.v2(x + 1, y),
cc.v2(x + 2, y),
cc.v2(x + 3, y),
cc.v2(x + 4, y)]);
}
}
//纵向
for (let x = 0; x < 15; x++) {
for (let y = 0; y < 11; y++) {
this.fiveGroup.push([
cc.v2(x, y),
cc.v2(x, y + 1),
cc.v2(x, y + 2),
cc.v2(x, y + 3),
cc.v2(x, y + 4)]);
}
}
//右上斜向
for (let b = -10; b <= 10; b++) {
for (let x = 0; x < 11; x++) {
if (b + x < 0 || b + x > 10) {
continue;
} else {
this.fiveGroup.push([
cc.v2(x, b + x),
cc.v2(x + 1, b + x + 1),
cc.v2(x + 2, b + x + 2),
cc.v2(x + 3, b + x + 3),
cc.v2(x + 4, b + x + 4)]);
}
}
}
//右下斜向
for (let b = 4; b <= 24; b++) {
for (let y = 0; y < 11; y++) {
if (b - y < 4 || b - y > 14) {
continue;
} else {
this.fiveGroup.push([
cc.v2(b - y, y),
cc.v2(b - y - 1, y + 1),
cc.v2(b - y - 2, y + 2),
cc.v2(b - y - 3, y + 3),
cc.v2(b - y - 4, y + 4)]);
}
}
}
}
getNextPoint():cc.Vec2 {
//评分
for (let i = 0; i < this.fiveGroup.length; i++) {
let b = 0;//五元组里黑棋的个数
let w = 0;//五元组里白棋的个数
for (let j = 0; j < 5; j++) {
let group = this.fiveGroup[i][j];
if (this.pieceMap[group.y][group.x].color === PieceColor.black) {
b++;
}
else if (this.pieceMap[group.y][group.x].color === PieceColor.white) {
w++;
}
}
if (b + w == 0) {
this.fiveGroupScore[i] = 7;
} else if (b > 0 && w > 0) {
this.fiveGroupScore[i] = 0;
} else if (b == 0 && w == 1) {
this.fiveGroupScore[i] = 35;
} else if (b == 0 && w == 2) {
this.fiveGroupScore[i] = 800;
} else if (b == 0 && w == 3) {
this.fiveGroupScore[i] = 15000;
} else if (b == 0 && w == 4) {
this.fiveGroupScore[i] = 800000;
} else if (w == 0 && b == 1) {
this.fiveGroupScore[i] = 15;
} else if (w == 0 && b == 2) {
this.fiveGroupScore[i] = 400;
} else if (w == 0 && b == 3) {
this.fiveGroupScore[i] = 1800;
} else if (w == 0 && b == 4) {
this.fiveGroupScore[i] = 100000;
}
}
//找最高分的五元组
let hScore = 0;
let mPosition = 0;
for (let i = 0; i < this.fiveGroupScore.length; i++) {
if (this.fiveGroupScore[i] > hScore) {
hScore = this.fiveGroupScore[i];
mPosition = i;
}
}
//在最高分的五元组里找到最优下子位置
let flag1 = false;//无子
let flag2 = false;//有子
let nPosition = 0;
for (let i = 0; i < 5; i++) {
let board=this.fiveGroup[mPosition][i]
if (!flag1 && this.pieceMap[board.y][board.x].color === PieceColor.none) {
nPosition = i;
}
if (!flag2 && this.pieceMap[board.y][board.x].color !== PieceColor.none) {
flag1 = true;
flag2 = true;
}
if (flag2 && this.pieceMap[board.y][board.x].color === PieceColor.none) {
nPosition = i;
break;
}
}
//在最最优位置下子
return this.fiveGroup[mPosition][nPosition];
}
}