JAVA设计:AI中国象棋(附详细解释和源码)

AI中国象棋核心就是:博弈;引申为:在一定的条件下,遵守一定的规则,一个或几个拥有绝对理想思维的团队,从各自允许选择的行为或策略经行选择并加以实施。

博弈问题一般有三个要素:局中人,规则,策略这里的三个要素分别对应象棋中的棋手、象棋规则以及棋术,有五个方面的内容:第一,博弈的参加者,即博弈过程中独立决策,独立承担后果的个人或者组织(本文局中人是棋手);第二,博弈信息,即博弈者所掌握的对选择策略有帮助的情报资料(本文就是两位棋手都知道对面的走的棋,因为棋盘都是公开透明);第三:博弈方可选择的全部行为或策略的集合(中国象棋每一步有50-70种走法,而平均30+回合即可决出胜负);第四:博弈的次序,即博弈参加者做出策略选择的先后(通俗点就是棋手是马吃炮,还是车吃马之间的选择);第五:博弈方的收益,即各博弈方做出的决策选择后的所得和所示(棋手最后是赢了还是输了或者平局)。

下面我们结合结果以及代码给大家进行详细解释:
JAVA设计:AI中国象棋(附详细解释和源码)_第1张图片       JAVA设计:AI中国象棋(附详细解释和源码)_第2张图片  JAVA设计:AI中国象棋(附详细解释和源码)_第3张图片

评价一个AI中国象棋的好坏主要看它的棋力,经过测试这款AI中国象棋可以战胜90%的象棋玩家,总体效果来说还勉强过得去吧。而一个棋力的好坏,主要看算法,这里用到的算法是决策树,大致的步骤就是(1)取得棋盘上的所有走法;(2)搜索所有走法的分支;(3)评估每个分支。

(1)取得棋盘上的所有分支,主要是根据象棋的规则来的

package com.pj.chess;

import static com.pj.chess.ChessConstant.*;
import static com.pj.chess.Tools.*;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Random;

import com.pj.chess.chessmove.ChessMovePlay;
import com.pj.chess.chessmove.ChessQuiescMove;
import com.pj.chess.chessmove.MoveNode;
import com.pj.chess.chessparam.ChessParam;
import com.pj.chess.evaluate.EvaluateCompute;
import com.pj.chess.evaluate.EvaluateComputeMiddle;
import com.pj.chess.zobrist.TranspositionTable;
import static com.pj.chess.chessmove.ChessQuiescMove.*;
/**
 * @author pengjiu
 * 棋子棋盘初始化操作
 * 棋子的着法预生成
 */



public class ChessInitialize {
	//马着法预生成数组
	int[][]  knightMove=new int[BOARDSIZE90][8];  
	//马着法拌腿位置预生成数组
	int[][]  horseLeg=new int[BOARDSIZE90][8];  
	//象着法预生成数组
	int[][]  elephantMove=new int[BOARDSIZE90][4];  
	//象着法拌腿位置预生成数组
	int[][]  elephantLeg=new int[BOARDSIZE90][4];
	//兵着法预生成数组
	 int[][][]  soldierMove=new int[2][BOARDSIZE90][3]; 
	//车吃子着法预生成数组
	int[][][]  chariotMoveRowEat=new int[9][512][2];//行(上下)
	int[][][]  chariotMoveColEat=new int[10][1024][2];   //列(左右)
	//车炮不吃子着法预生成数组
	int[][][]  move_chariotGunRowNop=new int[9][512][9];//行(上下)不吃子是有多个情况
	int[][][]  move_chariotGunColNop=new int[10][1024][10];   //列(左右)
	//炮吃子着法预生成数组
	int[][][]  gunMoveRowEat=new int[9][512][2];//行(上下)
	int[][][]  gunMoveColEat=new int[10][1024][2];   //列(左右)
	//炮伪攻击位置
	int[][][]  gunFackAttackRow=new int[9][512][9];//行(上下)
	int[][][]  gunFackAttackCol=new int[10][1024][10];   //列(左右)
	//炮隔多子所能攻击到的位置
	int[][][]  gunMoreRestAttackRow=new int[9][512][9];//行(上下)
	int[][][]  gunMoreRestAttackCol=new int[10][1024][10];   //列(左右)

	public static ChessParam getGlobalChessParam(int[] boardTemp ){
		int[] board = new int[BOARDSIZE90];
		int[] chesses = new int[48];
		for (int i = 0; i < board.length; i++) {
			board[i] = -1;
		}
		for (int i = 0; i < chesses.length; i++) {
			chesses[i] = -1;
		}

		BitBoard[] chessBitBoardRole = new BitBoard[15];
		for (int i = 0; i < chessBitBoardRole.length; i++) {
			chessBitBoardRole[i] = new BitBoard();
		}
		ChessParam chessParamCont = new ChessParam(board, chesses, new int[2],
				new int[10], new int[9], new int[15], new BitBoard(),
				new BitBoard[] { new BitBoard(), new BitBoard() },
				chessBitBoardRole);
		for(int i=0;i0){
				int destSite=i;
				int chess=boardTemp[i];
				chessParamCont.board[destSite]=chess;
				chessParamCont.allChess[chess]=destSite;
				int destRow = boardRow[destSite];
				int destCol = boardCol[destSite];
				chessParamCont.boardBitRow[destRow]|=(1<<(8-destCol));
				chessParamCont.boardBitCol[destCol]|=(1<<(9-destRow)); 
			}
		}
		chessParamCont.initChessBaseScoreAndNum();
		TranspositionTable.genStaticZobrist32And64OfBoard(chessParamCont.board);

		return chessParamCont;
	}
	static{
		// 位棋盘的初始
		for (int i = 0; i < MaskChesses.length; i++) {
			MaskChesses[i] = new BitBoard(i);
		}
		new ChessInitialize();
	}
	private ChessInitialize(){
		//马不考虑别腿的位棋盘
		initBitBoard(KnightBitBoards);
		//马别腿的位子
		initBitBoard(KnightLegBitBoards);
		//马象攻击生成
		initBitBoard(KnightBitBoardOfAttackLimit);
		initBitBoard(ElephanBitBoardOfAttackLimit);
		
		cleanEmpty(knightMove);
		cleanEmpty(horseLeg);
		cleanEmpty(elephantMove);
		cleanEmpty(elephantLeg);
		cleanEmpty(soldierMove);
		cleanEmpty(gunFackAttackRow);
		cleanEmpty(gunFackAttackCol);
		cleanEmpty(gunMoreRestAttackRow);
		cleanEmpty(gunMoreRestAttackCol);
		
		//初始马的着法
		initKnightMove();
		//初始象的着法
		initElephantMove();
		//初始卒的着法
		initSoldier();
		//初始不吃子车炮对应所有行着法  
		this.initChariotGunVariedMove(cleanEmpty(move_chariotGunRowNop), 0, 0,false);
		//初始不吃子车炮对应所有列着法
		this.initChariotGunVariedMove(cleanEmpty(move_chariotGunColNop), 1, 0,false); 
		//初始炮吃子对应所有行着法 
		this.initChariotGunVariedMove(cleanEmpty(gunMoveRowEat), 0, 1,true);
		//初始炮吃子对应所有列着法
		this.initChariotGunVariedMove(cleanEmpty(gunMoveColEat), 1, 1,true); 
		//车吃子 (行) 
		this.initChariotGunVariedMove(cleanEmpty(chariotMoveRowEat), 0, 0,true);
		//车吃子 (列)
		this.initChariotGunVariedMove(cleanEmpty(chariotMoveColEat), 1, 0,true); 
		
		/******炮伪攻击位置*******/
		initGunFackEatMove(gunFackAttackRow,0);
		initGunFackEatMove(gunFackAttackCol,1);
		//炮隔多子能攻击到的位置
		this.initChariotGunVariedMove(gunMoreRestAttackRow, 0, 2,true);
		this.initChariotGunVariedMove(gunMoreRestAttackCol, 1, 2,true);
		
		//生成置换表
//		genBoardZobrist();
		//生成基础分 和 棋子数量
 
		//预生成所有位棋盘
		preAllBitBoard();

		
	}

	private void preAllBitBoard() {
		// 马 考虑别腿所能攻击到的位置
		preBitBoardAttack(knightMove, horseLeg, KnightBitBoardOfAttackLimit, 0);
		// 象 考虑别腿所能攻击到的位置
		preBitBoardAttack(elephantMove, elephantLeg,
				ElephanBitBoardOfAttackLimit, 1);
		// 车炮不吃子的情况 行
		preGunAndChariotBitBoardAttack(move_chariotGunRowNop,
				MoveChariotOrGunBitBoardRow, 0);
		// 车炮不吃子的情况 列
		preGunAndChariotBitBoardAttack(move_chariotGunColNop,
				MoveChariotOrGunBitBoardCol, 1);
		// 车吃子情况 行
		preGunAndChariotBitBoardAttack(chariotMoveRowEat,
				ChariotBitBoardOfAttackRow, 0);
		// 车吃子情况 列
		preGunAndChariotBitBoardAttack(chariotMoveColEat,
				ChariotBitBoardOfAttackCol, 1);
		// 炮吃子情况 行
		preGunAndChariotBitBoardAttack(gunMoveRowEat, GunBitBoardOfAttackRow, 0);
		// 炮吃子情况 列
		preGunAndChariotBitBoardAttack(gunMoveColEat, GunBitBoardOfAttackCol, 1);
		// 生成将的位棋盘
		preBitBoardKingMove(KingBitBoard);
		// 生成士的位棋盘
		preBitBoardGuardMove(GuardBitBoard);
		// 卒将军的棋盘
		preKingCheckedSoldierBitBoards(KingCheckedSoldierBitBoards);
		//炮伪攻击位置
		preGunAndChariotBitBoardAttack(gunFackAttackRow, GunBitBoardOfFakeAttackRow, 0);
		preGunAndChariotBitBoardAttack(gunFackAttackCol, GunBitBoardOfFakeAttackCol, 1);
		//车炮的机动性
		preGunAndChariotMobility(MoveChariotOrGunBitBoardRow,ChariotAndGunMobilityRow);
		preGunAndChariotMobility(MoveChariotOrGunBitBoardCol,ChariotAndGunMobilityCol);
		// 炮隔多子吃子情况 行
		preGunAndChariotBitBoardAttack(gunMoreRestAttackRow, GunBitBoardOfMoreRestAttackRow, 0);
		// 炮隔多子吃子情况 列
		preGunAndChariotBitBoardAttack(gunMoreRestAttackCol, GunBitBoardOfMoreRestAttackCol, 1);
		//加载开局库
//		loadBook();
	}
	private void preKingCheckedSoldierBitBoards(BitBoard[] bitBoard){
		for(int i=0;i7) {
							_tSoldierMoveTab=new int[]{+0x10,-0x01,+0x01};
						}else{
							_tSoldierMoveTab=new int[]{+0x10};
						}
					}else if(i==REDPLAYSIGN){
						//红方兵以经过界						
						if(site/16<8){
							_tSoldierMoveTab=new int[]{-0x10,-0x01,+0x01};
						}else{
							_tSoldierMoveTab=new int[]{-0x10};
						}
					}
					for (int j = 0; j < _tSoldierMoveTab.length; j++) {
						int _tSoldier = site + _tSoldierMoveTab[j]; 
						if (isBoardTo255(_tSoldier)) { 
							 int siteTo90=boardMap[site];
							 int _tSoldier90=boardMap[_tSoldier];
							soldierMove[i][siteTo90][z] =_tSoldier90;
							if(SoldiersBitBoard[i][siteTo90]==null){
								SoldiersBitBoard[i][siteTo90]=new BitBoard();
							}
							//兵所能攻击到的位棋盘
							SoldiersBitBoard[i][siteTo90].assignOr(MaskChesses[_tSoldier90]);
							z++;
						}
					}
				}
			}
	}
	 
	 
	/**
	 *@author pengjiu 
	 *@date:Sep 23, 2011 1:44:24 PM
	 * 功能:车炮吃子与不吃子
	 *@param moveEat 数组
	 *@param direction 方向
	 *@param handicapNum 中间间隔棋子数
	 *@param isEat 是否吃子 true false
	*/
	private  void initChariotGunVariedMove(int [][][] moveEat,int direction,int handicapNum,boolean isEat){
		int num=moveEat.length-1;
		int sort=moveEat[0].length;
		 for(int i=0;i<=num;i++){
			 int site=1<0)){
					 if(isEat && j==site){ //吃子自己不能算进去
						 continue;
					 }
					 int isHandicap=0;
					 int eatIndex=0;
					 //向左(上)取值
					 for(int n=i+1;n<=num;n++){
						int _tSite=1< 0){ 
								if (isHandicap 0 ){
								break;
							}
						 }
					 } 
					 isHandicap=0; 
					 //向右(下)取值
					 for(int n=i-1;n>=0;n--){
						 int _tSite=1<0 ){ 
								 if(isHandicap0 ){
								break;
							}
						 }
					 }
				 }
			 }
			 
		 }
	}
	/*
	 * 生成32位64位 唯一随机数
	 */
//	private void genBoardZobrist(){
//		Random random = new Random();
//		for(int i=0;i"+i);
//						 System.out.println(siteLegBit+" \n  现在位置"+i+siteLegBit.checkSumOfKnight()+" 棋子在->"+i);
//						 System.out.println("=====================================================");
//					 }else {
						 attackBoardBit[i][siteLegBit.checkSumOfKnight()]=siteAttBit;
						 //马的机动性
						 KnightMobility[i][siteLegBit.checkSumOfKnight()]=siteAttBit.Count();
//					 }
				 }else{  //象
//					 if(!attackBoardBit[i][siteLegBit.checkSumOfElephant()].isEmpty()){
//						 System.out.println("========================象=============================");
//						 System.out.println(attackBoardBit[i][siteLegBit.checkSumOfElephant()]+" \n  原位置"+i+attackBoardBit[i][siteLegBit.checkSumOfElephant()].checkSumOfElephant()+" 棋子在->"+i);
//						 System.out.println(siteLegBit+" \n  现在位置"+i+siteLegBit.checkSumOfElephant()+" 棋子在->"+i);
//						 System.out.println("=====================================================");
//					 }else {
						 attackBoardBit[i][siteLegBit.checkSumOfElephant()]=siteAttBit;
//					 }
				 }
				 
			}
		}
	}	
	//数组中去除重复数据
	private  int[] removeRepeatArray(int[] array){
		int[] duplicate=new int[array.length];
		for(int k=0;k0){
					b++;
				}
			}
		}
		return r;
	}
	/**
	 *@author pengjiu 
	 * index : 数组起始位置
	 * a  : 数组
	 * num : 从数组后面拿取几位
	 * 一直拿取到只为0为止
	 */
	private  String[]  computCombination(int index,int[] a,int num){
		String[] value=new String[10];
		int b=0;
		for(int i=index;i0) && j!=site){
					 boolean isEat=false;
					 boolean isHandicap=false;
					 int eatIndex=0;
					 //向左(上)取值
					 for(int n=i+1;n<=num;n++){
						 int _tSite=1< 0) {
							if (isHandicap == false) {
								isHandicap = true;
							} else {
								isEat = true;
								
							}
						} else if (isHandicap) {
							if (direction == 0) {
								moveEat[num - i][j][eatIndex++] = (num - n);
							} else {
								moveEat[num - i][j][eatIndex++] = (num - n) * 9;
							}
						}
					 } 
					 isHandicap=false;
					 isEat=false; 
					 //向右(下)取值
					 for(int n=i-1;n>=0;n--){
						 int _tSite=1<0 ){ 
							 if(isHandicap==false){
								 isHandicap=true;
							 }else{
								 isEat=true;
							 }
							 
						 } else if (isHandicap) {
							 if(direction==0){
								 moveEat[num-i][j][eatIndex++]=(num-n);
							 }else{
								 moveEat[num-i][j][eatIndex++]=(num-n)*9;	 
							 }
						 }
					 }
				 }
			 }
			 
		 }
	}
	public void preInCheck(){
		
	}
	
	private int[][][] cleanEmpty(int[][][] array){
		for(int i=0;i

(2)评估;这里的评估是动态评估,起初可以给马,车,将等设置一个评估分数,但随着时间、位置等的改变对应的分数也需要发生改变,这里将就列出部分评估的代码吧。

package com.pj.chess.evaluate;

import static com.pj.chess.ChessConstant.*;

import com.pj.chess.BitBoard;
import com.pj.chess.ChessConstant;
import com.pj.chess.Tools;
import com.pj.chess.chessparam.ChessParam;

public abstract class  EvaluateCompute {
	protected ChessParam chessParam ;
	public abstract int evaluate(int play);
	public  abstract int chessAttachScore(int chessRole, int chessSite);

	public static int KINGSCORE=3000;
	public static int CHARIOTSCORE=1300;
	public static int KNIGHTSCORE=490;
	public static int GUNSCORE=610;
	public static int ELEPHANTSCORE=200;
	public static int GUARDSCORE=200;
	public static int SOLDIERSCORE=100;
    //棋子基本分数
	public static  final int[] chessBaseScore=new int[]{ 
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		KINGSCORE,CHARIOTSCORE,CHARIOTSCORE,KNIGHTSCORE,KNIGHTSCORE,GUNSCORE,GUNSCORE,ELEPHANTSCORE,ELEPHANTSCORE,GUARDSCORE,GUARDSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE,
		KINGSCORE,CHARIOTSCORE,CHARIOTSCORE,KNIGHTSCORE,KNIGHTSCORE,GUNSCORE,GUNSCORE,ELEPHANTSCORE,ELEPHANTSCORE,GUARDSCORE,GUARDSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE,SOLDIERSCORE
	};
	protected BitBoard getMainAttackChessesBitBoad(int play){
		BitBoard bitBoard=new BitBoard(chessParam.getBitBoardByPlayRole(play,CHARIOT));
		bitBoard=BitBoard.assignXorToNew(chessParam.getBitBoardByPlayRole(play,KNIGHT),bitBoard);
		bitBoard=BitBoard.assignXorToNew(chessParam.getBitBoardByPlayRole(play,GUN),bitBoard);
		return bitBoard;
	}
	protected BitBoard getDefenseChessesBitBoad(int play){
		BitBoard bitBoard=new BitBoard(chessParam.getBitBoardByPlayRole(play,ELEPHANT));
		bitBoard=BitBoard.assignXorToNew(chessParam.getBitBoardByPlayRole(play,GUARD),bitBoard);
		bitBoard=BitBoard.assignXorToNew( chessParam.getBitBoardByPlayRole(play,SOLDIER),bitBoard);
		return bitBoard;
	}
 
	protected int chessMobility(int chessRole, int srcSite,BitBoard bitBoard){
		int mobility=0;
		int row=chessParam.boardBitRow[boardRow[srcSite]];
		int col=chessParam.boardBitCol[boardCol[srcSite]];
		switch (chessRole) {
		//车炮
		case REDCHARIOT:
		case BLACKCHARIOT: 
		case REDGUN:
		case BLACKGUN:
			mobility=ChariotAndGunMobilityRow[srcSite][row]+ChariotAndGunMobilityCol[srcSite][col];
			 break;
	    //马
		case REDKNIGHT:
		case BLACKKNIGHT: 
			BitBoard legBoard = BitBoard.assignAndToNew(KnightLegBitBoards[srcSite],chessParam.maskBoardChesses);
			BitBoard knightAttackSite = KnightBitBoardOfAttackLimit[srcSite][legBoard.checkSumOfKnight()];
			mobility=knightAttackSite.Count()-BitBoard.assignAndToNew(knightAttackSite,bitBoard).Count(); 
			break;
		case REDKING:
		case BLACKKING: 
			BitBoard kingMove = BitBoard.assignAndToNew(KingBitBoard[srcSite],chessParam.maskBoardChesses);
			kingMove.assignXor(KingBitBoard[srcSite]);
			mobility= kingMove.Count();
			break;
		default :
			System.out.println("没有这个棋子:"+srcSite);
		} 
		return mobility;
	}
	protected BitBoard chessAllMove(int chessRole, int srcSite, int play) {
		BitBoard bitBoard=null;
		switch (chessRole) {
		case REDCHARIOT:
		case BLACKCHARIOT:
			int row=chessParam.boardBitRow[boardRow[srcSite]];
			int col=chessParam.boardBitCol[boardCol[srcSite]];
			//取出行列能攻击到的位置
			bitBoard=BitBoard.assignXorToNew(ChariotBitBoardOfAttackRow[srcSite][row], ChariotBitBoardOfAttackCol[srcSite][col]);			
			bitBoard.assignXor(BitBoard.assignXorToNew(MoveChariotOrGunBitBoardRow[srcSite][row], MoveChariotOrGunBitBoardCol[srcSite][col]));
			break;
		case REDKNIGHT:
		case BLACKKNIGHT:
			//取出被别马腿的位置
			BitBoard legBoard = BitBoard.assignAndToNew(KnightLegBitBoards[srcSite],chessParam.maskBoardChesses);
			//能走到的位置
			bitBoard=new BitBoard(KnightBitBoardOfAttackLimit[srcSite][legBoard.checkSumOfKnight()]);
			break;
		case REDGUN:
		case BLACKGUN:
			row=chessParam.boardBitRow[boardRow[srcSite]];
			col=chessParam.boardBitCol[boardCol[srcSite]];
			//取出行列能攻击到的位置
			bitBoard=BitBoard.assignXorToNew(GunBitBoardOfAttackRow[srcSite][row], GunBitBoardOfAttackCol[srcSite][col]);
			//能走到的位置
//			bitBoard=BitBoard.assignXorToNew(MoveChariotOrGunBitBoardRow[srcSite][row], MoveChariotOrGunBitBoardCol[srcSite][col]);
			//炮伪攻击位置
			bitBoard.assignXor(BitBoard.assignXorToNew(GunBitBoardOfFakeAttackRow[srcSite][row], GunBitBoardOfFakeAttackCol[srcSite][col]));
			break;
		case REDELEPHANT:
		case BLACKELEPHANT:
			//取出被塞象眼的位置
			legBoard=BitBoard.assignAndToNew(ElephanLegBitBoards[srcSite],chessParam.maskBoardChesses);
			bitBoard=new BitBoard(ElephanBitBoardOfAttackLimit[srcSite][legBoard.checkSumOfElephant()]);
			break;
		case REDKING:
		case BLACKKING:
			//将能走到的位置
			bitBoard=new BitBoard(KingBitBoard[srcSite]);
			break;
		case REDGUARD:
		case BLACKGUARD:
			bitBoard=new BitBoard(GuardBitBoard[srcSite]);
			break;
		case REDSOLDIER:
		case BLACKSOLDIER:
			bitBoard=new BitBoard(SoldiersBitBoard[play][srcSite]);
			break;
		default :
			System.out.println("没有这个棋子:"+srcSite);
		}
		return bitBoard;
	}
	 
	/**
	 *@author pengjiu  
	 * 功能:空头炮 
	*/
	protected int exposedCannon(int play,int oppkingSite,int row,int col){ 
		BitBoard bitBoard = BitBoard.assignXorToNew( ChariotBitBoardOfAttackRow[oppkingSite][row], ChariotBitBoardOfAttackCol[oppkingSite][col]);
		bitBoard.assignAnd(chessParam.getBitBoardByPlayRole(play, ChessConstant.GUN));
		if (!bitBoard.isEmpty()) {
			return bitBoard.MSB(play) ;
		}
		return -1;
	}
	/**
	 *@author pengjiu  
	 * 功能:沉底炮
	*/
	protected int bottomCannon(int play,int oppkingSite,int row,int col){ 
		BitBoard bitBoard = BitBoard.assignXorToNew( GunBitBoardOfMoreRestAttackRow[oppkingSite][row], GunBitBoardOfMoreRestAttackCol[oppkingSite][col]);
		bitBoard.assignAnd(chessParam.getBitBoardByPlayRole(play, ChessConstant.GUN));
		if (!bitBoard.isEmpty()) {
			return bitBoard.MSB(play) ;
		}
		return -1;
	}
	/**
	 *@author pengjiu  
	 * 功能:隔子车
	*/
	protected int restChariot(int play,int oppkingSite,int row,int col){ 
		BitBoard bitBoard = BitBoard.assignXorToNew( GunBitBoardOfAttackRow[oppkingSite][row], GunBitBoardOfAttackCol[oppkingSite][col]);
		bitBoard.assignAnd(chessParam.getBitBoardByPlayRole(play, ChessConstant.CHARIOT));
		if (!bitBoard.isEmpty()) {
			return bitBoard.MSB(play) ;
		}
		return -1;
	}

	public  void trimPartitionScore(int[][] partitionScore, int[][] attackPartition, int[][] defensePartition) {
		
		attackPartition[REDPLAYSIGN][LEFTSITE] = partitionScore[REDPLAYSIGN][1];
		attackPartition[REDPLAYSIGN][RIGHTSITE] = partitionScore[REDPLAYSIGN][2];
		attackPartition[REDPLAYSIGN][MIDSITE] = partitionScore[REDPLAYSIGN][3];
		defensePartition[REDPLAYSIGN][LEFTSITE] = partitionScore[REDPLAYSIGN][4];
		defensePartition[REDPLAYSIGN][RIGHTSITE] = partitionScore[REDPLAYSIGN][5];
		defensePartition[REDPLAYSIGN][MIDSITE] = partitionScore[REDPLAYSIGN][6];

		
		attackPartition[BLACKPLAYSIGN][LEFTSITE] = partitionScore[BLACKPLAYSIGN][4];
		attackPartition[BLACKPLAYSIGN][RIGHTSITE] = partitionScore[BLACKPLAYSIGN][5];
		attackPartition[BLACKPLAYSIGN][MIDSITE] = partitionScore[BLACKPLAYSIGN][6];
		defensePartition[BLACKPLAYSIGN][LEFTSITE] = partitionScore[BLACKPLAYSIGN][1];
		defensePartition[BLACKPLAYSIGN][RIGHTSITE] = partitionScore[BLACKPLAYSIGN][2];
		defensePartition[BLACKPLAYSIGN][MIDSITE] = partitionScore[BLACKPLAYSIGN][3];

	}
	//攻击区域分数
    static  final int[] attackChessPartitionScore=new int[]{ 
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,
		0,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2
	}; 
	//防守区域分数
    static  final int[] defenseChessPartitionScore=new int[]{ 
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2,
		0,4,4,4,4,4,4,3,3,3,3,2,2,2,2,2
	}; 
    /**
     * 动态调整攻击区域分数
     */
    int redElephantNum ,redGuardNum,blackElephantNum,blackGuardNum,redGun,redKnight,blackGun,blackKnight;
    //单士或单象价值下降
    private static final int[] guarAndElephantNumScore=new int[]{0,2,3};
	 //对手'士'数量决定炮与马的区域价值
    private static final int[] gunNumScoreDependGuard =new int[]{2,3,4};
    private static final int[] knightNumScoreDependGuard =new int[]{5,5,4};
    public  void dynamicCMPChessPartitionScore(){ 
		 redGuardNum = chessParam.getChessesNum(REDPLAYSIGN,ChessConstant.GUARD);
		 redElephantNum = chessParam.getChessesNum(REDPLAYSIGN,ChessConstant.ELEPHANT); 		 
		 blackGuardNum = chessParam.getChessesNum(BLACKPLAYSIGN,ChessConstant.GUARD);
		 blackElephantNum = chessParam.getChessesNum(BLACKPLAYSIGN,ChessConstant.ELEPHANT);
		 //单士或单象价值下降
		 defenseChessPartitionScore[23]=defenseChessPartitionScore[24]=guarAndElephantNumScore[blackElephantNum];
		 defenseChessPartitionScore[25]=defenseChessPartitionScore[26]=guarAndElephantNumScore[blackGuardNum];
		 
		 defenseChessPartitionScore[39]=defenseChessPartitionScore[40]=guarAndElephantNumScore[redElephantNum];
		 defenseChessPartitionScore[41]=defenseChessPartitionScore[42]=guarAndElephantNumScore[redGuardNum];		 
		 
//		 blackGun=(redGuardNum*2)+1; 
//		 blackKnight=(5-redGuardNum);
//		 redGun=(blackGuardNum*2)+1; 
//		 redKnight=(5-blackGuardNum);
		 //动态改变炮与马的攻击价值
		 attackChessPartitionScore[21]=attackChessPartitionScore[22]=gunNumScoreDependGuard[redGuardNum];  
		 attackChessPartitionScore[19]=attackChessPartitionScore[20]=knightNumScoreDependGuard[redGuardNum];
		 attackChessPartitionScore[37]=attackChessPartitionScore[38]=gunNumScoreDependGuard[blackGuardNum];
		 attackChessPartitionScore[35]=attackChessPartitionScore[36]=knightNumScoreDependGuard[blackGuardNum];
    }
//	public static final int KING=7;    //王
//	public static final int CHARIOT=6; //车
//	public static final int KNIGHT=5; //马
//	public static final int GUN=4; //炮
//	public static final int ELEPHANT=3; //象
//	public static final int GUARD=2; //士
//	public static final int SOLDIER=1; //兵
    

	/**区域分数
	 * @param site
	 * @param chess
	 * @param partitionScore
	 */
	public void compPartitionScore(int play,int site,int chess,int[] partitionScore){
		int parSiteTemp=chessRolePartitionSite[chessRoles[chess]][site];
		if(play==REDPLAYSIGN){ //红
			switch(parSiteTemp){
			case 1:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;
			case 2:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;			
			case 3:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;
			case 31:
				partitionScore[3]+=attackChessPartitionScore[chess];
				partitionScore[1]+=attackChessPartitionScore[chess];
				break;
			case 32:
				partitionScore[3]+=attackChessPartitionScore[chess];
				partitionScore[2]+=attackChessPartitionScore[chess];
				break;
			case 33:
				partitionScore[3]+=attackChessPartitionScore[chess];
				partitionScore[2]+=attackChessPartitionScore[chess];
				partitionScore[1]+=attackChessPartitionScore[chess];
				break;
			case 4:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;
			case 5:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;			
			case 6:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;
			case 64:
				partitionScore[6]+=defenseChessPartitionScore[chess];
				partitionScore[4]+=defenseChessPartitionScore[chess];
				break;
			case 65:
				partitionScore[6]+=defenseChessPartitionScore[chess];
				partitionScore[5]+=defenseChessPartitionScore[chess];
				break;
			case 66:
				partitionScore[6]+=defenseChessPartitionScore[chess];
				partitionScore[5]+=defenseChessPartitionScore[chess];
				partitionScore[4]+=defenseChessPartitionScore[chess];
				break;				
			} 
		}else{ //黑
			switch(parSiteTemp){
			case 1:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;
			case 2:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;			
			case 3:
				partitionScore[parSiteTemp]+=defenseChessPartitionScore[chess];
				break;
			case 31:
				partitionScore[3]+=defenseChessPartitionScore[chess];
				partitionScore[1]+=defenseChessPartitionScore[chess];
				break;
			case 32:
				partitionScore[3]+=defenseChessPartitionScore[chess];
				partitionScore[2]+=defenseChessPartitionScore[chess];
				break;
			case 33:
				partitionScore[3]+=defenseChessPartitionScore[chess];
				partitionScore[2]+=defenseChessPartitionScore[chess];
				partitionScore[1]+=defenseChessPartitionScore[chess];
				break;
			case 4:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;
			case 5:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;			
			case 6:
				partitionScore[parSiteTemp]+=attackChessPartitionScore[chess];
				break;
			case 64:
				partitionScore[6]+=attackChessPartitionScore[chess];
				partitionScore[4]+=attackChessPartitionScore[chess];
				break;
			case 65:
				partitionScore[6]+=attackChessPartitionScore[chess];
				partitionScore[5]+=attackChessPartitionScore[chess];
				break;
			case 66:
				partitionScore[6]+=attackChessPartitionScore[chess];
				partitionScore[5]+=attackChessPartitionScore[chess];
				partitionScore[4]+=attackChessPartitionScore[chess];
				break;				
			} 
		}
		
	}
 static int[] ChariotPartitionSite=new int[]{ //车
		      1  ,1  ,1  ,31 ,3 , 32,2  ,2  ,2    
			 ,1  ,1  ,1  ,31 ,33, 32,2  ,2  ,2  
			 ,1  ,1  ,1  ,31 ,33, 32,2  ,2  ,2  
			 ,0  ,0  ,0  ,3  ,3 , 3 ,0  ,0  ,0  
			 ,0  ,0  ,0  ,3  ,3 , 3 ,0  ,0  ,0  
			 
			 ,0  ,0  ,0  ,6 ,6  ,6  ,0  ,0  ,0  
			 ,0  ,0  ,0  ,6 ,6 ,6 ,0  ,0  ,0  
			 ,4  ,4  ,4  ,64,66,65,5  ,5  ,5  
			 ,4  ,4  ,4  ,64,66,65,5  ,5  ,5  
			 ,4  ,4  ,4  ,64,6 ,65,5  ,5  ,5   
  };
	static int[] KnightPartitionSite=new int[]{ //马
	      1  ,1  ,1  ,0  ,0 ,0 ,2  ,2  ,2    
		 ,1  ,1  ,1  ,31,33 ,32,2  ,2  ,2  
		 ,1  ,1  ,1  ,31,33 ,32,2  ,2  ,2  
		 ,0  ,1  ,1  ,31,33 ,32,2  ,2  ,0  
		 ,0  ,0  ,0  ,0  ,0  ,0 ,0  ,0  ,0  
		 
		 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
		 ,0  ,4  ,4  ,64,66,65 ,5  ,5  ,0  
		 ,4  ,4  ,4  ,64,66,65,5  ,5  ,5  
		 ,4  ,4  ,4  ,64,66,65,5  ,5  ,5  
		 ,4  ,4  ,4  ,0 ,0 ,0 ,5  ,5  ,5   
};
static int[] GunPartitionSite=new int[]{ //炮
	      1  ,1  ,1  ,0 ,0 ,0 ,2 ,2  ,2    
		 ,1  ,1  ,1  ,0 ,0 ,0 ,2 ,2  ,2  
		 ,1  ,1  ,1  ,0 ,3 ,0 ,2 ,2  ,2  
		 ,0  ,0  ,0  ,32,33,32,0 ,0  ,0  
		 ,0  ,0  ,0  ,0 ,0 ,0 ,0 ,0  ,0  
		 
		 ,0  ,0  ,0  ,0  ,0  ,0 ,0  ,0  ,0  
		 ,0  ,0  ,0  ,64 ,66 ,65,0  ,0  ,0    
		 ,4  ,4  ,4  ,0  ,6  ,0 ,5  ,5  ,5  
		 ,4  ,4  ,4  ,0  ,0  ,0 ,5  ,5  ,5  
		 ,4  ,4  ,4  ,0  ,0  ,0 ,5  ,5  ,5   
};
static int[] SoldierPartitionSite=new int[]{ //卒
      0  ,0  ,0  ,3  ,3 ,3  ,0  ,0  ,0    
	 ,0  ,0  ,0  ,3  ,3 ,3  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,3  ,3 ,3  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0 ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0 ,0  ,0  ,0  ,0  
	 
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,6  ,6  ,6  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,6  ,6  ,6  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,6  ,6  ,6  ,0  ,0  ,0     
};
static int[] DefensePartitionSite=new int[]{ //象士
      1  ,1  ,1  ,31 ,33,32 ,2  ,2  ,2    
	 ,1  ,1  ,1  ,31 ,33,32 ,2  ,2  ,2  
	 ,1  ,1  ,1  ,31 ,33,32 ,2  ,2  ,2  
	 ,1  ,1  ,1  ,31 ,3 ,32 ,2  ,2  ,2  
	 ,1  ,1  ,1  ,31 ,3 ,32 ,2  ,2  ,2   
	 
	 ,4  ,4  ,4  ,64 ,6  ,65 ,5  ,5  ,5   
	 ,4  ,4  ,4  ,64 ,6  ,65 ,5  ,5  ,5  
	 ,4  ,4  ,4  ,64 ,66 ,65 ,5  ,5  ,5  
	 ,4  ,4  ,4  ,64 ,66 ,65 ,5  ,5  ,5  
	 ,4  ,4  , 4 ,64 ,66 ,65 ,5  ,5  ,5   
};
static int[]KingPartitionSite=new int[]{ //王
	  0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
	 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0     
};
static final int[][] chessRolePartitionSite=new int[][]{ 
	{},SoldierPartitionSite,DefensePartitionSite,DefensePartitionSite,GunPartitionSite,KnightPartitionSite,ChariotPartitionSite,KingPartitionSite
	  ,SoldierPartitionSite,DefensePartitionSite,DefensePartitionSite,GunPartitionSite,KnightPartitionSite,ChariotPartitionSite,KingPartitionSite
};
	protected final static BitBoard[][] AttackDirection= new BitBoard[2][3];
	protected final static BitBoard[][] DefenseDirection= new BitBoard[2][3];
	protected final static int LEFTSITE=0,RIGHTSITE=1,MIDSITE=2,OTHERSITE=3;
	static{
		int[] AttackRedLeftSite=new int[]{
				      1  ,1  ,1  ,1  ,1  ,0  ,0  ,0  ,0    
					 ,1  ,1  ,1  ,1  ,1  ,0  ,0  ,0  ,0  
					 ,1  ,1  ,1  ,1  ,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   
		};
		int[] AttackRightSite=new int[]{
				  0  ,0  ,0  ,0  ,2  ,2  ,2  ,2  ,2  
				 ,0  ,0  ,0  ,0  ,2  ,2  ,2  ,2  ,2  
				 ,0  ,0  ,0  ,0  ,2  ,2  ,2  ,2  ,2  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0 
				 
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0   
	   };
		int[] AtackRedMidSite=new int[]{
				  0  ,0  ,0  ,3  ,3  ,3  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,3  ,3  ,3  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,3  ,3  ,3  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,3  ,3  ,3  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0   
				 
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  
				 ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0   
	  };
	  int[] AttackBlackLeftSite=Tools.exchange(AttackRedLeftSite); 
	  int[] AttackBlackRightSite=Tools.exchange(AttackRightSite);
	  int[] AttackBlackMidSite=Tools.exchange(AtackRedMidSite); 
	  
	  BitBoard AttackBlackLeftBit = new BitBoard(AttackBlackLeftSite);
	  BitBoard AttackBlackRightBit = new BitBoard(AttackBlackRightSite); 
	  BitBoard AttackBlackMidBit = new BitBoard(AttackBlackMidSite); 
	  BitBoard AttackRedLeftBit = new BitBoard(AttackRedLeftSite); 
	  BitBoard AttackRedRightBit = new BitBoard(AttackRightSite); 
	  BitBoard AttackRedMidBit = new BitBoard(AtackRedMidSite); 	  
	  
	  AttackDirection[REDPLAYSIGN][LEFTSITE]=AttackRedLeftBit;
	  AttackDirection[REDPLAYSIGN][RIGHTSITE]=AttackRedRightBit;
	  AttackDirection[REDPLAYSIGN][MIDSITE]=AttackRedMidBit;
	  
	  AttackDirection[BLACKPLAYSIGN][LEFTSITE]=AttackBlackLeftBit;
	  AttackDirection[BLACKPLAYSIGN][RIGHTSITE]=AttackBlackRightBit;
	  AttackDirection[BLACKPLAYSIGN][MIDSITE]=AttackBlackMidBit;
	  
	  
	  DefenseDirection[BLACKPLAYSIGN][LEFTSITE]=AttackRedLeftBit;
	  DefenseDirection[BLACKPLAYSIGN][RIGHTSITE]=AttackRedRightBit;
	  DefenseDirection[BLACKPLAYSIGN][MIDSITE]=AttackRedMidBit;
	  
	  DefenseDirection[REDPLAYSIGN][LEFTSITE]=AttackBlackLeftBit;
	  DefenseDirection[REDPLAYSIGN][RIGHTSITE]=AttackBlackRightBit;
	  DefenseDirection[REDPLAYSIGN][MIDSITE]=AttackBlackMidBit;	 
	  
	}
	
}

由于这个项目篇幅较大,放上来极不方便,故有需要的同学可以叫我微信:18476275715(永久有效)

你可能感兴趣的:(java)