在上一篇中,我们基本上实现了除AI外的所有五子棋功能,此处要讲述一个简单的权值算法。
- 权值是什么权值?
某个未落子的点沿某一方向的某种棋子排布对应一个权值。
举例如上:从红点开始,①向下是连续四个黑棋,很危了,权值必定很大,设为3000.②右上是黑黑白,比较安全,权值为100。③向右是黑黑黑白,有点危险,权值为1000。④向左只有一个白,安全,权值为20…以此类推。
所以我们把各种棋子排布列成一个权值表:1代表黑棋,2代表白棋
棋子排布 | 权值 |
---|---|
1 | 20 |
11 | 200 |
111 | 2000 |
1111 | 3000 |
12 | 10 |
112 | 100 |
1112 | 1000 |
11112 | 3000 |
再把上表的1,2互换,对应权值也是一样的。
- 如何存储权值表?
·用HashMap来储存权值与排布的键值对
用HashhMap<K,V>的字典储存特性。某个方向的棋局用字符串表示,比如③方向:“1112”。
HashMap<String, Integer> hm = new HashMap<>();//储存棋局权值
hm.put("1", 20);
hm.put("11",200);
hm.put("111",2000);
hm.put("1111",3000);
hm.put("12",10);
hm.put("112", 100);
hm.put("1112", 1000);
hm.put("11112", 3000);
hm.put("2", 20);
hm.put("22", 200);
hm.put("222", 2000);
hm.put("2222", 3000);
hm.put("21", 10);
hm.put("221", 100);
hm.put("2221", 1000);
hm.put("22221", 3000);
- 如何搜索记录棋子排布?
遍历chessArray二维数组的每一个未落子的位置,对于每一个未落子位置,分八个方向记录棋子排布(类似于输赢的判断)。
·那么如何把数字拼接成字符串呢?用如下方法:“字符串变量+数字”实现字符串数字拼接。
String code = "";
code += chessArray[i][j];
- 如何找到AI下一步该落子的点?
定义一个新的整型二维数组来记录每一个未落子的点的权值(8个方向的权值之和),权值最大的点就是AI要落子的点。要求某未落子的点沿某方向的权值,先得到棋子排布code,利用HashMap的get方法找到相应排布对应的权值即可。
·算法代码如下:
String code = ""; //记录每个方向上的棋局情况。""+数字 :自动转成字符串
int color = 0;
Integer value = 0;
int max = 0,im=0,jm=0;
for (int i = 0; i < LINE; i++) {
for (int j = 0; j < LINE; j++) {
if (chessArray[i][j] != 0)
continue;
//向左:
for (int k = i - 1; k >= 0; k--) {
if (chessArray[k][j] == 0) { //沿该方向紧邻的点若也未落子,直接结束本循环
break;
} else if (color == 0) {
color = chessArray[k][j];
code += chessArray[k][j];
} else if(color != chessArray[k][j]){ //然后若后面紧接着异色棋子,记录第一颗异色棋子,结束循环
code += chessArray[k][j];
break;
} else {
code += chessArray[k][j];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向右:
for (int k = i + 1; k < LINE; k++) {
if (chessArray[k][j] == 0) {
break;
} else if (color == 0) {
color = chessArray[k][j];
code += chessArray[k][j];
} else if(color != chessArray[k][j]){
code += chessArray[k][j];
break;
} else {
code += chessArray[k][j];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向上:
for (int k = j - 1; k >= 0; k--) {
if (chessArray[i][k] == 0) {
break;
} else if (color == 0) {
color = chessArray[i][k];
code += chessArray[i][k];
} else if(color != chessArray[i][k]){
code += chessArray[i][k];
break;
} else {
code += chessArray[i][k];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向下:
for (int k = j + 1; k < LINE; k++) {
if (chessArray[i][k] == 0) {
break;
} else if (color == 0) {
color = chessArray[i][k];
code += chessArray[i][k];
} else if(color != chessArray[i][k]){
code += chessArray[i][k];
break;
} else {
code += chessArray[i][k];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向右下
for (int k = i + 1, r = j + 1; k < LINE && r < LINE; k++, r++) {
if (chessArray[k][r] == 0) {
break;
} else if (color == 0) {
color = chessArray[k][r];
code += chessArray[k][r];
} else if(color != chessArray[k][r]){
code += chessArray[k][r];
break;
} else {
code += chessArray[k][r];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向左下:
for (int k = i - 1, r = j + 1; k >= 0 && r < LINE; k--, r++) {
if (chessArray[k][r] == 0) {
break;
} else if (color == 0) {
color = chessArray[k][r];
code += chessArray[k][r];
} else if(color != chessArray[k][r]){
code += chessArray[k][r];
break;
} else {
code += chessArray[k][r];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向左上:
for (int k = i - 1, r = j - 1; k >= 0 && r >= 0; k--, r--) {
if (chessArray[k][r] == 0) {
break;
} else if (color == 0) {
color = chessArray[k][r];
code += chessArray[k][r];
} else if(color != chessArray[k][r]){
code += chessArray[k][r];
break;
} else {
code += chessArray[k][r];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
//向右上:
for (int k = i + 1, r = j - 1; k < LINE && r >= 0; k++, r--) {
if (chessArray[k][r] == 0) {
break;
} else if (color == 0) {
color = chessArray[k][r];
code += chessArray[k][r];
} else if(color != chessArray[k][r]){
code += chessArray[k][r];
break;
} else {
code += chessArray[k][r];
}
}
value = hm.get(code);
if (value != null) {
chessValue[i][j] += value;
}
code = "";
color = 0;
}
}
//找最大权值
for (int i = 0; i < LINE; i++) {
for (int j = 0; j < LINE; j++) {
if (max < chessValue[i][j]) {
max = chessValue[i][j];
im = i;
jm = j;
}
}
}
//在(im,jm)处下棋...
xx = im;
yy = jm;
cStack.push(xx, yy);
x = (xx + 1) * SIZE;
y = (yy + 1) * SIZE;
以下是画棋子..........
以上就是五子棋简单的权值算法的核心部分。
如对此拙作有任何意见或者疑问,欢迎评论或私信提出,批评指正!
- 相关链接: