Java學習筆記(七):五子棋AI演算法

MoLC發表於2019-02-08

參考部落格: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在判斷邊角的地方還可以更完善一點,現在先這樣吧,最後附一張效果圖:
在這裡插入圖片描述

相關文章