AI中國象棋(附詳細解釋和源碼)


需要完整AI象棋的同學可以加微信15813406574

AI中國象棋核心就是:博弈;引申為:在一定的條件下,遵守一定的規則,一個或幾個擁有絕對理想思維的團隊,從各自允許選擇的行為或策略經行選擇並加以實施。

博弈問題一般有三個要素:局中人,規則,策略這里的三個要素分別對應象棋中的棋手、象棋規則以及棋術,有五個方面的內容:第一,博弈的參加者,即博弈過程中獨立決策,獨立承擔后果的個人或者組織(本文局中人是棋手);第二,博弈信息,即博弈者所掌握的對選擇策略有幫助的情報資料(本文就是兩位棋手都知道對面的走的棋,因為棋盤都是公開透明);第三:博弈方可選擇的全部行為或策略的集合(中國象棋每一步有50-70種走法,而平均30+回合即可決出勝負);第四:博弈的次序,即博弈參加者做出策略選擇的先后(通俗點就是棋手是馬吃炮,還是車吃馬之間的選擇);第五:博弈方的收益,即各博弈方做出的決策選擇后的所得和所示(棋手最后是贏了還是輸了或者平局)。

下面我們結合結果以及代碼給大家進行詳細解釋:
​       ​  

評價一個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;i<boardTemp.length;i++){
            if(boardTemp[i]>0){
                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;i<bitBoard.length;i++){
            bitBoard[i]=new BitBoard(KnightLegBitBoards[i]);
            if(bitBoard[i].Count()==4){
                if(i<45){
                    bitBoard[i].assignXor(new BitBoard(i-9));
                }else{
                    bitBoard[i].assignXor(new BitBoard(i+9));
                }
            }
        }
    }
    /**
     * 初始馬的着法預生成數組
     */
    private  void initKnightMove(){
        int[] cnKnightMoveTab=new int[]{-0x21, -0x1f, -0x12, -0x0e, +0x0e, +0x12, +0x1f, +0x21}; 
        int[] cnHorseLegTab=new int[]{-0x10, -0x10, -0x01, +0x01, -0x01, +0x01, +0x10, +0x10};
        for(int site=0;site<255;site++){ 
            if(isBoardTo255(site)){ 
                int z=0;
                 for(int j=0;j<cnKnightMoveTab.length;j++){
                     int _tKnight=site+cnKnightMoveTab[j];
                     int _tHorseLeg=site+cnHorseLegTab[j];
                     if(isBoardTo255(_tKnight) && isBoardTo255(_tHorseLeg)){ 
                         int siteTo90=boardMap[site];
                         int _tKnightTo90=boardMap[_tKnight];
                         int _tHorseLegTo90=boardMap[_tHorseLeg];
                         knightMove[siteTo90][z]=_tKnightTo90;
                         horseLeg[siteTo90][z]=_tHorseLegTo90;                          
                         z++;
                         if(KnightBitBoards[siteTo90]==null){
                             KnightBitBoards[siteTo90]=new BitBoard();
                         }
                         if(KnightLegBitBoards[siteTo90]==null){
                             KnightLegBitBoards[siteTo90]=new BitBoard();
                         }
                         //馬的位棋盤
                         KnightBitBoards[siteTo90].assignOr(new BitBoard(_tKnightTo90));
                         KnightLegBitBoards[siteTo90].assignOr(new BitBoard(_tHorseLegTo90));
                         
                     }
                 }
            }
        }  
        
    }
    /**
     * 初始象的着法預生成數組
     */
    public void initElephantMove(){
        int[] cnElephantMoveTab=new int[]{-0x22, -0x1e,+0x1e, +0x22}; 
        int[] cnElephantLegTab=new int[]{-0x11, -0xf,+0xf, +0x11};
        for(int site=0;site<255;site++){ 
            if(isBoardTo255(site)){ 
                int z=0;
                int[] _tElephantMoveTab=cnElephantMoveTab;
                int[] _tElephantLegTab=cnElephantLegTab;
                //黑象到達楚漢邊界重置其着法表不允許地河
                if(site/16==7 || site/16==6){  
                     _tElephantMoveTab=new int[]{-0x22, -0x1e}; 
                     _tElephantLegTab=new int[]{-0x11, -0xf};
                 //紅象到達楚漢邊界重置其着法表不允許地河                     
                 }else if(site/16==8 || site/16==9){
                     _tElephantMoveTab=new int[]{+0x1e, +0x22}; 
                     _tElephantLegTab=new int[]{+0xf, +0x11};
                 }
                 for(int j=0;j<_tElephantMoveTab.length;j++){
                     
                     int _tElephant=site+_tElephantMoveTab[j];
                     int _tElephantLeg=site+_tElephantLegTab[j];
                     
                     if(isBoardTo255(_tElephant) && isBoardTo255(_tElephantLeg)){
                         
                         int siteTo90=boardMap[site];
                         int _tElephant_90=boardMap[_tElephant];
                         int _tElephantLeg_90=boardMap[_tElephantLeg];
                         
                         elephantMove[siteTo90][z]=_tElephant_90;
                         elephantLeg[siteTo90][z]=_tElephantLeg_90;
                         
                         if(ElephanLegBitBoards[siteTo90]==null){
                             ElephanLegBitBoards[siteTo90]=new BitBoard();
                         }
                         //象被塞眼的位棋盤
                         ElephanLegBitBoards[siteTo90].assignXor(MaskChesses[_tElephantLeg_90]);
                         z++;
                     }
                 }
            }
        }  
    }
    /**
     * 初始兵的着法預生成數組
     */
    private void initSoldier() { 
        int[] _tSoldierMoveTab = null;
        for (int i = 0; i < soldierMove.length; i++)
            for (int site = 0; site < 255; site++) {
                if (isBoardTo255(site)) {
                    int z = 0;
                    if(i==BLACKPLAYSIGN){
                        //黑方兵以經過界
                        if (site/16 >7) {
                            _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<<i;//所在位置
             for(int j=0;j<=sort;j++){
                 if(((j & site)>0)){
                     if(isEat && j==site){ //吃子自己不能算進去
                         continue;
                     }
                     int isHandicap=0;
                     int eatIndex=0;
                     //向左(上)取值
                     for(int n=i+1;n<=num;n++){
                        int _tSite=1<<n;
                        if (isEat) {
                            if((j & _tSite) > 0){ 
                                if (isHandicap <handicapNum) {
                                    isHandicap ++;
                                } else {
                                    if (direction == 0) {
                                        moveEat[num - i][j][eatIndex++] = (num - n);
                                    } else {
                                        moveEat[num - i][j][eatIndex++] = (num - n) * 9;
                                    }
                                    break;
                                }
                            }
                        }else{
                            if((j & _tSite)==0 ){
                                 if(direction==0){
                                     moveEat[num-i][j][eatIndex++]=(num-n);
                                 }else{
                                     moveEat[num-i][j][eatIndex++]=(num-n)*9;
                                 }
                            }else if((j & _tSite)>0 ){
                                break;
                            }
                         }
                     } 
                     isHandicap=0; 
                     //向右(下)取值
                     for(int n=i-1;n>=0;n--){
                         int _tSite=1<<n;
                         if (isEat) {
                             if((j & _tSite)>0 ){ 
                                 if(isHandicap<handicapNum){
                                     isHandicap++;
                                 }else{
                                     if(direction==0){
                                         moveEat[num-i][j][eatIndex++]=(num-n);
                                     }else{
                                         moveEat[num-i][j][eatIndex++]=(num-n)*9;     
                                     }
                                     break;
                                 }
                                 
                             } 
                         }else{
                            if((j & _tSite)==0 ){
                                 if(direction==0){
                                     moveEat[num-i][j][eatIndex++]=(num-n);
                                 }else{
                                     moveEat[num-i][j][eatIndex++]=(num-n)*9;
                                 }
                            }else if((j & _tSite)>0 ){
                                break;
                            }
                         }
                     }
                 }
             }
             
         }
    }
    /*
     * 生成32位64位 唯一隨機數
     */
//    private void genBoardZobrist(){
//        Random random = new Random();
//        for(int i=0;i<ChessZobristList64.length;i++){
//            for(int j=0;j<ChessZobristList64[i].length;j++){
//                    ChessZobristList64[i][j]=Math.abs((random.nextLong()<<15)^(random.nextLong()<<30)^(random.nextLong()<<45)^(random.nextLong()<<60));
//                    ChessZobristList32[i][j]= Math.abs((random.nextInt()<<15)^(random.nextInt()<<30));
//            }
//        }
//    }
 
    
    private void initChessBaseScoreAndNum(ChessParam chessParamCont){
 
        int[] allChess = chessParamCont.allChess;
        int[] board = chessParamCont.board;
        
        for (int i = 16; i < allChess.length; i++) {
            if(allChess[i]!=NOTHING){
                int site=allChess[i];
                int chessRole = chessRoles[board[allChess[i]]];
                int play=i < 32?BLACKPLAYSIGN:REDPLAYSIGN;
                chessParamCont.increaseChessesNum(chessRole);
//                chessParamCont.baseScore[play]+=EvaluateComputeMiddle.chessBaseScore[i];
//                chessParamCont.baseScore[play]+=new EvaluateComputeMiddle(chessParamCont).chessAttachScore(chessRole,allChess[i]);
                chessParamCont.maskBoardChesses.assignXor(MaskChesses[site]);
                chessParamCont.maskBoardPersonalChesses[play].assignXor(MaskChesses[site]);
                chessParamCont.maskBoardPersonalRoleChesses[chessRole].assignXor(MaskChesses[site]);
            }
        } 
        
    }
    /**
     *@author pengjiu 
     *@date:Aug 26, 2011 5:09:07 PM
     * 功能: 生成馬 and 象 不別腿所能攻擊到的位置
     *@param attackBoard  預生成攻擊位置
     *@param leg  攻擊時的別腿位置
     *@param attackBoardBit 最終返回的數據
     *@param type 0 為馬  1為象
    */
    private  void preBitBoardAttack(int[][] attackBoard,int[][]leg,BitBoard[][] attackBoardBit,int type){ 
        for(int i=0;i<ChessConstant.BOARDSIZE90;i++){ 
            //所有別腿去重復后的數組
            int[] legSite=removeRepeatArray(leg[i]);
            //得到此別腿的所有組合情況 KnightBitBoardOfAttackLimit
            int[][] legSiteComb=getAllLegCombByLeg(legSite);
            for(int k=0;k<legSiteComb.length;k++){
                 if(legSiteComb[k][0]==ChessConstant.NOTHING){
                     break;
                 }
                 BitBoard siteAttBit=new BitBoard();
                 BitBoard siteLegBit=new BitBoard();
                 int[] legTemp=leg[i];
                 for(int n=0;n<legTemp.length && legTemp[n]!=ChessConstant.NOTHING;n++){
                     boolean isExists=false;
                     for(int j=0;j<legSiteComb[k].length&&legSiteComb[k][j]!=ChessConstant.NOTHING;j++){
                         //把組合中在legTemp存在的
                          if(legTemp[n]==legSiteComb[k][j]){
                              isExists=true;break;
                          }
                     }
                     //設置別腿
                     if(!isExists){ 
                         if(attackBoard[i][n]!=ChessConstant.NOTHING){
                             siteLegBit.assignOr(MaskChesses[legTemp[n]]); 
                         }
                     }
                     //設置不別腿能走到的位置
                     if(isExists){//在組合中不存在 寫入位棋盤
                         if(attackBoard[i][n]!=ChessConstant.NOTHING){
                             siteAttBit.assignXor(MaskChesses[attackBoard[i][n]]);
                         }
                     }
                 }
                 if(type==0){ ////                     if(!attackBoardBit[i][siteLegBit.checkSumOfKnight()].isEmpty()){
//                         System.out.println("==========================馬===========================");
//                         System.out.println(attackBoardBit[i][siteLegBit.checkSumOfKnight()]+" \n  原位置"+i+attackBoardBit[i][siteLegBit.checkSumOfKnight()].checkSumOfKnight()+" 棋子在->"+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;k<duplicate.length;k++){
            duplicate[k]=-1;
        }
        for(int i=0;i<array.length;i++){
            if(array[i]==ChessConstant.NOTHING){
                break;
            }
            for(int z=0;z<duplicate.length;z++){
                if(duplicate[z]==array[i]){
                    break;
                }else if(duplicate[z]==ChessConstant.NOTHING){
                    duplicate[z]=array[i];
                    break;
                }
            }
        }
        return duplicate;
    }
    /*
     * 所有別腿的組合
     */
    private  int[][] getAllLegCombByLeg(int legs[]){
        int r[][]=new int[20][4];
        for(int i=0;i<r.length;i++ ){
            for(int j=0;j<r[i].length;j++ ){
                r[i][j]=ChessConstant.NOTHING;
            }
        }
        for(int i=0,b=0;i<legs.length&&legs[i]!=ChessConstant.NOTHING;i++){
            String[] result=computCombination(0,legs,i+1);
            for(int j=0;j<result.length && result[j]!=null;j++){
                String[] siteStr=result[j].split(",");
                for(int m=0;m<siteStr.length;m++){
                    r[b][m]=Integer.valueOf(siteStr[m]);
                }
                if(siteStr.length>0){
                    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;i<a.length&&a[i]!=ChessConstant.NOTHING;i++){
            if(num==1){
                value[b++]=a[i]+"";
            }else{
                String[] r=computCombination(i+1,a,num-1);
                for(int j=0;j<r.length&&r[j]!=null;j++){
                    value[b++]=a[i]+","+r[j];
                }
            }
        }
        return value;
    }
    /**
     *@author pengjiu 
     *@date:Sep 1, 2011 12:43:05 PM
     * 功能: 車炮機動性能預生成
     *@param moveSite
     *@param mobility
    */
    private void preGunAndChariotMobility(BitBoard[][] moveSite,int[][] mobility){
        for(int i=0;i<moveSite.length;i++){
            for(int j=0;j<moveSite[i].length;j++){
                if(moveSite[i][j]!=null){
//                    System.out.println(moveSite[i][j].Count());
                    mobility[i][j]=moveSite[i][j].Count();
                }
                    
            }
        }
    }
    /** @author pengjiu 
     * @param moveSite 需要從之前預生成着法中遍歷所有可行着法用來生成位棋盤
     * @param bitBoard 生成后賦值的位棋盤
     * @param type 0行  1 列
     */
    private void preGunAndChariotBitBoardAttack(int[][][] moveSite,BitBoard[][] bitBoard,int type){
        
        for(int i=0;i<BOARDSIZE90;i++){
            int row = boardRow[i];
            int col = boardCol[i];
            //moveSite[rowOrCol][行or列的二進制狀態][能移動到的位置]
            int rowOrCol=0; 
            int[][] moveSiteTemp=null;
            if(type==0){ //
                rowOrCol=row;
                //因為一行上面要知道他所在的位置所以放入當前棋子所在的一行中的哪一列
                moveSiteTemp=moveSite[col];
            }else{  //
                rowOrCol=col;
                moveSiteTemp=moveSite[row];
            }
            for(int j=0;j<moveSiteTemp.length;j++){
                bitBoard[i][j]=new BitBoard();
                for(int k=0;k<moveSiteTemp[j].length &&moveSiteTemp[j][k]!=NOTHING ;k++){
                    int site=0;
                    if(type==0){ //
                        site=moveSiteTemp[j][k]+rowOrCol*9;
                    }else{  //
                        site=moveSiteTemp[j][k]+rowOrCol;
                    }
                    bitBoard[i][j].assignXor(MaskChesses[site]);
                }    
            }    
        }
        
    }
    /**
     *@author pengjiu 
     *@date:Aug 29, 2011 12:17:14 PM
     * 功能: 將的位棋盤生成
     *@param bitBoard
    */
    public void preBitBoardKingMove(BitBoard[] bitBoard){
        for(int i=0;i<BOARDSIZE90;i++){
            int[] _tMove=null;
            int srcSite=i;
            switch (srcSite) { 
            case 3:
                _tMove=new int[]{4,12};
                break;            
            case 4:
                _tMove=new int[]{3,13,5};
                break; 
            case 5:
                _tMove=new int[]{4,14};
                break; 
            case 12:
                _tMove=new int[]{3,13,21};
                break;
            case 13:
                _tMove=new int[]{12,4,14,22};
                break; 
            case 14:
                _tMove=new int[]{5,13,23};
                break;
            case 21:
                _tMove=new int[]{12,22};
                break;    
            case 22:
                _tMove=new int[]{21,13,23};
                break;
            case 23:
                _tMove=new int[]{22,14};
                break;  
            case 84:
                _tMove=new int[]{75,85};
                break;            
            case 85:
                _tMove=new int[]{84,76,86};
                break; 
            case 86:
                _tMove=new int[]{85,77};
                break;
            case 75:
                _tMove=new int[]{66,84,76};
                break; 
            case 76:
                _tMove=new int[]{85,75,77,67};
                break;
            case 77:
                _tMove=new int[]{76,68,86};
                break;    
            case 66:
                _tMove=new int[]{75,67};
                break;
            case 67:
                _tMove=new int[]{66,76,68};
                break;
            case 68:
                _tMove=new int[]{67,77};
                break;                 
            }  
            if(_tMove!=null){
                bitBoard[i]=new BitBoard();
                for(int j=0;j<_tMove.length;j++){
                    bitBoard[i].assignXor(MaskChesses[_tMove[j]]);
                }
            }
        }
    }
    /**
     *@author pengjiu 
     *@date:Aug 29, 2011 12:25:50 PM
     * 功能:士位棋盤
     *@param bitBoard
    */
    public void preBitBoardGuardMove(BitBoard[] bitBoard){
        for(int i=0;i<bitBoard.length;i++){
            int[] _tMove=null;
            int srcSite=i;
            switch (srcSite) { 
            case 3:
                _tMove=new int[]{13}; 
                break;
            case 5:
                _tMove=new int[]{13};
                break;
            case 13:
                _tMove=new int[]{3,5,21,23}; 
                break;
            case 21:
                _tMove=new int[]{13}; 
                break; 
            case 23:
                _tMove=new int[]{13}; 
                break; 
            case 84:
                _tMove=new int[]{76}; 
                break;
            case 86:
                _tMove=new int[]{76};
                break;
            case 76:
                _tMove=new int[]{66,68,84,86}; 
                break;
            case 66:
                _tMove=new int[]{76};
                break;
            case 68:
                _tMove=new int[]{76};
                break;             
            }  
            if(_tMove!=null){
                bitBoard[i]=new BitBoard();
                for(int j=0;j<_tMove.length;j++){
                    bitBoard[i].assignXor(MaskChesses[_tMove[j]]);
                }
            }
        }
    }
    
    /**初始炮能攻擊到的位置
     * @param moveEat
     * @param direction
     */
    private  void initGunFackEatMove(int [][][] moveEat,int direction){
        int num=moveEat.length-1;
        int sort=moveEat[0].length;
         for(int i=0;i<=num;i++){
             int site=1<<i;//所在位置
             for(int j=0;j<=sort;j++){
                 if(((j & site)>0) && j!=site){
                     boolean isEat=false;
                     boolean isHandicap=false;
                     int eatIndex=0;
                     //向左(上)取值
                     for(int n=i+1;n<=num;n++){
                         int _tSite=1<<n;
                         if(isEat){
                             break;
                         }
                        if ((j & _tSite) > 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<<n;
                         if(isEat){
                             break;
                         }
                         if((j & _tSite)>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<array.length;i++){
            for(int j=0;j<array[i].length;j++){
                for(int k=0;k<array[i][j].length;k++){
                    array[i][j][k]=-1;
                }
            }
        }
        return array;
    }
    public int[][] cleanEmpty(int[][] array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array[i].length;j++){
                    array[i][j]=-1;
            }
        }
        return array;
    }
    public int[] cleanEmpty(int[] array){
            for (int j = 0; j < array.length; j++) {
            array[j] = -1;
        }
        return array;
    }
    public BitBoard[][] initBitBoard(BitBoard[][] array){
        for(int i=0;i<array.length;i++){
            for(int j=0;j<array[i].length;j++){
                    array[i][j]=new BitBoard();
            }
        }
        return array;
    }
    public BitBoard[] initBitBoard(BitBoard[] array){
        for(int i=0;i<array.length;i++){
                array[i]=new BitBoard();
        }
        return array;
    }

    public static void main(String[] args) {
    }
} 

 

(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;     
      
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM