2013-11-28 318 views
2

我目前正在創建一盤棋,由以下類:國際象棋遊戲的設計和Singleton模式

  • ChessPiece - 對於所有不同的棋子,用MovementBehaviour實例變量
  • MovementBehaviour組成 - 由PawnMovementBehaviour實現的接口, KingMovementBehaviour等類定義 如何移動每個塊類型
  • 器ChessBoard - 與像addPiece()/ removePiece()功能的ChessPiece [] [] 2D陣列由......組成/ replacePiece()等
  • 播放 - 小類有助於關聯哪個片屬於哪個演奏人
  • 遊戲 - 主要的課程首先要詢問玩家的名字和想要的棋子顏色,然後通過實例化棋盤並讓玩家移動轉過 轉到達到將軍。

我想知道如果我應該使用Singleton模式(關於ChessBoard類)?目前我不是,我正在將棋盤的實例傳遞給棋子移動功能,以便棋子可以理解其周圍環境。這是因爲當然移動被認爲是合法的,這取決於任何時候在棋盤上佔用/空的空間。

+4

當涉及到典當時,注意MovementBehaviour:en-passant取決於對手的previoius移動。 Castling需要考慮其他因素(不能通過檢查進行城堡檢查,這兩件棋子都不得在castling之前移動)。如果我是你,我不會選擇單身。把棋盤作爲每件棋子的父對象似乎對我來說是合理的。 – Bathsheba

+1

你希望從Singleton模式中獲得什麼?如果有的話,您的設計的靈活性和一致性會產生什麼樣的成本? – GaryF

回答

3

單身很少是一個好主意。我最近剛剛開始了一個類似的項目,所以我會從我目前的經驗中回答這個問題。

我實現的方式是通過考慮棋盤Location對象,其中一個位置持有X - 值,Y - 值的集合和Piece對象。只有相關的地方填寫空的地方甚至沒有被跟蹤。

你似乎想知道你是否應該使用單例作爲驗證的單一目的。移動完成後,您需要驗證許多許多事情:您可以這樣移動嗎?你檢查?它是否和諧?這是一個rochade?等等。

你可以做的是創建一組驗證方法,它們將棋盤和起始和終止位置作爲參數。通過這種方式,您可以獲得檢查移動是否有效所需的全部信息。這確實需要件知道他們自己的屬性:我該如何移動?我的顏色是什麼?

當你有這一切,你可以實現不同的驗證邏輯來​​移動。

使用單例將是相當討厭的,當你可以提取驗證並通過棋盤周圍。測試也會更加困難(並且好的測試絕對是你想在棋類遊戲中找到的東西)。

我的設置是這樣的:

Chessboard.CanMoveToLocation(int startX, int startY, int endX, int endY) { 
    // Call validators with local field chessboard and given location objects 
} 

每個驗證將返回一個自定義枚舉ValidationResult以表明它是否允許或禁止這種特殊的驗證。

您必須確保以正確的順序調用驗證器(在檢查它是否爲有效的移動後返回錯誤不是一個好主意:他可能一直在rochading或殺死en-passant)。或者你可以結合相關的驗證器。

如果您想查看:my current (far from finished) implementation

1

以我的經驗,我寧願在這種情況下使用觀察者模式。 ChessBoard類扮演Observer的角色,ChessPiece應該是一個抽象類,它是Subject類。您可能需要查看觀察者模式及其用法

當您拿一塊棋子進行移動時,這意味着該棋子的位置已被更改,棋子會通知棋盤檢查移動是否它是否有效。