需要一些关于如何实现评估功能的想法

时间:2014-07-13 07:06:15

标签: java artificial-intelligence chess

我正在制作一个国际象棋游戏,现在正试图实现一个minimax算法,该算法使用一个方块表和一个Piece值来计算得分。我已经能够创建以下显示的方法,但不知道如何在 CalculateScore() evaluatePieceScore ()方法中计算得分。拜托,我真的很困惑,需要帮助。

1)getPieceValue()此方法返回分配给每个棋子的常量值 2)getScoreForPiecePosition()获得指定位置的评估奖励 3)CalculateScore()使用方块表计算并返回分数。 4)evaluatePieceScore()将CalculateScore()的计算得分加到原始得分上,具体取决于轮到谁了。

public class MinimaxPlayer implements IPlayerHandler, EvaluationAlgorithm{

private Game chessgame;
private MoveChecker checker;
private BoardGUI boardgui;

private static int maxDepth = 2;

public MinimaxPlayer(Game chessgame){
    this.chessgame = chessgame;
    this.checker = chessgame.getMoveChecker();
    this.boardgui = new BoardGUI(chessgame);
}

@Override
public int getPieceValue(int type) {
    switch(type){
    case Piece.TYPE_PAWN: return 100;
    case Piece.TYPE_KNIGHT: return 320;
    case Piece.TYPE_BISHOP: return 325;
    case Piece.TYPE_ROOK: return 500;
    case Piece.TYPE_QUEEN: return 975;
    case Piece.TYPE_KING: return 32767;
    default: throw new IllegalArgumentException("Unknown piece type: "+ type);
    }
}



@Override
public int evaluatePieceScore() {
    int scoreBrown = 0;
    int scoreYellow = 0;
    for (Piece piece : this.chessgame.getPieces()) {
        if(piece.getColor() == Piece.BROWN_COLOR){
            scoreBrown +=
                getScoreForPieceType(piece.getType());
            scoreBrown +=
                getScoreForPiecePosition(piece.getRow(),piece.getColumn());
        }else if( piece.getColor() == Piece.YELLOW_COLOR){
            scoreYellow +=
                getScoreForPieceType(piece.getType());
            scoreYellow +=
                getScoreForPiecePosition(piece.getRow(),piece.getColumn());
        }else{
            throw new IllegalStateException(
                    "unknown piece color found: "+piece.getColor());
        }
    }

    // return evaluation result depending on who's turn it is
    int gameState = this.chessgame.getGameState();

    if( gameState == Game.GAME_STATE_BROWN){
        return scoreBrwon - scoreYellow;

    }else if(gameState == Game.GAME_STATE_YELLOW){
        return scoreYellow - scoreBrown;

    }else if(gameState == Game.GAME_STATE_END_YELLOW_WON
            || gameState == Game.GAME_STATE_END_BROWN_WON){
        return Integer.MIN_VALUE + 1;

    }else{
        throw new IllegalStateException("unknown game state: "+gameState);
    }
}

public int CalculateScore(int index, int pieceValue, int[] SquareTable ){
    int score = pieceValue;

    for(int i = 0; i < SquareTable.length; i++){
        score += getPieceValue(index.get(SquareTable[i]));

    }

    return 0;
}

@Override
public int getScoreForPiecePosition(int row, int column) {
    byte[][] positionWeight =
    { {1,1,1,1,1,1,1,1}
     ,{2,2,2,2,2,2,2,2}
     ,{2,2,3,3,3,3,2,2}
     ,{2,2,3,4,4,3,2,2}
     ,{2,2,3,4,4,3,2,2}
     ,{2,2,3,3,3,3,2,2}
     ,{2,2,2,2,2,2,2,2}
     ,{1,1,1,1,1,1,1,1}
     };
    return positionWeight[row][column];
}



private static int[] PawnSquareTable = new int[]
{
    0,  0,  0,  0,  0,  0,  0,  0,
    50, 50, 50, 50, 50, 50, 50, 50,
    10, 10, 20, 30, 30, 20, 10, 10,
     5,  5, 10, 25, 25, 10,  5,  5,
     0,  0,  0, 20, 20,  0,  0,  0,
     5, -5,-10,  0,  0,-10, -5,  5,
     5, 10, 10,-20,-20, 10, 10,  5,
     0,  0,  0,  0,  0,  0,  0,  0
};


private static int[] KnightSquareTable = new int[]
{
    -50,-40,-30,-30,-30,-30,-40,-50,
    -40,-20,  0,  0,  0,  0,-20,-40,
    -30,  0, 10, 15, 15, 10,  0,-30,
    -30,  5, 15, 20, 20, 15,  5,-30,
    -30,  0, 15, 20, 20, 15,  0,-30,
    -30,  5, 10, 15, 15, 10,  5,-30,
    -40,-20,  0,  5,  5,  0,-20,-40,
    -50,-40,-30,-30,-30,-30,-40,-50,
};


private static int[] BishopSquareTable = new int[]
{
    -20,-10,-10,-10,-10,-10,-10,-20,
    -10,  0,  0,  0,  0,  0,  0,-10,
    -10,  0,  5, 10, 10,  5,  0,-10,
    -10,  5,  5, 10, 10,  5,  5,-10,
    -10,  0, 10, 10, 10, 10,  0,-10,
    -10, 10, 10, 10, 10, 10, 10,-10,
    -10,  5,  0,  0,  0,  0,  5,-10,
    -20,-10,-10,-10,-10,-10,-10,-20,
};

    private static int[] RookSquareTable = new int[]
{
    0,  0,  0,  0,  0,  0,  0,  0,
    5, 10, 10, 10, 10, 10, 10,  5,
   -5,  0,  0,  0,  0,  0,  0, -5,
   -5,  0,  0,  0,  0,  0,  0, -5,
   -5,  0,  0,  0,  0,  0,  0, -5,
   -5,  0,  0,  0,  0,  0,  0, -5,
   -5,  0,  0,  0,  0,  0,  0, -5,
    0,  0,  0,  5,  5,  0,  0,  0,
};

    private static int[] QueenSquareTable = new int[]
{
    -20,-10,-10, -5, -5,-10,-10,-20,
    -10,  0,  0,  0,  0,  0,  0,-10,
    -10,  0,  5,  5,  5,  5,  0,-10,
     -5,  0,  5,  5,  5,  5,  0, -5,
      0,  0,  5,  5,  5,  5,  0, -5,
    -10,  5,  5,  5,  5,  5,  0,-10,
    -10,  0,  5,  0,  0,  0,  0,-10,
    -20,-10,-10, -5, -5,-10,-10,-20,
};


private static int[] KingMiddleGameSquareTable = new int[]
{
    -30,-40,-40,-50,-50,-40,-40,-30,
    -30,-40,-40,-50,-50,-40,-40,-30,
    -30,-40,-40,-50,-50,-40,-40,-30,
    -30,-40,-40,-50,-50,-40,-40,-30,
    -20,-30,-30,-40,-40,-30,-30,-20,
    -10,-20,-20,-20,-20,-20,-20,-10,
     20, 20,  0,  0,  0,  0, 20, 20,
     20, 30, 10,  0,  0, 10, 30, 20,
};


private static int[] KingEndGameSquareTable = new int[]
{
    -50,-40,-30,-20,-20,-30,-40,-50,
    -30,-20,-10,  0,  0,-10,-20,-30,
    -30,-10, 20, 30, 30, 20,-10,-30,
    -30,-10, 30, 40, 40, 30,-10,-30,
    -30,-10, 30, 40, 40, 30,-10,-30,
    -30,-10, 20, 30, 30, 20,-10,-30,
    -30,-30,  0,  0,  0,  0,-30,-30,
    -50,-30,-30,-30,-30,-30,-30,-50,
};


public static int[] reverse(int[] arr){
    ArrayUtils.reverse(arr);
    return arr;
}

}

2 个答案:

答案 0 :(得分:1)

如果你感到困惑,我会建议从一个简单的评估功能入手,只考虑棋子的价值(一个棋子为1分,一个主教和一个骑士为3分,一个车为5分,9分)对于一个女王和一个国王的很多积分,让我们说200)

然后你的功能变为:

    public int calculateScore()
    {
        return blackPlayer.getMaterial() - whitePlayer.getMaterial()
    }

函数 getMaterial()将是所有作品点的总和。

示例:黑色有1个棋子,1个女王和1个国王,然后blackPlayer.getMaterial()将返回= 1 + 9 + 200 = 210

如果你想把这件作品的位置考虑到评估函数中,你可以这样做:

    public int calculateScore()
    {
        int blackScore = blackPlayer.getMaterial() + blackPlayer.getBonusPosition();
        int whiteScore = whitePlayer.getMaterial() + whitePlayer.getBonusPosition();
        return blackScore - whiteScore; 
    }

函数 getBonusPosition()将返回所有作品的所有奖励位置总和的总和:

示例:blackPlayer在位置(0,0)有1个pawn,在位置(0,1)有1个皇后,在位置(2,2)有1个国王:

  • 在(0,0)处的兵的奖励位置是 0
  • 女王在(0,1)的奖励位置 -10
  • 国王(在最后阶段)在(2,2)的奖金位置是 -20

blackPlayer.getBonusPosition()将返回= 0 - 10 -20 = -30

您可以更改系数,以更加重视材料价值或板上的位置。例如,在之前的例子中,与材料评分相比,职位评分非常重要。

示例:您希望对材料价值给予更多重要性(比如说多10倍)并且您并不真正关心棋盘上棋子的位置,那么您的新计算分数功能将是:

    public int calculateScore()
    {
        int blackScore = 10*blackPlayer.getMaterial() + blackPlayer.getBonusPosition();
        int whiteScore = 10*whitePlayer.getMaterial() + whitePlayer.getBonusPosition();
        return blackScore - whiteScore; 
    }

答案 1 :(得分:1)

您缺少的部分是以类型作为参数的函数:

public int getScoreForPieceTypeAndPosition(int type, int row, int
 column) { public int getPieceValue(int type) {
     switch(type){
     case Piece.TYPE_PAWN: return PawnSquareTable[row * 8 + column ];
     case Piece.TYPE_KNIGHT: return KnightSquareTable[row * 8 + column ];
     case Piece.TYPE_BISHOP: return BishopSquareTable[row * 8 + column ];
     case Piece.TYPE_ROOK: return RookSquareTable[row * 8 + column ];
     case Piece.TYPE_QUEEN: return QueendSquareTable[row * 8 + column ]; 
     case Piece.TYPE_KING: return KingSquareTable[row *8 + column];
     default: throw new IllegalArgumentException("Unknown piece type: "+ type);
     } }

并在整体计算中使用该方法。

[未经测试]

对于像Pawn那样不对称的表可能还不够,那么你需要给出BROWN或WHITE参数并用(7 - 行)调用函数而不是BROWN的行。

(googling = http://chessprogramming.wikispaces.com/Simplified+evaluation+function