Java中国际象棋游戏的OOP设计(片/板交互的麻烦)
我正在尝试用Java编写自己的国际象棋游戏。 我已经开始编写课程,我的高级想法如下:
我有这些字段的Piece类:
private String name; private String color;
最初我会为每件作品设置一个x和y坐标,但这似乎更像是董事会的财产。 这让我…
我有一个像这样的字段的Board类:
Piece[][] myBoard = new Piece[8][8];
我不确定我应该在哪里/如何跟踪作品的位置。 截至目前,我只有一个2d的Piece对象数组。 但是,我认为这会带来一些挑战。 例如,假设用户点击一块,想要移动它。 我需要弄清楚移动是否有效,为此,我需要当前的方块。
如果每个棋子都有一个x和y坐标,我会在两个地方(在Board类的2d数组中)和当前棋子的x和y坐标更新游戏状态。 这看起来很糟糕……
有什么建议么?
感谢Mariogs的帮助
我可以提供帮助,因为我已经用Java编写了一个完整的国际象棋引擎,你可以在这里找到
需要考虑的一些事项:
而不是让您的电路板成为8x8arrays,为什么不使用64个Tile的单维数组。 Tile
类可以是抽象的,有两个子类: OccupiedTile
和EmptyTile
。 每个tile都可以有一个整数coordinate
,编号为0到63,而OccupiedTile
也有一个Piece
。
Originally I was going to have an x and y coordinate for each piece but that seems like it's more a property of the board. Which brings me to...
一件作品很方便“知道”它的位置,所以用一块整数字段来跟踪它是不是坏事。
Piece
还应该包括Knight
, Bishop
, Pawn
, Rook
, Queen
和King
等子类。 这样,他们的toString()
方法可以返回pieceName
的固定值,而不是将其作为成员字段进行跟踪
最后,为什么没有名为Alliance
枚举来追踪白色或黑色碎片。 String
对于这个工作来说非常脆弱,因为调用者可以传递它想要的任何值。 看我的联盟版本。
我在我的程序中创建了这样的一块:
King king = new King(Alliance.BLACK, 4);
我觉得这很可读。
你的Piece[8][8]
方法似乎足以跟踪碎片的位置(除了我宁愿把它变成自己的类,里面有一个数组,你可能希望它早晚有更多的逻辑)只是设置和移动件)。 至于确定一件可以移动的位置,这似乎是实际作品的一个function:
public class BoardCoordinates { public final char vertical; public final int horizontal; public BoardCoordinates(char v, int h) { vertical = v; horizontal = h; } } public class Board { private Piece[8][8] state = new Piece[8][8]{}; public Piece at(BoardCoordinates c) { state[c.vertical - 'a'][c.horizontal]; } public void set(Piece what, BoardCoordinates where) { state[where.vertical - 'a'][where.horizontal] = what; } public void move(BoardCoordinates from, BoardCoordinates to) { set(at(from), to); set(null, from); } } public class Piece { .... public List findMoves(BoardCoordinates from, Board theBoard) { ... } }
大多数情况下,你不需要第二个参数,但是有必要处理特殊情况 – 比如castling或en passant – 其中移动的可能性取决于棋盘上的其他棋子(你实际上需要更多的信息)适当地处理en passant,但这与手头的问题没什么关系。
我绝对同意你在每件作品中保持坐标的说法,这听起来像是一个糟糕的主意。
您的描述中可能缺少另一个对象:BoardTile。 每个BoardTile都知道它的位置,推断它的颜色和相邻的瓷砖。 它也知道它是否为空或有任何一块。 此外,BoardTile和董事会相互了解(显然!)
鉴于棋子的行为很大程度上取决于它在棋盘中的位置,它应该知道它在哪个瓦片中。 因此,当您首次将所有部分放入董事会时,董事会应为每个部分分配相应的磁贴(请注意,此知识对应于ChessGame的规则,而不是董事会,因为您可能想要使用董事会和部分例如,国际象棋的一种变体。)同样,当棋子从棋盘上取下(大概是由ChessGame)时,棋子应该丢失它的棋子(通过消灭它)。
有了这三个对象,您将有几种选择。 例如,一件作品可以通过回答其拼贴的位置来了解其位置。 董事会可以通过查询瓷砖等来了解每件的位置。