暑假复习篇之五子棋③【人机对战篇1】
人机五子棋算法:从每个空位开始出发,八个方位分析连子情况,把每个方向的连子对应的分数累加在空位上
一、分析棋盘情况
活连:两端都是空位
①010 10
②0110 100
③01110 1000
④011110 5000
⑤020 11
⑥0220 110
⑦02220 1100
⑧022220 5500
眠连:一边是空位,一边不可以下棋
①01 6
②011 60
③0111 600
④01111 5000
⑤02 7
⑥022 70
⑦0222 700
⑧02222 5500
算分示例:
007:它的周围有七个点可以落子,在它左边落子会形成一个两连给10分,在它的下面和左上角右下角落子皆是如此,在它左下角落子则会形成一个三连给100分,在它的右边落子与001/003/005形成一个四连则是1000分然后与007形成一个二连就是10,加起来就是1010,在它上面落子分别与005/003/007形成二连,三个10相加就是30
其他棋子的算分与007保持一致
二、哈希表:HashMap
1、存储的数据:key value
2、可以通过key 查找值 value
3、所有的key不允许重复
4、使用方式:HashMap<key的数据类型,value的数据类型>map = new HashMap<>;
5、存储上面的连子情况与对照分数 可以使用HashMap
HashMap<String , Integer> scoreMap = new HashMap<>();
存储数据:scoreMap.put(" 010 " , 10);
三、向左查找棋子的代码实例
package daytoday.lfx250706;import java.util.HashMap;public class AI {int ROW = 16;int COL = 16;HashMap<String, Integer> scoreMap = new HashMap<>();public AI() {//关于棋子评分的哈希表scoreMap.put("010", 10);scoreMap.put("0110", 100);scoreMap.put("01110", 1000);scoreMap.put("011110", 5000);scoreMap.put("020", 11);scoreMap.put("0220", 110);scoreMap.put("02220", 1100);scoreMap.put("022220", 5500);scoreMap.put("01", 6);scoreMap.put("011", 60);scoreMap.put("0111", 600);scoreMap.put("01111", 5000);scoreMap.put("02", 7);scoreMap.put("022", 70);scoreMap.put("0222", 700);scoreMap.put("02222", 5500);}public static void main(String[] args) {//测试棋盘二维数组int[][] chessArr = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},};System.out.println(chessArr.length);System.out.println(chessArr[0].length);AI ai = new AI();ai.getAIScore(chessArr);}int[][] scoreArr;public void getAIScore(int[][] chessArr) {scoreArr = new int[ROW][COL];//遍历所有的空位,计算每个空位的分数for(int i=0;i< ROW;i++){for(int j=0;j<COL;j++){int cnum = chessArr[i][j];if (cnum == 0){//向八个方位查找连子情况,统计分数累加到空位上toLeft(chessArr,i,j);//toRight(chessArr,i,j);}}}}private void toLeft(int[][] chessArr, int r, int c) {//rc是空位置的坐标//向左边找if (c == 0) {//左边没有位置return;}int cn1 = chessArr[r][c - 1];if (cn1 == 0) {//左边有位置但是没有棋子return;}String codeStr = "0" + cn1;for (int i = c - 2; i >= 0; i--) {if (cn1 == chessArr[r][i]) {//左边第2 - n颗棋子是否与第一颗颜色相等codeStr = codeStr + cn1;} else {if (chessArr[r][i] == 0) {//左边第2 - n颗棋子是否为空codeStr = codeStr + "0";break;} else {break;}}}System.out.println("向左统计:" + codeStr);}
}
四、算分+打印评分位置棋盘
package daytoday;import java.util.HashMap;
//250706public class AI {int ROW = 16;int COL = 16;HashMap<String, Integer> scoreMap = new HashMap<>();public AI() {scoreMap.put("010", 10);scoreMap.put("0110", 100);scoreMap.put("01110", 1000);scoreMap.put("011110", 5000);scoreMap.put("020", 11);scoreMap.put("0220", 110);scoreMap.put("02220", 1100);scoreMap.put("022220", 5500);scoreMap.put("01", 6);scoreMap.put("011", 60);scoreMap.put("0111", 600);scoreMap.put("01111", 5000);scoreMap.put("02", 7);scoreMap.put("022", 70);scoreMap.put("0222", 700);scoreMap.put("02222", 5500);}public static void main(String[] args) {//测试棋盘二维数组int[][] chessArr = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},};System.out.println(chessArr.length);System.out.println(chessArr[0].length);AI ai = new AI();ai.getAIScore(chessArr);}int[][] scoreArr;public void getAIScore(int[][] chessArr) {scoreArr = new int[ROW][COL];//遍历所有的空位,计算每个空位的分数for(int i=0;i< ROW;i++){for(int j=0;j<COL;j++){int cnum = chessArr[i][j];if (cnum == 0){//向八个方位查找连子情况,统计分数累加到空位上toLeft(chessArr,i,j);toRight(chessArr,i,j);}}}System.out.println("分数数组:");for (int i=0;i< ROW;i++){for (int j=0;j<COL;j++){System.out.print(scoreArr[i][j] + " \t");}System.out.println();}}private void toLeft(int[][] chessArr, int r, int c) {//rc是空位置的坐标//向左边找if (c == 0) {//左边没有位置return;}int cn1 = chessArr[r][c - 1];if (cn1 == 0) {//左边有位置但是没有棋子return;}String codeStr = "0" + cn1;for (int i = c - 2; i >= 0; i--) {if (cn1 == chessArr[r][i]) {//左边第2 - n颗棋子是否与第一颗颜色相等codeStr = codeStr + cn1;} else {if (chessArr[r][i] == 0) {//左边第2 - n颗棋子是否为空codeStr = codeStr + "0";break;} else {break;}}}int score = scoreMap.get(codeStr);System.out.println("向左统计:" + codeStr + "--- 分数:" + score);scoreArr[r][c] += score;}public void toRight(int[][] chessArr, int r, int c) {// 向右找if (c == COL - 1) {// 空位在最右边return;}int cn1 = chessArr[r][c + 1];if (cn1 == 0) {// 右边第一颗就是空位return;}String codeStr = "0" + cn1;for (int i = c + 2; i < COL; i++) {if (cn1 == chessArr[r][i]) {codeStr += cn1;} else {if (chessArr[r][i] == 0) {codeStr += "0";}break;}}int score = scoreMap.get(codeStr);System.out.println("向右统计:" + codeStr + "--- 分数:" + score);scoreArr[r][c] += score;}
}