⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 evaluation.java

📁 Java五子棋 支持本地游戏
💻 JAVA
字号:
/**
 * 
 * This class evaluates the situation of the board 
 *
 */
class Evaluation
{
	int size;

	static final int sTwo = 0;
	static final int sThree = 1;
	static final int sFour = 2;
	static final int two = 3;
	static final int three= 4;
	static final int four = 5;
	static final int five = 6;
	
	//array records the count of the above kind
	int[] blackTypeCount = new int[8];
	int[] whiteTypeCount = new int[8];
	//the two dimension array records the position weight
	public static int[][] posValue;
	
	/**
	 * 
	 * @param mapSize	the size of the board
	 */
	Evaluation(int mapSize)
	{
		size = mapSize;
		posValue = new int[mapSize][mapSize];
		
		//initialize the position weight
		int edge = size - 1;
		for(int i = 0; i < size; i++)
			for(int j = 0; j < size; j++)
			{
				int a = (i > edge - i)?(edge - i):i;
				int b = (j > edge - j)?(edge - j):j;
				posValue[i][j] = (a > b)?b:a;
			}
		
		return;
	}
	
	/**
	 *This method evaluate the board and return a score, if it's a white turn, it'll return
	 *-score, else return score. score will be large if the situation is better for the black
	 *and vice versa
	 * 
	 * @param board				the board information
	 * @param isWhiteTurn		whether the next turn is white
	 * @return 					the score of the board
	 */
	int evaluate(ChessMan[][] board, boolean isWhiteTurn)
	{
		for(int i = 0; i < 8; i++)
		{	
			blackTypeCount[i] = 0;
			whiteTypeCount[i] = 0;
		}
		this.analysisBoard(board);
		int score = 0;
		
		//多个冲四相当与一个活四
		if (whiteTypeCount[sFour] > 1)
			whiteTypeCount[four]++;

		if (blackTypeCount[sFour] > 1)
			blackTypeCount[four]++;

		//computes the white value and the black value
		int WValue = 0, BValue = 0;
		if (isWhiteTurn)
		{
			if (blackTypeCount[five] > 0)
			{	
				BValue = 9999;
			}
			else if (whiteTypeCount[five] > 0)
			{	
				WValue = 9999;
			}
			//white wins
			else if (whiteTypeCount[four] > 0 || whiteTypeCount[sFour] > 0)
			{
				WValue = 9990;
			}
			//black wins
			else if (blackTypeCount[four] > 0)
			{
				BValue = 9970;
			}
			//black wins
			else if (blackTypeCount[sFour] > 0 && blackTypeCount[three] > 0)
			{
				BValue = 9960;
			}
			//white wins
			else if (whiteTypeCount[three] > 0 && blackTypeCount[sFour] == 0)
			{
				WValue = 9950;
			}
			//black wins
			else if (blackTypeCount[three] > 1 && 
				whiteTypeCount[three] == 0 &&
				whiteTypeCount[sThree] == 0)
			{
				BValue = 9940;
			}
			else {
			//calculates the respective value of black and white
			if (whiteTypeCount[three] > 1)
				WValue += 2000;
			else
			{
				if (whiteTypeCount[three] > 0)
					WValue += 200;
			}

			if (blackTypeCount[three] > 1)
				BValue += 1000;
			else
			{
				if (blackTypeCount[three] > 0)
					BValue += 100;
			}

			if (whiteTypeCount[sThree] > 0)
				WValue += whiteTypeCount[sThree]*10;

			if (blackTypeCount[sThree] > 0)
				BValue += blackTypeCount[sThree]*10;

			if (whiteTypeCount[two] > 0)
				WValue += whiteTypeCount[two]*4;

			if (blackTypeCount[two] > 0)
				BValue += blackTypeCount[two]*4;

			if (whiteTypeCount[sTwo] > 0)
				WValue += whiteTypeCount[sTwo];

			if (blackTypeCount[sTwo] > 0)
				BValue += blackTypeCount[sTwo];
			}
		}
		else
		{
			//the following is similar to the above
			if (whiteTypeCount[five] > 0)
			{	
				WValue = 9999;
			}
			else if(blackTypeCount[five] > 0)
			{	
				BValue = 9999;
			}
			else if (blackTypeCount[four] > 0 || blackTypeCount[sFour] > 0)
			{
				BValue = 9990;
			}

			else if (whiteTypeCount[four] > 0)
			{
				WValue = 9970;
			}
			else if (whiteTypeCount[sFour] > 0 && whiteTypeCount[three] > 0)
			{
				WValue = 9960;
			}
			else if (blackTypeCount[three] > 0 && whiteTypeCount[sFour] == 0)
			{
				BValue = 9950;
			}
			else if (whiteTypeCount[three] > 1 && 
				blackTypeCount[three] == 0 &&
				blackTypeCount[sThree] == 0)
			{
				WValue = 9940;
			}
			else {

			if (blackTypeCount[three] > 1)
				BValue += 2000;
			else{
				if (blackTypeCount[three] > 0)
					BValue += 200;
			}

			if (whiteTypeCount[three] > 1)
				WValue += 1000;
			else{
				if (whiteTypeCount[three] > 0)
					WValue += 100;
			}

			if (whiteTypeCount[sThree] > 0)
				WValue += whiteTypeCount[sThree]*10;

			if (blackTypeCount[sThree] > 0)
				BValue += blackTypeCount[sThree]*10;

			if (whiteTypeCount[two] > 0)
				WValue += whiteTypeCount[two]*4;

			if (blackTypeCount[two] > 0)
				BValue += blackTypeCount[two]*4;

			if (whiteTypeCount[sTwo] > 0)
				WValue += whiteTypeCount[sTwo];

			if (blackTypeCount[sTwo] > 0)
				BValue += blackTypeCount[sTwo];
			}
		}
		for (int i = 0; i < size; i++)
			for (int j = 0; j < size; j++)
			{
				ChessMan tmp = board[i][j];
				if (tmp != ChessMan.Empty)
				{
					if (tmp == ChessMan.Black)
						 BValue += posValue[i][j];
					else
						 WValue += posValue[i][j];
				}
			}			
		score = BValue - WValue;
		
		return score;
	}
	
	/**
	 * this method analysis the board and find out the FIVEs, FOURs and THREEs and etc
	 * 
	 * @param board		the board to be analysised
	 */
	void analysisBoard(ChessMan[][] board)
	{
		ChessMan[] line = new ChessMan[size];
		
		//the horizontal direction
		for(int i = 0; i < size; i++)
			analysisLine(board[i], size);
		
/*		System.out.println("水平");
		for(int i = 0; i < 8; i++)
			System.out.print(blackTypeCount[i] + " ");
		
		System.out.println();
		for(int i = 0; i < 8; i++)
			System.out.print(whiteTypeCount[i] + " ");		
		System.out.println();*/
		
		//the vertical direction
		for(int i = 0; i < size; i++)
		{
			for(int j = 0; j < size; j++)
				line[j] = board[j][i];
			analysisLine(line, size);
		}
		
		
/*		System.out.println();
		for(int i = 0; i < 8; i++)
			System.out.print(blackTypeCount[i] + " ");
		
		System.out.println("竖直");
		for(int i = 0; i < 8; i++)
			System.out.print(whiteTypeCount[i] + " ");	
		System.out.println();*/
		
		//the north east direction
		for(int k = 0; k <= 2 * size - 2; k++)
		{
			int n = 0;
			for(int i = 0; i <= k; i++)
			{
				int j = k - i;
				if(j >= size || i >= size)
					continue;
				line[n++] = board[i][j];
			}
			analysisLine(line, size);
		}
		
/*		System.out.println("右上");
		for(int i = 0; i < 8; i++)
			System.out.print(blackTypeCount[i] + " ");
		
		System.out.println();
		for(int i = 0; i < 8; i++)
			System.out.print(whiteTypeCount[i] + " ");	
		System.out.println();
*/		
		//the north west direction
		for(int k = 0; k < size; k++)
		{
			int n = 0;
			for(int i = 0; i < size - k; i++)
			{	
				line[n++] = board[i][i + k];
			}
			analysisLine(line, n);
		}
		
		for(int k = 1; k < size; k++)
		{
			int n = 0;
			for(int i = k; i < size; i++)
			{	
				line[n++] = board[i][i - k];
			}
			
			analysisLine(line, n);
		}		
		
/*		System.out.println("右下");
		for(int i = 0; i < 8; i++)
			System.out.print(blackTypeCount[i] + " ");
		
		System.out.println();
		for(int i = 0; i < 8; i++)
			System.out.print(whiteTypeCount[i] + " ");
*/
	}
	
	/**
	 * this method analysis one line, and finds out how many FIVEs FOURs THREEs of each side 
	 * 
	 * @param line		array stores the line
	 * @param end		the length of the array
	 */
	void analysisLine(ChessMan[] line, int end)
	{
		int i = 0;
		int j = 0;
		int k = 0;
		int bitLine = 0;
		ChessMan oldChess = ChessMan.Empty;
		ChessMan lastChess = ChessMan.Empty;
		
		//divide this line into several segments of different chess color
		//and analysis them respectively 
		while(i < end)
		{
			ChessMan curChess = line[i];
			boolean isOldEmpty = (oldChess == ChessMan.Empty);
			boolean isCurEmpty = (curChess == ChessMan.Empty);
			boolean isCurEqOld = (oldChess == curChess);
			
			//finds out the latest change in chess
			if(!isOldEmpty && curChess != lastChess && lastChess == oldChess)
			{
				k = i;
				//System.out.println("k:" + k);
			}
			
			if(!isCurEmpty)
				bitLine |=  1<<i;
			
			if(isOldEmpty)
			{
				if(!isCurEmpty)
					oldChess = curChess;
			}
			else if(!isCurEqOld && !isCurEmpty)
			{
				analysisChess(bitLine, j, i, oldChess);
				oldChess = curChess;
				j = k;
			}
			lastChess = curChess;
			i++;
		}
		//analysis the last segment
		analysisChess(bitLine, j, size, oldChess);		
		
	}
	
	/**
	 * this method uses bit comparison to find how many FIVEs FOURs THREEs TWOs in a single
	 * segment
	 * 
	 * @param bitLine	one integer value records the bit information of the segment
	 * @param start		the start bit number
	 * @param end		the end bit number
	 * @param c			the chess color the this segment
	 */
	void analysisChess(int bitLine, int start, int end, ChessMan c)
	{
		//System.out.println("start:" + start + "  end:" + end + "  Line:" + bitLine);

		int length = end - start;		
		if(length < 5)
			return;

		int line = bitLine >> start;
		int[] typeCount;
		//System.out.println("line:" + line);
		
		if(c == ChessMan.Black)
			typeCount = blackTypeCount;
		else
			typeCount = whiteTypeCount;
		
		int tmpLine = line;
		for(int i = 0; i <= length - 5; i++)
		{
			int tmp = tmpLine & 0x1f;
			//System.out.println("tmp:" + tmp);

			switch(tmp)
			{
			//五连11111b
			case 0x1f: typeCount[five]++; return;
			//冲四11011b
			case 0x1b: typeCount[sFour]++; break;
			//眠三10011b, 10101b, 11001b
			case 0x13: case 0x15: case 0x19: typeCount[sThree]++; break;
			//眠二10001
			case 0x11: typeCount[sTwo]++; break;
			default: break;
			}
			
			tmpLine >>= 1;
		}
		
		tmpLine = line;
		for(int i = 0; i <= length - 6; i++)
		{
			int tmp = tmpLine & 0x3f;
			//System.out.println("tmp:" + tmp);

			switch(tmp)
			{
			//活四011110b
			case 0x1e: typeCount[four]++; break;
			//活三011010b, 010110b
			case 0x1a: case 0x16: typeCount[three]++; break;
			//活二010010b, 001100b
			case 0x12: case 0xc: typeCount[two]++; break;
			default: break;
			}
			
			tmpLine >>= 1;
		}
		
		tmpLine = line;
		for(int i = 0; i <= length - 7; i++)
		{
			//mask:0111110
			int tmp = tmpLine & 0x3e;
			//System.out.println("tmp:" + tmp);

			//活三:X01110Y
			if(tmp == 0x1c)
			{
				//活三:X 或 Y 等于 0
				if(((tmpLine & 0x1) == 0) || ((tmpLine & 0x40) == 0))
					typeCount[three]++;
			}
			
			//活二:X01010Y
			if(tmp == 0x14)
			{
				//活二:X 或 Y 等于 0
				if(((tmpLine & 0x1) == 0) || ((tmpLine & 0x40) == 0))
					typeCount[two]++;
			}
			
			//mask:0011100
			tmp = tmpLine & 0x1c;
			//冲四:XY101ZW
			if(tmp == 0x14)
			{
				//冲四:XY 等于 11 且 Z 等于 0 或 ZW 等于 11 且 Y 等于 0
				if(((tmpLine & 0x62) == 0x60) || ((tmpLine & 0x23) == 0x3))
					typeCount[sFour]++;
			}
			
			tmpLine >>= 1;
		}
		
		tmpLine = line;
		for(int i = 0; i <= length - 8; i++)
		{
			//mask:00111100
			int tmp = tmpLine & 0x3c;

			//活二:XY0110ZW
			if(tmp == 0x18)
			{
				//活二:XY 等于 0 且 ZW 不等于 0 或 ZW 等于 0 且 XY 不等于 0
				int XY = tmpLine & 0xc0;
				int ZW = tmpLine & 0x3;
				if(((XY == 0) && (ZW != 0)) || ((ZW == 0) && (XY != 0)))
					typeCount[two]++;
			}
			
			tmpLine >>= 1;
		}
		
		//取尾部五位
		int suffix = line & 0x1f;
		//System.out.println("suffix:" + suffix);
		
		switch(suffix)
		{
		//冲四01111, 11101
		case 0xf: case 0x1d: typeCount[sFour]++; break;
		//眠三01011,眠三01101,眠三00111
		case 0xb: case 0xd: case 0x7: typeCount[sThree]++; break;
		//眠二00011,00101,01001
		case 0x3: case 0x5: case 01001: typeCount[sTwo]++; break;
		default: break;
		}
		
		int prefix = (line >> (length - 5)) & 0x1f;
		//System.out.println("prefix:" + prefix);
		
		switch(prefix)
		{
		//冲四11110, 10111
		case 0x1e: case 0x17: typeCount[sFour]++; break;
		//眠三11010,眠三10110,眠三11100
		case 0x1a: case 0x16: case 0x1c: typeCount[sThree]++; break;
		//眠二11000,10100,10010
		case 0x18: case 0x14: case 0x12: typeCount[sTwo]++; break;
		default: break;
		}
		
		if(length >= 6)
		{
			//取尾部六位111111
			suffix = line & 0x3f;
			//System.out.println("suffix:" + suffix);
			
			switch(suffix)
			{
			//活三001110
			case 0xe: typeCount[three]++; break;
			//活二001010, 000110
			case 0xa: case 0x6: typeCount[two]++; break;
			default: break;
			}
			
			prefix = (line >> (length - 6)) & 0x3f;
			
			switch(prefix)
			{
			//活三011100
			case 0x1c: typeCount[three]++; break;
			//活二010100, 011000
			case 0x14: case 0x18: typeCount[two]++; break;
			default: break;
			}
		}
		
/*		for(int i = 0; i < 8; i++)
			System.out.print(typeCount[i] + " ");
		System.out.println();*/
	}
	
/*	public static void main(String[] args)
	{
		Evaluation e = new Evaluation(15);
		ChessMan[][] board = new ChessMan[15][15];
		
		e.analysisChess(52, 0, 15, ChessMan.Black);
		
		System.exit(0);
	}*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -