2015-09-13 44 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。