我正在制作一个国际象棋游戏,现在正试图实现一个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;
}
}
答案 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个国王:
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)