面向对象设计的国际象棋引擎
我想用面向对象的想法设计一个象棋引擎作为练习。 目前,我的国际象棋引擎大多是程序性编写的,我很难从对象的角度思考国际象棋引擎(决定接下来做哪一步的过程似乎并不基于'真实生活对象'尽可能多的例子是)目前我想到的设计是:
为了做出决定,发动机将需要一个位置,合法的动作,并能够进行分析未来排列的动作。 所以
该位置具有法定移动集合和基于位置的分数
人工智能“大脑”可以进入一个位置,并能够对其位置进行理论上的移动
电脑播放器有一个位置以及决定最佳移动的“大脑”
我正沿着正确的轨道走吗? 一般来说,如何设计类似于国际象棋引擎的东西,以面向对象的方式进行设计?
我不完全确定你的问题,但希望这可以推动你朝着正确的方向前进。
你需要的是:
您可以将您的电路板表示为二维数组,这使得坐标读取容易,但性能可怕。 如果你仍然希望它易于眼睛,一维数组是更有效的选择。 示例如下:
public class Board
{
///<summary>Chess board</summary>
/// 0 1 2 3 4 5 6 7
/// 8 9 10 11 12 13 14 15
/// 16 17 18 19 20 21 22 23
/// 24 25 26 27 28 29 30 31
/// 32 33 34 35 36 37 38 39
/// 40 41 42 43 44 45 46 47
/// 48 49 50 51 52 53 54 55
/// 56 57 58 59 60 61 62 63
public Piece[] Pieces;
//Is it white or blacks turn?
public bool IsWhiteTurn { get; set; }
public Piece GetField(int index)
{
return Pieces[index];
}
public Board CopyBoardAndDoMove(Move m)
{
//todo
}
}
碎片可以像这样表示:
public enum Piece
{
Empty =0,
WhitePawn = 1,
WhiteRook = 2,
WhiteKnight = 3,
WhiteBishop = 4,
WhiteQueen = 5,
WhiteKing =6,
BlackPawn = -1,
BlackRook = -2,
BlackKnight = -3,
BlackBishop = -4,
BlackQueen = -5,
BlackKing = -6
}
移动可以像这样表示:
public class SimpleMoveType
{
public SimpleMoveType(Piece chessPiece, Piece content, int oldField, int newField, SpecialMoves special = SpecialMoves.None)
{
ChessPiece = chessPiece;
Content = content;
NewField = newField;
OldField = oldField;
Special = special;
}
//The Piece to move
public Piece ChessPiece { get; set; }
//The Piece in the new field, if any.
public Piece Content { get; set; }
//index of new field
public int NewField { get; set; }
//index of old field
public int OldField { get; set; }
//Special move like promotion, castling effects the Piece or other pieces
//In case it's a special move, we need this info to apply the move to the Board.
public SpecialMoves Special { get; set; }
}
public enum SpecialMoves
{
None = 0,
EnPassant,
PawnTwoStepStart, //When a pawn makes its fist move it can move to fields forward
Promotion,
CastlingKingSide,
CastlingQueenSide,
PromotionKnight,
PromotionBishop,
PromotionRook
}
那么你将需要一个移动发生器。 在你进行任何进一步工作之前,你必须决定你是否想要合法或合法的合法行动。 法律行为是一个痛苦的执行,但sodu法律行动可能真的很难调试和发现问题。 相信我,这在前10次尝试中并不完美。
移动生成器应该是这样的:
public class MoveGenerator : IMoveGenerator
{
private readonly IMoveContainer _moveContainer;
public MoveGenerator(IMoveContainer moveContainer)
{
_moveContainer = moveContainer;
}
public List<SimpleMoveType> GetPsoudoLegalMoves(SimpleBoard b)
{
var moves = new List<SimpleMoveType>();
var white = b.White;
for (int i = 0; i < 64; i++)
{
moves.AddRange(GetMoves(i, b, white);
}
return moves;
}
private List<SimpleMoveType> GetMove(int indexBoardPosition, Board b, bool isWhiteTurn)
{
//TODO
}
}
现在是游戏逻辑(“大脑”)。 AI应该是min-max或alpha beta搜索树实现。 叶子是板子。 每一个可能的举动都会产生一个新的叶子(板)。 应该计算棋盘的价值,关于应该做下一步棋的棋手(黑色或白色)。
静态值可以用多种方式计算。 一个简单的方法是让你的作品指向棋盘上的位置,并为棋子赋予价值。 如果一块棋子丢失了,棋盘的价值就会下降。 是一个对手拍摄,你的董事会将获得价值。
件数的例子:
国王10.000(如果棋盘上的任何东西都加起来,如果比赛结束了)
女王900
塔500
主教300
骑士300
典当100
这个职位的价值可以由Kaare Danielsen从这些表中计算出来:
国际象棋程序设计是一个很大的项目,所以我建议看看这个wiki。 我建议在移动生成器中添加一些很好的单元测试。 这是项目第一阶段错误的首要原因。 我基于perft结果实施了很多测试,并为我吸引了很多bug。
玩的开心 :)
这个位置看起来更像是一名球员的状态。 我会有一个棋盘对象,其状态是棋子的放置位置,以及只允许有效移动的方法。 玩家对象都可以访问棋盘并可以评估他们的位置和移动。 玩家的控制器可以是AI大脑或用户输入的GUI。
链接地址: http://www.djcxy.com/p/84653.html