五子棋


js 基础

js 数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var a = [];
for(var i = 0; i < 10;i++){
a[i] = [];
}
//定义赢得胜利种类
//种情况,横向,纵向,左斜,右斜
wins =[
/* - */
[[-1,0],[1,0]],
/* | */
[[0,-1],[0,1]],
/* / */
[[-1,1],[1,-1]],
/* \ */
[[-1,-1],[1,1]],
];

JavaScript 对象
对象由花括号分隔。在括号内部,对象的属性以名称和值对的形式 (name : value) 来定义。属性由逗号分隔:

1
var person={firstname:"Bill", lastname:"Gates", id:5566};

上面例子中的对象 (person) 有三个属性:firstname、lastname 以及 id。

空格和折行无关紧要。声明可横跨多行:

1
2
3
4
5
var person={
firstname : "Bill",
lastname : "Gates",
id : 5566
};

1
2
3
4
var Cache = {
vct: {},
vcf: {}
}

界面部分

利用 js 完成前端布局。

界面代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>五子棋</title>
<style type="text/css">
canvas {
background: #fff;
margin: 100px auto;
display: block;
/*<!-- 0px: 水平方向0px:垂直方向;10px: 模糊度-->*/
box-shadow: 0px 0px 10px #000;
}
</style>
<link href="./bootstrap-4.1.3-dist/css/bootstrap.min.css" rel="stylesheet">

</head>
<body>
<canvas width="450" height="450" id = "canvas1" > </canvas>
<!-- <button type="button" class="btn btn-danger">Restart</button> -->

<script type="text/javascript">

//获取画板
var chess = document.getElementById("canvas1");

//获取上下文权限
var ctx = chess.getContext("2d");
//设置线条颜色
ctx.strokeStyle = "#b3b3b3";

//绘制棋盘
var drawChessBoard = function( ){
for(var i = 0;i<15;i++){
//画竖线
ctx.moveTo(15+i*30,15);
ctx.lineTo(15+i*30,435);
ctx.stroke();
//画横线
ctx.moveTo(15,15+i*30);
ctx.lineTo(435,15+i*30);
ctx.stroke();
}
}

//保存每个点的状态
//0表示没有棋子
//1表示黑棋
//2表示白棋
var aleadyin = [];
for(var i = 0;i<15;i++){
aleadyin [i] = [];
for(var j =0;j<15;j++){
aleadyin[i][j] = 0;
}
}

//绘制棋子
var drawPiece= function (x,y,me) {
ctx.beginPath();
ctx.arc(15+x*30,15+y*30,14,0,Math.PI*2);
//创建渐变色,两个圆心
var gradient = ctx.createRadialGradient(15+30*x,15+y*30,13,15+30*x,15+y*30,0);

//设置填充色
if(me){
gradient.addColorStop(0,"#0a0a0a");
gradient.addColorStop(1,"#636767");
// ctx.fillStyle = "#333";
}
else{
gradient.addColorStop(0,"#d1d1d1");
gradient.addColorStop(1,"#f9f9f9");
// ctx.fillStyle = "#fff";
}
//绘制,先设置再绘制
ctx.fillStyle = gradient;
ctx.fill();
ctx.stroke();
}

var me = true;
//点击事件下棋
chess.onclick = function(e){
console.log(e);
//获取鼠标坐标
var x = e.offsetX;
var y = e.offsetY;
// console.log("x的坐标是"+ x +" y的坐标是"+y);
//四舍五入
var x1 = Math.round((x-15)/30);
var y1 = Math.round((y-15)/30);
// console.log("x1的坐标是"+ x1 +" y1的坐标是"+y1);
if(aleadyin[x1][y1] == 0){
if(me){ aleadyin[x1][y1] = 1; } //黑棋记为1
else { aleadyin[x1][y1] = 2; } //白棋记为2 无棋子记为0

drawPiece(x1,y1,me);
//判断是否取得胜利
if(isWin(x1,y1,me)){
if(me){ alert("恭喜黑棋取得了胜利!");}
else { alert("恭喜白棋取得了胜利!");}
}
me = !me;
}
}

//定义赢,一个三维数组
//定义赢得胜利种类
//四种情况,横向,纵向,左斜,右斜
wins =[
/* - */
[[-1,0],[1,0]],
/* | */
[[0,-1],[0,1]],
/* / */
[[-1,1],[1,-1]],
/* \ */
[[-1,-1],[1,1]],
];

//下在x,y判断是否能够取得胜利
var isWin = function (x , y,me) {
var ok = 0;
var tempX = x;
var tempY = y;
var count = 1;;
var flag = false;
var colorPiece = 1; //当前的颜色
if(me){ colorPiece = 1; }
else { colorPiece = 2; }

//四种赢的方式
for(var i = 0;i<4;i++){
count = 1;
//现在判断两个方向,加上赢的方式一共是8个方向
//比如横向有两个方向,向左和向右
for(var j=0;j<2;j++){
flag = true;
//沿着某一个方向继续前行,找相同颜色的棋子
while(flag){
tempX = tempX + wins[i][j][0];
tempY = tempY + wins[i][j][1];
if(tempX<0 || tempX>=15 || tempY<0 || tempY >=15){
flag = false;
}
else if(aleadyin[tempX][tempY] == colorPiece){
count ++;
}
//结束循环
else{
flag = false;
}
}
tempX = x;
tempY = y;
}
if(count >= 5){
ok =1;
break;
}
}
if(ok){ return true;}
else { return false;}
}

var AI = function (argument) {

}


// 当前页面加载完成后执行
window.onload = function () {
//画棋盘
drawChessBoard();
// drawPiece(1,1,true);
// drawPiece(1,2,false);
// drawPiece(11,2,false);
// alert("cool boy !");
}

</script>

</body>



</html>

算法部分

五子棋的复杂度为10^70

种类 复杂度
黑白棋 58
五子棋 70
国际象棋 123
象棋 150
围棋 360

评估函数
  对一个棋局需要你计算该棋局的收益值,如果对每一个点考虑,遍历所有空余的点,不考虑其他了,就只能考虑一步,有点目光短浅了。
  这里需要用到博弈树搜索alpha-beta剪枝,之后ok。

参考

五子棋AI教程第二版
w3school