2015-09-13 47 views
0

我想设计一个使用面向对象思想的象棋引擎作为练习。目前,我的国际象棋引擎大多是程序性编写的,我很难从对象的角度思考国际象棋引擎(决定接下来做哪一步的过程似乎并不基于'真实生活对象'尽可能多的例子是)目前我想到的设计是:面向对象设计的国际象棋引擎

为了决定一个移动,引擎将需要一个位置,其法律动作,并能够做出动作来分析未来排列。所以

  • 的位置具有基于位置的法律动作的集合和一个得分

  • 的AI“大脑”能存取的位置,并且能够使自己的立场理论移动

  • 其中有一个位置,以及一个“大脑”,这决定了最好的移动电脑玩家

上午我沿着正确的TRA会中正?一般来说,如何设计类似于国际象棋引擎的东西,以面向对象的方式进行设计?

+0

这是太宽泛/意见为基础的堆栈溢出恐怕。 –

回答

1

我不完全确定你的问题,但希望这可以给你一个正确的方向推动。

你需要的是:

  • 委员会(代表64个领域,并在其上的残片)
  • 件(简单类型者优先由于性能,FX的 枚举会做)
  • 移动(片移动,旧场,新的字段和对新的字段内容)
  • MoveGenerator(要生成一个给定的板实例可能移动)
  • StaticValueGenerator(属te给定白板或黑板的板子实例的值)

您可以将您的主板表示为二维数组,这可以使坐标读取容易,但性能可怕。如果你仍然希望它易于眼睛,一维数组是更有效的选择。 示例如下:

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 
} 

然后你需要移动发电机。在你走之前,你必须决定是否要合法或sudo legal moves。法律行为是一个痛苦的执行,但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

位置的值可以从这些表由卡雷·丹尼尔森来计算: enter image description here

象棋编程是一个大项目,所以我会建议采取看看这个wiki。 我建议在移动生成器中添加一些很好的单元测试。这是项目第一阶段错误的首要原因。我实施了很多基于perft results的测试,并且为我吸引了很多错误。

玩得开心:)

+0

非常感谢您的详细回复!我知道我不应该只是回应说谢谢,但因为你花了这么多的工作来回答我的问题,这是我能做的最少的事情。 – CowNorris

0

该位置似乎更像是一名球员的状态。我会有一个棋盘对象,其状态是棋子的放置位置,以及只允许有效移动的方法。玩家对象都可以访问棋盘并可以评估他们的位置和移动。玩家的控制器可以是AI大脑或用户输入的GUI。