Java学习笔记(七):五子棋AI算法

参考博客:https://www.cnblogs.com/songdechiu/p/5768999.html

一、五子棋棋型分析

参考:http://game.onegreen.net/wzq/HTML/142336.html
最常见的基本棋型大体有以下几种:连五,活四,冲四,活三,眠三,活二,眠二。

连五:顾名思义,五颗同色棋子连在一起,不需要多讲。

在这里插入图片描述

活四:有两个连五点(即有两个点可以形成五),图中白点即为连五点。

稍微思考一下就能发现活四出现的时候,如果对方单纯过来防守的话,是已经无法阻止自己连五了。
图2-2

冲四:有一个连五点

如下面三图,均为冲四棋型。图中白点为连五点。
相对比活四来说,冲四的威胁性就小了很多,因为这个时候,对方只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。
图2-3  图2-4  图2-5

活三:可以形成活四的三

如下图,代表两种最基本的活三棋型。图中白点为活四点。
活三棋型是我们进攻中最常见的一种,因为活三之后,如果对方不以理会,将可以下一手将活三变成活四,而我们知道活四是已经无法单纯防守住了。所以,当我们面对活三的时候,需要非常谨慎对待。在自己没有更好的进攻手段的情况下,需要对其进行防守,以防止其形成可怕的活四棋型。
图2-6  图2-7

其中图2-7中间跳着一格的活三,也可以叫做跳活三。

眠三:只能够形成冲四的三

如下各图,分别代表最基础的六种眠三形状。图中白点代表冲四点。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,我们知道,是可以防守住的。
图2-8  图2-9  图2-10
在这里插入图片描述
如上所示,眠三的形状是很丰富的。对于初学者,在下棋过程中,很容易忽略不常见的眠三形状,例如图2-13所示的眠三。

有新手学了活三眠三后,会提出疑问,说活三也可以形成冲四啊,那岂不是也可以叫眠三?
会提出这个问题,说明对眠三定义看得不够仔细:眠三的的定义是,只能够形成冲四的三。而活三可以形成眠三,但也能够形成活四。

此外,在五子棋中,活四棋型比冲四棋型具有更大的优势,所以,我们在既能够形成活四又能够形成冲四时,会选择形成活四。

活二:能够形成活三的二

如下图,是三种基本的活二棋型。图中白点为活三点。
活二棋型看起来似乎很无害,因为他下一手棋才能形成活三,等形成活三,我们再防守也不迟。但其实活二棋型是非常重要的,尤其是在开局阶段,我们形成较多的活二棋型的话,当我们将活二变成活三时,才能够令自己的活三绵绵不绝微风里,让对手防不胜防。
图2-14  图2-15  图2-16

眠二:能够形成眠三的二

图中四个为最基本的眠二棋型,细心且喜欢思考的同学会根据眠三介绍中的图2-13找到与下列四个基本眠二棋型都不一样的眠二。图中白点为眠三点。
图2-17 图2-18图2-19  图2-20

二、五子棋打分机制

打分思路:
  • 每次一个棋子,找出棋盘上全部棋子的旁边位置,下图打勾位置
    在这里插入图片描述
  • 把打勾的位置用一个point类的数组target[]保存起来
  • 对target[]中的每个棋子评分
  • 取target[]中的棋子各个方向的4个棋子,以横向为例(取三角形位置):
    在这里插入图片描述
  • 根据以上得出八个方向的棋子分布,做出评分(属于哪一类)
评分规定:

综合四个方向后:

棋型分数
成五(five)+100000分
活四/双眠四/眠四活(alive_4/highdie_4>1/highdie_4&alive_3)+10000分
双活三(alive_3>1)+5000分
眠三活三(die_3&alive_3)+1000分
眠四(highdie_4)+500分
低级眠四(die_4)+400分
单活三(alive_3)+100分
跳活三(tiaoalive_3)+90分
双活二(alive_2>1)+50分
活二(alive_2)+10分
低级活二(lowalive_2)+9分
眠三(die_3)+5分
眠二(die_2)+2分
初始值(无威胁的其他情况)+1分

三、附录代码

在上一篇双人五子棋的基础上添加一个AI判断机制,棋盘和判断方法(Check)、重绘函数等都不变 https://blog.csdn.net/qq_36804363/article/details/86733292
分八个方向判断
在这里插入图片描述
可归为横纵左斜右斜四个方向,以黑棋子为例(评定黑棋子分数)

  • 先用八个函数分别得出八个方向上除了黑色外的棋盘坐标,此时得出的是最靠黑棋子的坐标
  • 得出坐标后,再拓展,相当于以上的八个方向拓展到4个,以横向为例,如下图所示
    在这里插入图片描述
  • 再对应各种不同的棋型判断棋子的位置是否符合条件
    AIJudge:
package com.GobandAI;

import java.awt.Point;

import com.GobandAI.Checkerboard.Config;

/**
 * 判断是否能成5, 如果是机器方的话给予100000分,如果是人方的话给予100000 分;
 * 判断是否能成活4或者是双死4或者是死4活3,如果是机器方的话给予10000分,如果是人方的话给予10000分;
 * 判断是否已成双活3,如果是机器方的话给予5000分,如果是人方的话给予5000 分;
 * 判断是否成死3活3(高级),如果是机器方的话给予1000分,如果是人方的话给予1000 分;
 * 判断是否能成死4,如果是机器方的话给予500分,如果是人方的话给予500分;
 * 判断是否能成低级死4,如果是机器方的话给予400分,如果是人方的话给予400分;
 * 判断是否能成单活3,如果是机器方的话给予100分,如果是人方的话给予100分; 判断是否能成跳活3,如果是机器方的话给予90分,如果是人方的话给予90分;
 * 判断是否能成双活2,如果是机器方的话给予50分,如果是人方的话给予50分; 判断是否能成活2,如果是机器方的话给予10分,如果是人方的话给予10分;
 * 判断是否能成低级活2,如果是机器方的话给予9分,如果是人方的话给予9分; 判断是否能成死3,如果是机器方的话给予5分,如果是人方的话给予5分;
 * 判断是否能成死2,如果是机器方的话给予2分,如果是人方的话给予2分。
 * 判断是否其他情况(nothing),如果是机器方的话给予1分,如果是人方的话给予1分。 有棋子,则直接0分
 * 
 * @author mo
 *
 */
public class AIjudge {

	private int five, alive_4, highdie_4, die_4, alive_3, die_3, alive_2, die_2, lowalive_2, tiaoalive_3;

	public void Init() {
		five = 0;
		alive_4 = 0;
		highdie_4 = 0;
		die_4 = 0;
		alive_3 = 0;
		die_3 = 0;
		alive_2 = 0;
		die_2 = 0;
		lowalive_2 = 0;
		tiaoalive_3 = 0;
	}

	public Point getright(int[][] chesses, int x, int y) {// 右
		Point count = new Point();
		for (int i = x + 1; i < Config.columns; i++) {
			if (chesses[i][y] != chesses[x][y]) {
				count = new Point(i, y);
				// System.out.println("右:"+count);
				return count;
			}
		}
		return count;
	}

	public Point getleft(int[][] chesses, int x, int y) {// 左
		Point count = new Point();
		for (int i = x - 1; i >= 0; i--) {
			if (chesses[i][y] != chesses[x][y]) {
				count = new Point(i, y);
				return count;
			}
		}
		return count;
	}

	public Point getup(int[][] chesses, int x, int y) {// 上
		Point count = new Point();
		for (int i = y; i >= 0; i--) {
			if (chesses[x][i] != chesses[x][y]) {
				count = new Point(x, i);
				return count;
			}
		}
		return count;
	}

	public Point getdown(int[][] chesses, int x, int y) {// 下
		Point count = new Point();
		for (int i = y + 1; i < Config.rows; i++) {
			if (chesses[x][i] != chesses[x][y]) {
				count = new Point(x, i);
				return count;
			}
		}
		return count;
	}

	public Point getSlashru(int[][] chesses, int x, int y) {// 右上
		Point count = new Point();
		for (int i = y - 1, j = x + 1; j < Config.rows && i >= 0; j++, i--) {
			if (chesses[j][i] != chesses[x][y]) {
				count = new Point(j, i);
				return count;
			}
		}
		return count;
	}

	public Point getSlashrd(int[][] chesses, int x, int y) {// 右下
		Point count = new Point();
		for (int i = y + 1, j = x + 1; j < Config.rows && i < Config.columns; j++, i++) {
			if (chesses[j][i] != chesses[x][y]) {
				count = new Point(j, i);
				return count;
			}
		}
		return count;
	}

	public Point getSlashlu(int[][] chesses, int x, int y) {// 左上
		Point count = new Point();
		for (int i = y, j = x; j >= 0 && i >= 0; j--, i--) {
			if (chesses[j][i] != chesses[x][y]) {
				count = new Point(j, i);
				return count;
			}
		}
		return count;
	}

	public Point getSlashld(int[][] chesses, int x, int y) {// 左下
		Point count = new Point();
		for (int i = y + 1, j = x - 1; j >= 0 && i < Config.columns; j--, i++) {
			if (chesses[j][i] != chesses[x][y]) {
				count = new Point(j, i);
				return count;
			}
		}
		return count;
	}

	public int judge(int[][] chesses, int x, int y, int data) {
		this.Init();
		chesses[x][y] = data;// 给个假设值!
		Point index_r = getright(chesses, x, y);// 右
		Point index_l = getleft(chesses, x, y);// 左
		Point index_u = getup(chesses, x, y);// 上
		Point index_d = getdown(chesses, x, y);// 下
		Point index_ru = getSlashru(chesses, x, y);// 右上
		Point index_rd = getSlashrd(chesses, x, y);// 右下
		Point index_lu = getSlashlu(chesses, x, y);// 左上
		Point index_ld = getSlashld(chesses, x, y);// 左下
		int left = chesses[index_l.x][index_l.y];// 左
		int left1 = 9, right1 = 9, left2 = 9, right2 = 9, left3 = 9, right3 = 9;
		if (index_l.x > 0)
			left1 = chesses[index_l.x - 1][index_l.y];
		int right = chesses[index_r.x][index_r.y];// 右
		if (index_r.x < Config.columns - 2)
			right1 = chesses[index_r.x + 1][index_r.y];
		if (index_l.x - 1 > 0)
			left2 = chesses[index_l.x - 2][index_l.y];
		if (index_r.x < Config.columns - 3)
			right2 = chesses[index_r.x + 2][index_r.y];
		if (index_l.x - 2 > 0)
			left3 = chesses[index_l.x - 3][index_l.y];
		if (index_r.x < Config.columns - 4)
			right3 = chesses[index_r.x + 3][index_r.y];

		// 纵向
		int up = chesses[index_u.x][index_u.y];// 上
		int up1 = 9, down1 = 9, up2 = 9, down2 = 9, up3 = 9, down3 = 9;
		if (index_u.x > 0)
			up1 = chesses[index_u.x - 1][index_u.y];
		int down = chesses[index_d.x][index_d.y];// 1下
		if (index_d.x < Config.rows - 2)
			down1 = chesses[index_d.x + 1][index_d.y];
		if (index_u.x - 1 > 0)
			up2 = chesses[index_u.x - 2][index_u.y];
		if (index_d.x < Config.rows - 3)
			down2 = chesses[index_d.x + 2][index_d.y];
		if (index_u.x - 2 > 0)
			up3 = chesses[index_u.x - 3][index_u.y];
		if (index_d.x < Config.rows - 4)
			down3 = chesses[index_d.x + 3][index_d.y];

		// 左斜线

		int ld = chesses[index_ld.x][index_ld.y];// 左下
		int ld1 = 9, ru1 = 9, ld2 = 9, ru2 = 9, ld3 = 9, ru3 = 9;
		if (index_ld.x > 0 && index_ld.y < Config.rows - 2)// 1左下
			ld1 = chesses[index_ld.x - 1][index_ld.y + 1];
		int ru = chesses[index_ru.x][index_ru.y];// 右上
		if (index_ru.x < Config.columns - 2 && index_ru.y > 0)// 右上
			ru1 = chesses[index_ru.x + 1][index_ru.y - 1];
		if (index_ld.x - 1 > 0 && index_ld.y < Config.rows - 3)// 2左下
			ld2 = chesses[index_ld.x - 2][index_ld.y + 2];
		if (index_ru.x < Config.columns - 3 && index_ru.y > 1)// 右上
			ru2 = chesses[index_ru.x + 2][index_ru.y - 2];
		if (index_ld.x - 2 > 0 && index_ld.y < Config.rows - 4)// 3左下
			ld2 = chesses[index_ld.x - 3][index_ld.y + 3];
		if (index_ru.x < Config.columns - 4 && index_ru.y > 2)// 右上
			ru2 = chesses[index_ru.x + 3][index_ru.y - 3];

		// 右斜线
		int lu = chesses[index_lu.x][index_lu.y];// 右上
		int lu1 = 9, rd1 = 9, lu2 = 9, rd2 = 9, lu3 = 9, rd3 = 9;
		if (index_lu.x > 0 && index_lu.y > 0)// 1左上
			lu1 = chesses[index_lu.x - 1][index_lu.y - 1];
		int rd = chesses[index_rd.x][index_rd.y];// 左下
		if (index_rd.x < Config.columns - 2 && index_rd.y < Config.rows - 2)// 右下
			rd1 = chesses[index_rd.x + 1][index_rd.y + 1];
		if (index_lu.x - 1 > 0 && index_lu.y > 1)// 2左上
			lu2 = chesses[index_lu.x - 2][index_lu.y - 2];
		if (index_rd.x < Config.columns - 3 && index_rd.y < Config.rows - 3)// 右下
			rd2 = chesses[index_rd.x + 2][index_rd.y + 2];
		if (index_lu.x - 2 > 0 && index_lu.y > 2)// 3左上
			lu2 = chesses[index_lu.x - 3][index_lu.y - 3];
		if (index_rd.x < Config.columns - 4 && index_rd.y < Config.rows - 4)// 右下
			rd2 = chesses[index_rd.x + 3][index_rd.y + 3];
		/**
		 * 五连珠
		 */

		if (Check.checkfive(chesses, x, y))// 成5
		{
			five++;
		}
		/**
		 * 四连珠
		 */
		if (Check.checkRow(chesses, x, y) == 4) {// 横向四连珠
			System.out.println("四连珠 <" + x + ", " + y + ">");
			if (left == 0 && right == 0)// 活四
			{
				alive_4++;
			} else if ((left == 0 && right == -data) || (left == -data && right == 0)) {
				highdie_4++;
			} // 死4
		}
		if (Check.checkColumn(chesses, x, y) == 4) {// 纵向四连珠
			if (up == 0 && down == 0)// 活四
			{
				alive_4++;
			} else if ((up == 0 && down == -data) || (up == -data && down == 0)) {
				highdie_4++;
			} // 眠4
		}
		if (Check.checkIncleft(chesses, x, y) == 4) {// 左斜线:左下右上
			if (ld == 0 && ru == 0)// 活四
			{
				alive_4++;
			} else if ((ld == 0 && ru == -data) || (ld == -data && ru == 0)) {
				highdie_4++;
			} // 眠4
		}
		if (Check.checkIncright(chesses, x, y) == 4) {// 右斜线:左上右下
			if (lu == 0 && rd == 0)// 活四
			{
				alive_4++;
			} else if ((lu == 0 && rd == -data) || (lu == -data && rd == 0)) {
				highdie_4++;
			} // 眠4
		}
		/**
		 * 三连珠
		 */
		if (Check.checkRow(chesses, x, y) == 3) {// 横向三连珠
			if (left == 0 && right == 0) {// 断开处空
				if (left1 == 0 || right1 == 0)// 活三
				{
					alive_3++;
				}
				if (left1 == data || right == data)// 死4
				{
					die_4++;
				}
				if (left1 == -data || right1 == -data)// 眠三
				{
					die_3++;
				}
			} else if (left == -data && right == 0) {// 左边被拦
				if (right1 == data)// 右边隔一个有棋子,眠四
				{
					die_4++;
				} else if (right1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			} else if (right == -data && left == 0) {// 右边被拦
				if (left1 == data)// 左边隔一个棋子,眠四
				{
					die_4++;
				} else if (left1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			}

		}
		if (Check.checkColumn(chesses, x, y) == 3) {// 纵向三连珠
			if (up == 0 && down == 0) {// 断开处空
				if (up1 == 0 || down1 == 0)// 活三
				{
					alive_3++;
				}
				if (up1 == data || down == data)// 死4
				{
					die_4++;
				}
				if (up1 == -data || down1 == -data)// 眠三
				{
					die_3++;
				}
			} else if (up == -data && down == 0) {// 左边被拦
				if (down1 == data)// 右边隔一个有棋子,眠四
				{
					die_4++;
				} else if (down1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			} else if (down == -data && up == 0) {// 右边被拦
				if (up1 == data)// 左边隔一个棋子,眠四
				{
					die_4++;
				} else if (up1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			}

		}
		if (Check.checkIncleft(chesses, x, y) == 3) {// 左斜线三连珠 :左下+右上
			if (ld == 0 && ru == 0) {// 断开处空
				if (ld1 == 0 || ru1 == 0)// 活三
				{
					alive_3++;
				}
				if (ld1 == data || ru == data)// 死4
				{
					die_4++;
				}
				if (ld1 == -data || ru1 == -data)// 眠三
				{
					die_3++;
				}
			} else if (ld == -data && ru == 0) {// 左边被拦
				if (ru1 == data)// 右边隔一个有棋子,眠四
				{
					die_4++;
				} else if (ru1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			} else if (ru == -data && ld == 0) {// 右边被拦
				if (ld1 == data)// 左边隔一个棋子,眠四
				{
					die_4++;
				} else if (ld1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			}

		}
		if (Check.checkIncright(chesses, x, y) == 3) {// 右斜三连珠:右下+左上
			if (lu == 0 && rd == 0) {// 断开处空
				if (lu1 == 0 || rd1 == 0)// 活三
				{
					System.out.println(data + "<" + x + "," + y + ">右斜线活3   右斜线检查" + Check.checkIncright(chesses, x, y)
							+ "左斜线检查:" + Check.checkIncleft(chesses, x, y));
					System.out.println("<" + x + "," + y + ">" + "" + lu3 + "" + "live2:" + lu2 + " live3:" + lu1
							+ " die3:" + lu + " low2:" + rd);
					alive_3++;
				}
				if (lu1 == data || rd == data)// 死4
				{
					die_4++;
				}
				if (lu1 == -data || rd1 == -data)// 眠三
				{
					die_3++;
				}
			}
			if (lu == -data && rd == 0) {// 左边被拦
				if (rd1 == data)// 右边隔一个有棋子,眠四
				{
					die_4++;
				} else if (rd1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			}
			if (rd == -data && lu == 0) {// 右边被拦
				if (lu1 == data)// 左边隔一个棋子,眠四
				{
					die_4++;
				} else if (lu1 == 0)// 没有放棋子为眠3
				{
					die_3++;
				}
			}

		}
		/**
		 * 二连珠
		 */
		if (Check.checkRow(chesses, x, y) == 2) {// 横向二连珠

			if (right == 0 && left == 0) {// 如果两边断开位置都为空
				// System.out.println("二连珠"+left2+" "+left1+" "+left+" "+right+"
				// "+right1+" "+right2);
				if ((right1 == 0 && right2 == data) || (left1 == 0 && left2 == data))// 第三棋子有一个为本色,眠3
				{
					die_3++;
				} else if (right1 == 0 && left1 == 0)// 断开第二个位置都为空,活2
				{
					// System.out.println("活二!");
					alive_2++;
				}
				if ((right1 == data && right2 == 0) || (left1 == data && left2 == 0))
				// 某一边断开第二个位置为本色,第三位置为空,跳活三
				{
					tiaoalive_3++;
				}
				if ((right1 == data && right2 == -data) || (left1 == data && left2 == -data))
				// 某一边断开第二位置为本色,得三位置为他色,眠三
				{
					die_3++;
				}
				if ((right1 == data && right2 == data) || (left1 == data && left2 == data))
				// 某一边的12都为本色,眠四
				{
					die_4++;
				}
			} else if (right == 0 && left == -data) {// 右边为空左边被拦
				if (right1 == data && right2 == data)// 右边12都为本色,眠四
				{
					die_4++;
				} else if (right1 == data || right2 == data)// 右2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (right1 == 0 && right2 == 0)// 右123都为空,眠2
				{
					die_2++;
				}

			} else if (left == 0 && right == -data) {// 左边为空右边被拦
				if (left1 == data && left2 == data)// 左边12都为本色,眠四
				{
					die_4++;
				} else if (left1 == data || left2 == data)// 左2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (left1 == 0 && left2 == 0)// 左123为空,眠2
				{
					die_2++;
				}
			}
		}
		if (Check.checkColumn(chesses, x, y) == 2) {// 纵向二连珠

			if (up == 0 && down == 0) {// 如果两边断开位置都为空
				if ((up1 == 0 && up2 == data) || (down1 == 0 && down2 == data))// 第三棋子有一个为本色,眠3
				{
					die_3++;
				} else if (up1 == 0 && down1 == 0)// 断开第二个位置都为空,活2
				{
					alive_2++;
				}
				if ((up1 == data && up2 == 0) || (down1 == data && down2 == 0))
				// 某一边断开第二个位置为本色,第三位置为空,跳活三
				{
					tiaoalive_3++;
				}
				if ((up1 == data && up2 == -data) || (down1 == data && down2 == -data))
				// 某一边断开第二位置为本色,得三位置为他色,眠三
				{
					die_3++;
				}
				if ((up1 == data && up2 == data) || (down1 == data && down2 == data))
				// 某一边的12都为本色,眠四
				{
					die_4++;
				}
			} else if (up == 0 && down == -data) {// 上边为空下边被拦
				if (up1 == data && up2 == data)// 上边12都为本色,眠四
				{
					die_4++;
				} else if (up1 == data || up2 == data)// 上2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (up1 == 0 && up2 == 0)// 上123都为空,眠2
				{
					die_2++;
				}

			} else if (down == 0 && up == -data) {// 下边为空上边被拦
				if (down1 == data && down2 == data)// 下边12都为本色,眠四
				{
					die_4++;
				} else if (down1 == data || down2 == data)// 下2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (down1 == 0 && down2 == 0)// 下123为空,眠2
				{
					die_2++;
				}
			}

		}
		if (Check.checkIncleft(chesses, x, y) == 2) {// 左斜线:左下ld+右上ru
			if (ld == 0 && ru == 0) {// 如果两边断开位置都为空
				if ((ld1 == 0 && ld2 == data) || (ru1 == 0 && ru2 == data))// 第三棋子有一个为本色,眠3
				{
					die_3++;
				} else if (ld1 == 0 && ru1 == 0)// 断开第二个位置都为空,活2
				{
					alive_2++;
				}
				if ((ld1 == data && ld2 == 0) || (ru1 == data && ru2 == 0))
				// 某一边断开第二个位置为本色,第三位置为空,跳活三
				{
					tiaoalive_3++;
				}
				if ((ld1 == data && ld2 == -data) || (ru1 == data && ru2 == -data))
				// 某一边断开第二位置为本色,得三位置为他色,眠三
				{
					die_3++;
				}
				if ((ld1 == data && ld2 == data) || (ru1 == data && ru2 == data))
				// 某一边的12都为本色,眠四
				{
					die_4++;
				}
			} else if (ld == 0 && ru == -data) {// 左边为空右边被拦
				if (ld1 == data && ld2 == data)// 左边12都为本色,眠四
				{
					die_4++;
				} else if (ld1 == data || ld2 == data)// 左2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (ld1 == 0 && ld2 == 0)// 左123都为空,眠2
				{
					die_2++;
				}

			} else if (ru == 0 && ld == -data) {// 右边为空右边被拦
				if (ru1 == data && ru2 == data)// 右边12都为本色,眠四
				{
					die_4++;
				} else if (ru1 == data || ru2 == data)// 右2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (ru1 == 0 && ru2 == 0)// 右123为空,眠2
				{
					die_2++;
				}
			}
		}
		if (Check.checkIncright(chesses, x, y) == 2) {// 右斜线:左上lu+右下rd
			if (lu == 0 && rd == 0) {// 如果两边断开位置都为空
				if ((lu1 == 0 && lu2 == data) || (rd1 == 0 && rd2 == data))// 第三棋子有一个为本色,眠3
				{
					die_3++;
				} else if (lu1 == 0 && rd1 == 0)// 断开第二个位置都为空,活2
				{
					// System.out.println("<"+x+","+y+"> 检测到右斜线活二");
					alive_2++;
				}
				if ((lu1 == data && lu2 == 0) || (rd1 == data && rd2 == 0))
				// 某一边断开第二个位置为本色,第三位置为空,跳活三
				{
					tiaoalive_3++;
				}
				if ((lu1 == data && lu2 == -data) || (rd1 == data && rd2 == -data))
				// 某一边断开第二位置为本色,得三位置为他色,眠三
				{
					die_3++;
				}
				if ((lu1 == data && lu2 == data) || (rd1 == data && rd2 == data))
				// 某一边的12都为本色,眠四
				{
					die_4++;
				}
			} else if (lu == 0 && rd == -data) {// 左边为空右边被拦
				if (lu1 == data && lu2 == data)// 左边12都为本色,眠四
				{
					die_4++;
				} else if (lu1 == data || lu2 == data)// 左2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (lu1 == 0 && lu2 == 0)// 左123都为空,眠2
				{
					die_2++;
				}

			} else if (rd == 0 && lu == -data) {// 右边为空左边被拦
				if (rd1 == data && rd2 == data)// 右边12都为本色,眠四
				{
					die_4++;
				} else if (rd1 == data || rd2 == data)// 右2只要有一个为自己的棋子,眠三
				{
					die_3++;
				} else if (rd1 == 0 && rd2 == 0)// 右123为空,眠2
				{
					die_2++;
				}
			}

		}
		/**
		 * 1连珠
		 */
		if (Check.checkRow(chesses, x, y) == 1) {// 横向1连
			// 眠四情况01000
			if ((right == 0 && right1 == data && right2 == data && right3 == data)
					|| (left == 0 && left1 == data && left2 == data && left3 == data)) {
				die_4++;
			}
			// 跳三101001
			if ((right == 0 && left == 0 && left1 == data && left2 == data && left3 == 0)
					|| (left == 0 && right == 0 && right1 == data && right2 == data && right3 == 0)) {
				tiaoalive_3++;
			}
			// 眠三
			if ((right == 0 && left == 0 && left1 == data && left2 == data && left3 == -data)
					|| (right == 0 && left == 0 && right1 == data && right2 == data && right3 == -data))// 101002
			{
				die_3++;
			} else if ((right == -data && left == 0 && left1 == data && left2 == data && left3 == 0)
					|| (right == 0 && left == -data && right1 == data && right2 == data && right3 == 0))// 100102
			{
				die_3++;
			} else if ((right == 0 && right1 == 0 && right2 == data && right3 == data)
					|| (left == 0 && left1 == 0 && left2 == data && left3 == data))// 01100
			{
				die_3++;
			} else if ((right == 0 && right1 == data && right2 == 0 && right3 == data)
					|| (left == 0 && left1 == data && left2 == 0 && left3 == data))
				// 活二
				if ((left == 0 && right == 0 && left1 == data && left2 == 0 && left3 == 0)
						|| (right == 0 && left == 0 && right1 == data && right2 == 0 && right3 == 0))
				// 101011
				{
				lowalive_2++;
				} else if ((left == 0 && right == 0 && right1 == 0 && right2 == data && right3 == 0) || (right == 0 && left == 0 && left1 == 0 && left2 == data && left3 == 0))
				// 101101
				{
				lowalive_2++;
				}
			// 眠二
			// 低眠2不考虑
		}
		if (Check.checkColumn(chesses, x, y) == 1) {// 纵向1连
			// 眠四情况01000
			if ((up == 0 && up1 == data && up2 == data && up3 == data)
					|| (down == 0 && down1 == data && down2 == data && down3 == data)) {
				die_4++;
			}
			// 跳三101001
			if ((up == 0 && down == 0 && down1 == data && down2 == data && down3 == 0)
					|| (down == 0 && up == 0 && up1 == data && up2 == data && up3 == 0)) {
				tiaoalive_3++;
			}
			// 眠三
			if ((up == 0 && down == 0 && down1 == data && down2 == data && down3 == -data)
					|| (up == 0 && down == 0 && up1 == data && up2 == data && up3 == -data))// 101002
			{
				die_3++;
			} else if ((up == -data && down == 0 && down1 == data && down2 == data && down3 == 0)
					|| (up == 0 && down == -data && up1 == data && up2 == data && up3 == 0))// 100102
			{
				die_3++;
			} else if ((up == 0 && up1 == 0 && up2 == data && up3 == data)
					|| (down == 0 && down1 == 0 && down2 == data && down3 == data))// 01100
			{
				die_3++;
			} else if ((up == 0 && up1 == data && up2 == 0 && up3 == data)
					|| (down == 0 && down1 == data && down2 == 0 && down3 == data)) {
				die_3++;
			}
			// 活二
			if ((down == 0 && up == 0 && down1 == data && down2 == 0 && down3 == 0)
					|| (up == 0 && down == 0 && up1 == data && up2 == 0 && up3 == 0))
			// 101011
			{
				lowalive_2++;
			} else if ((down == 0 && up == 0 && up1 == 0 && up2 == data && up3 == 0)
					|| (up == 0 && down == 0 && down1 == 0 && down2 == data && down3 == 0))
			// 101101
			{
				lowalive_2++;
			}
			// 眠二
			// 低眠2不考虑
		}
		if (Check.checkIncleft(chesses, x, y) == 1) {// 左斜线:左下+右上
			// 眠四情况01000
			if ((ru == 0 && ru1 == data && ru2 == data && ru3 == data)
					|| (ld == 0 && ld1 == data && ld2 == data && ld3 == data)) {
				die_4++;
			}
			// 跳三101001
			if ((ru == 0 && ld == 0 && ld1 == data && ld2 == data && ld3 == 0)
					|| (ld == 0 && ru == 0 && ru1 == data && ru2 == data && ru3 == 0)) {
				tiaoalive_3++;
			}
			// 眠三
			if ((ru == 0 && ld == 0 && ld1 == data && ld2 == data && ld3 == -data)
					|| (ru == 0 && ld == 0 && ru1 == data && ru2 == data && ru3 == -data))// 101002
			{
				die_3++;
			} else if ((ru == -data && ld == 0 && ld1 == data && ld2 == data && ld3 == 0)
					|| (ru == 0 && ld == -data && ru1 == data && ru2 == data && ru3 == 0))// 100102
			{
				die_3++;
			} else if ((ru == 0 && ru1 == 0 && ru2 == data && ru3 == data)
					|| (ld == 0 && ld1 == 0 && ld2 == data && ld3 == data))// 01100
			{
				die_3++;
			} else if ((ru == 0 && ru1 == data && ru2 == 0 && ru3 == data)
					|| (ld == 0 && ld1 == data && ld2 == 0 && ld3 == data)) {
				die_3++;
			}
			// 活二
			if ((ld == 0 && ru == 0 && ld1 == data && ld2 == 0 && ld3 == 0)
					|| (ru == 0 && ld == 0 && ru1 == data && ru2 == 0 && ru3 == 0))
			// 101011
			{
				lowalive_2++;
			} else if ((ld == 0 && ru == 0 && ru1 == 0 && ru2 == data && ru3 == 0)
					|| (ru == 0 && ld == 0 && ld1 == 0 && ld2 == data && ld3 == 0))
			// 101101
			{
				lowalive_2++;
			}
			// 眠二
		}
		if (Check.checkIncright(chesses, x, y) == 1) {// 右斜线:右下rd+左上lu
			// 眠四情况01000
			if ((rd == 0 && rd1 == data && rd2 == data && rd3 == data)
					|| (lu == 0 && lu1 == data && lu2 == data && lu3 == data)) {
				die_4++;
			}
			// 跳三101001
			if ((rd == 0 && lu == 0 && lu1 == data && lu2 == data && lu3 == 0)
					|| (lu == 0 && rd == 0 && rd1 == data && rd2 == data && rd3 == 0)) {
				tiaoalive_3++;
			}
			// 眠三
			if ((rd == 0 && lu == 0 && lu1 == data && lu2 == data && lu3 == -data)
					|| (rd == 0 && lu == 0 && rd1 == data && rd2 == data && rd3 == -data))// 101002
			{
				die_3++;
			} else if ((rd == -data && lu == 0 && lu1 == data && lu2 == data && lu3 == 0)
					|| (rd == 0 && lu == -data && rd1 == data && rd2 == data && rd3 == 0))// 100102
			{
				die_3++;
			} else if ((rd == 0 && rd1 == 0 && rd2 == data && rd3 == data)
					|| (lu == 0 && lu1 == 0 && lu2 == data && lu3 == data))// 01100
			{
				die_3++;
			} else if ((rd == 0 && rd1 == data && rd2 == 0 && rd3 == data)
					|| (lu == 0 && lu1 == data && lu2 == 0 && lu3 == data)) {
				die_3++;
			}
			// 活二
			if ((lu == 0 && rd == 0 && lu1 == data && lu2 == 0 && lu3 == 0)
					|| (rd == 0 && lu == 0 && rd1 == data && rd2 == 0 && rd3 == 0))
			// 101011
			{
				lowalive_2++;
			} else if ((lu == 0 && rd == 0 && rd1 == 0 && rd2 == data && rd3 == 0)
					|| (rd == 0 && lu == 0 && lu1 == 0 && lu2 == data && lu3 == 0))
			// 101101
			{
				lowalive_2++;
			}
			// 眠二
		}
		chesses[x][y] = 0;// 检查假设值之后返回

		return this.getLevel();
	}

	public int getLevel() {
		int count = 1;
		if (five > 0)
			count += 100000;// 赢
		if (alive_4 > 0 || highdie_4 > 1 || (highdie_4 > 0 && alive_3 > 0))// 活4,双死4,死4活3
			count += 10000;
		if (alive_3 > 1)// 双活3
			count += 5000;
		if (die_3 > 0 && alive_3 > 0)// 死3活3
			count += 1000;
		if (highdie_4 > 0)// 死4
			count += 500;
		if (die_4 > 0)// 低级死4
			count += 400;
		if (alive_3 > 0)// 单活3
			count += 100;
		if (tiaoalive_3 > 0)// 跳活3
			count += 90;
		if (alive_2 > 1)// 双活2
			count += 50;
		if (alive_2 > 0)// 活2
			count += 10;
		if (lowalive_2 > 0)// 低活2
			count += 9;
		if (die_3 > 0)// 死3
			count += 5;
		if (die_2 > 0)// 死2
			count += 2;
		// if()
		return count;
	}
}

在监听器中添加人机对战的模式:

  • 人机模式要先找到target数组
  • 在target数组中分别对黑白棋评分
  • 机器人为白棋,取黑白棋中分数最高的点落子
package com.GobandAI;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;

import com.GobandAI.Checkerboard.Config;
import com.GobandAI.Repaint;

/**
 * 五子棋监听器
 * 
 * @author mo
 *
 */

public class DrawListener implements MouseListener, ActionListener {
	private int count = 0, flag_start = 0, flag_winner = 0, flag_play = -1;
	private Graphics g;
	private Repaint[] rep;
	private int de = 0;
	private int[][] chesses;// 1黑 -1白
	private int[][] back = new int[256][2];
	private Checkerboard board;
	private String name;
	private JFrame finshjf = new JFrame();
	private JTextArea txt = new JTextArea();

	public void setGraphics(Graphics g) {
		this.g = g;

	}

	/**
	 * 为了实现棋盘的重绘
	 */
	public void setCheckerboard(Checkerboard c) {
		this.board = c;
		txt = board.getEast();
	}

	public void setChesses(int[][] c) {
		this.chesses = c;
	}

	/**
	 * 重绘数组
	 * 
	 * @param rep
	 */
	public void setrepaint(Repaint[] rep) {
		this.rep = rep;
	}

	public void actionPerformed(ActionEvent e) {
		name = e.getActionCommand();
		if (name.equals("开始游戏") || name.equals("重新开始")) {
			board.clearChesses();
			flag_start = 1;
			flag_winner = 0;
			count = 0;
			finshjf.setVisible(false);
			txt.append("游戏开始" + "\n");
		}
		if (name.equals("返回棋局")) {
			finshjf.setVisible(false);
			txt.append("返回棋局" + "\n");
		}
		if (name.equals("悔棋")) {
			if (count < 2)
				txt.append("不能悔棋!" + "\n");
			else txt.append("悔棋成功" + "\n");
			this.rep[count - 1] = null;
			this.rep[count - 2] = null;
			chesses[back[count - 1][0]][back[count - 1][0]] = 0;
			chesses[back[count - 1][0]][back[count - 1][1]] = 0;
			chesses[back[count - 2][0]][back[count - 2][0]] = 0;
			chesses[back[count - 2][0]][back[count - 2][1]] = 0;
			count -= 2;
			board.paint(board.getGraphics());
		}
		if (name.equals("玩家对战")) {
			flag_play = 0;
			txt.append("选择模式为:玩家对战\n");
		}
		if (name.equals("人机对战")) {
			flag_play = 1;
			txt.append("选择模式为:人机对战\n");
		}
	}

	/**
	 * 鼠标点击事件 放下棋子
	 */
	public void mouseClicked(MouseEvent e) {
		int x0 = e.getX();
		int y0 = e.getY();
		/**
		 * 判断按下是否有效
		 */
		if (flag_play == -1)
			txt.append("请选择对战模式:人机/玩家\n");
		if (flag_start == 0)
			txt.append("请点击开始游戏" + "\n");

		if (flag_play == 0)
			this.Player_against(x0, y0);
		if (flag_play == 1)
			this.Computer_against(x0, y0);

	};

	/**
	 * 玩家对抗
	 * 
	 * @param x0
	 *            按下的坐标
	 * @param y0
	 *            按下的坐标
	 */
	public void Player_against(int x0, int y0) {
		Image img_b = new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/黑棋.png").getImage();
		Image img_w = new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/白棋.png").getImage();
		if ((flag_start == 1)
				&& ((x0 - Config.start) % Config.SIZE < Config.SIZE / 3
						|| ((x0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)
								&& ((y0 - Config.start) % Config.SIZE < Config.SIZE / 3)
						|| (y0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)
				&& (x0 > Config.SIZE * 2 / 3) && (y0 > Config.SIZE * 2 / 3)
				&& (x0 < (Config.start + (Config.columns - 1) * Config.SIZE) - 5
						&& y0 < (Config.start + (Config.rows - 1) * Config.SIZE) - 5)) {
			/**
			 * x,y保存的是画笔需要绘制的界面坐标
			 */
			int x = Config.start + Config.SIZE * ((x0 - Config.start) / Config.SIZE);
			int y = Config.start + Config.SIZE * ((y0 - Config.start) / Config.SIZE);
			if (((x0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)) {
				x = Config.start + Config.SIZE * (1 + (x0 - Config.start) / Config.SIZE);

			}
			if (((y0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)) {
				y = Config.start + Config.SIZE * (1 + (y0 - Config.start) / Config.SIZE);
			}
			/*
			 * x,y需减去start再除棋盘大小 对应棋盘数组的索引
			 */
			int index_x = (x - Config.start) / Config.SIZE;
			int index_y = (y - Config.start) / Config.SIZE;
			if (chesses[index_x][index_y] == 0) {
				System.out.println(index_x + " " + index_y);

				if (count % 2 == 0) {
					txt.append("当前为白棋" + "\n");
					g.drawImage(img_b, x - Config.CHESS_SIZE / 2, y - Config.CHESS_SIZE / 2, null);
					chesses[index_x][index_y] = 1;
					back[count][0] = index_x;
					back[count][1] = index_y;
					if (Check.checkfive(chesses, index_x, index_y)) {
						System.out.println("黑胜");
						txt.append("游戏结束" + "\n");
						txt.append("黑棋胜利" + "\n");
						flag_winner = 1;
					}
				} else {
					txt.append("当前为黑棋" + "\n");
					g.drawImage(img_w, x - Config.CHESS_SIZE / 2, y - Config.CHESS_SIZE / 2, null);
					chesses[index_x][index_y] = -1;
					back[count][0] = index_x;
					back[count][1] = index_y;
					if (Check.checkfive(chesses, index_x, index_y)) {
						System.out.println("白胜");
						txt.append("游戏结束" + "\n");
						txt.append("白棋胜利" + "\n");
						flag_winner = -1;
					}

				}
				Repaint r = new Repaint(x - Config.CHESS_SIZE / 2, y - Config.CHESS_SIZE / 2,
						count % 2 == 0 ? img_b : img_w);

				rep[de++] = r;
				count++;

			}
			System.out.println("name:" + name);
			if (flag_winner != 0) {
				finshjf = this.finshShow();
				finshjf.setVisible(true);
			}

		}
	}

	/**
	 * 人机对抗
	 * 
	 * @param x0
	 * @param y0
	 */
	public void Computer_against(int x0, int y0) {
		Image img_b = new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/黑棋.png").getImage();
		Image img_w = new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/白棋.png").getImage();
		if ((flag_start == 1)
				&& ((x0 - Config.start) % Config.SIZE < Config.SIZE / 3
						|| ((x0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)
								&& ((y0 - Config.start) % Config.SIZE < Config.SIZE / 3)
						|| (y0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)
				&& (x0 > Config.SIZE * 2 / 3) && (y0 > Config.SIZE * 2 / 3)
				&& (x0 < (Config.start + (Config.columns - 1) * Config.SIZE - 5)
						&& y0 < (Config.start + (Config.rows - 1) * Config.SIZE) - 5)) {
			// System.out.println(x0+" "+y0);
			/**
			 * x,y保存的是画笔需要绘制的界面坐标
			 */
			int x = Config.start + Config.SIZE * ((x0 - Config.start) / Config.SIZE);
			int y = Config.start + Config.SIZE * ((y0 - Config.start) / Config.SIZE);
			if (((x0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)) {
				x = Config.start + Config.SIZE * (1 + (x0 - Config.start) / Config.SIZE);

			}
			if (((y0 - Config.start) % Config.SIZE > 2 * Config.SIZE / 3)) {
				y = Config.start + Config.SIZE * (1 + (y0 - Config.start) / Config.SIZE);
			}
			/*
			 * x,y需减去start再除棋盘大小 对应棋盘数组的索引
			 */
			int index_x = (x - Config.start) / Config.SIZE;
			int index_y = (y - Config.start) / Config.SIZE;
			if (chesses[index_x][index_y] == 0) {
				txt.append("当前为白棋" + "\n");

				chesses[index_x][index_y] = 1;
				// System.out.println("黑"+chesses[index_x][index_y]);
				back[count][0] = index_x;
				back[count][1] = index_y;
				System.out.println("黑 :" + index_x + " " + index_y);
				count++;

				g.drawImage(img_b, x - Config.CHESS_SIZE / 2, y - Config.CHESS_SIZE / 2, null);
				Repaint r = new Repaint(x - Config.CHESS_SIZE / 2, y - Config.CHESS_SIZE / 2, img_b);
				rep[de++] = r;
				if (Check.checkfive(chesses, index_x, index_y)) {
					System.out.println("黑胜");
					txt.append("游戏结束" + "\n");
					txt.append("黑棋胜利" + "\n");
					flag_winner = 1;
				}

				index_x = this.getTarget().x;
				index_y = this.getTarget().y;
				if (flag_winner == 0) {
					// 输出
					System.out.println("白" + index_x + " " + index_y);

					txt.append("当前为黑棋" + "\n");
					g.drawImage(img_w, (index_x * Config.SIZE + Config.start) - Config.CHESS_SIZE / 2,
							(index_y * Config.SIZE + Config.start) - Config.CHESS_SIZE / 2, null);
					chesses[index_x][index_y] = -1;
					back[count][0] = index_x;
					back[count][1] = index_y;
					count++;
					r = new Repaint((index_x * Config.SIZE + Config.start) - Config.CHESS_SIZE / 2,
							(index_y * Config.SIZE + Config.start) - Config.CHESS_SIZE / 2, img_w);
					rep[de++] = r;
					if (Check.checkfive(chesses, index_x, index_y)) {
						System.out.println("白胜");
						txt.append("游戏结束" + "\n");
						txt.append("白棋胜利" + "\n");
						flag_winner = -1;
					}
				}
			}
			if (flag_winner != 0 || count == 225) {
				finshjf = this.finshShow();
				finshjf.setVisible(true);
			}
		}
	}

	/**
	 * 一方胜利后显示
	 */
	public JFrame finshShow() {
		flag_start = 0;
		board.initchesses();
		JFrame jf = new JFrame("Finsh Game!");
		jf.setSize(200, 130);
		jf.setDefaultCloseOperation(2);
		// 关闭方法 :销毁不结束
		jf.setLocationRelativeTo(null);
		// 居中显示
		jf.setLayout(new FlowLayout());
		// 流式布局
		JButton yes = new JButton("重新开始");
		JButton no = new JButton("返回棋局");
		jf.add(yes);
		jf.add(no);
		yes.addActionListener(this);
		no.addActionListener(this);

		JLabel jl = new JLabel();
		if (flag_winner == 1)
			jl = new JLabel(" 黑棋胜利! ", new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/黑棋.png"), 0);
		else if (flag_winner == -1)
			jl = new JLabel(" 白棋胜利! ", new ImageIcon("D:/learning/mydemo/Javaworkspace/rect/src/com/goband/白棋.png"), 0);
		else if (flag_winner == 0 && count == 225)
			jl = new JLabel(" 平局! ");
		jf.add(jl);
		return jf;
	}

	public class Target {
		public int x;
		public int y;
		public int score_b;
		public int score_w;

		public Target(int x, int y, int scoreb, int scorew) {
			this.x = x;
			this.y = y;
			this.score_b = scoreb;
			this.score_w = scorew;
		}

		public Target() {
		}
	}

	/**
	 * 获取人机评分点
	 */
	public Target[] getScore() {
		Target[] target = new Target[Config.rows * Config.columns];

		int index = 0;
		AIjudge judge = new AIjudge();
		for (int i = 0; i < count; i++) {
			int x = back[i][0];
			int y = back[i][1];
			// System.out.println(chesses[x-1][y-1]+" "+chesses[x][y-1]+"
			// "+chesses[x+1][y-1]);
			// System.out.println(chesses[x-1][y]+" "+chesses[x][y]+"
			// "+chesses[x+1][y]);
			// System.out.println(chesses[x-1][y+1]+" "+chesses[x][y+1]+"
			// "+chesses[x+1][y+1]);
			if (x > 0) {
				// 棋子左边有效
				// 正左
				if (chesses[x - 1][y] == 0) {
					Target t = new Target(x - 1, y, judge.judge(chesses, x - 1, y, 1),
							judge.judge(chesses, x - 1, y, -1));
					target[index++] = t;
				}
			}
			if (x > 0 && y < Config.rows - 2) {
				// 棋子下面有效,左下
				if (chesses[x - 1][y + 1] == 0) {
					Target t = new Target(x - 1, y + 1, judge.judge(chesses, x - 1, y + 1, 1),
							judge.judge(chesses, x - 1, y + 1, -1));
					target[index++] = t;

				}
			}
			if (y < Config.rows - 2) {
				// 正下
				if (chesses[x][y + 1] == 0) {
					Target t = new Target(x, y + 1, judge.judge(chesses, x, y + 1, 1),
							judge.judge(chesses, x, y + 1, -1));
					target[index++] = t;

				}

			}
			if (y < Config.rows - 2 && x < Config.columns - 2) {
				// 右下
				if (chesses[x + 1][y + 1] == 0) {
					Target t = new Target(x + 1, y + 1, judge.judge(chesses, x + 1, y + 1, 1),
							judge.judge(chesses, x + 1, y + 1, -1));
					target[index++] = t;

				}
			}
			if (y > 0 && x > 0) {
				// 左上有效
				if (chesses[x - 1][y - 1] == 0) {
					Target t = new Target(x - 1, y - 1, judge.judge(chesses, x - 1, y - 1, 1),
							judge.judge(chesses, x - 1, y - 1, -1));
					target[index++] = t;

				}
			}
			if (y > 0 && x < Config.columns - 2) {// 右上
				if (chesses[x + 1][y - 1] == 0) {
					Target t = new Target(x + 1, y - 1, judge.judge(chesses, x + 1, y - 1, 1),
							judge.judge(chesses, x + 1, y - 1, -1));
					target[index++] = t;

				}
			}
			if (x < Config.columns - 2) {
				// 正右
				if (chesses[x + 1][y] == 0) {
					// System.out.println("right");
					Target t = new Target(x + 1, y, judge.judge(chesses, x + 1, y, 1),
							judge.judge(chesses, x + 1, y, -1));
					target[index++] = t;

				}
			}
			if (y > 0) {
				// 正上
				if (chesses[x][y - 1] == 0) {
					// System.out.println("up");
					Target t = new Target(x, y - 1, judge.judge(chesses, x, y - 1, 1),
							judge.judge(chesses, x, y - 1, -1));
					target[index++] = t;

				}
			}
		}
		return target;
	}

	// 评分类
	public Target getTarget() {
		Target[] t = getScore();
		Target max_b = new Target();
		Target max_w = new Target();
		max_b.score_b = 0;
		max_w.score_w = 0;
		for (int i = 0; i < t.length; i++) {
			if (t[i] != null) {
				System.out.println("<" + t[i].x + ", " + t[i].y + "> " + t[i].score_b + " " + t[i].score_w);
				if (t[i].score_b > max_b.score_b) {
					max_b = t[i];
					// System.out.println(max_b.score_b);
				}
				if (t[i].score_w > max_w.score_w) {
					max_w = t[i];
					// System.out.println(max_w.score_w);
				}
			}
		}
		if (max_b.score_b >= max_w.score_w)
			return max_b;
		if (max_b.score_b < max_w.score_w)
			return max_w;
		return null;
	}

	public void mousePressed(MouseEvent e) {

	};

	public void mouseReleased(MouseEvent e) {

	};

	public void mouseEntered(MouseEvent e) {
	};

	public void mouseExited(MouseEvent e) {
	};
}

其他的部分跟双人对战没有什么差别,这个AI在判断边角的地方还可以更完善一点,现在先这样吧,最后附一张效果图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值