Chess Game in Java: Should Square Class Have “Generate Possible Moves” Method?
我在写象棋游戏。 我的基本设计是要有一个由正方形对象组成的2d数组(8 x 8)。 正方形具有许多字段:int高度,int宽度,计件(如果为空则为null,否则为某种类型的计件对象。
注意:白嘴鸦,骑士,主教等都扩展了Piece。
现在,考虑到我的OOP设计,我对如何弄清楚某个给定零件的合法移动有所了解。 这就是我的想法:
1)用户点击正方形
2)我们确定什么是正方形(如果为空,则返回错误消息)
3)在该广场上为该作品产生合法移动
我担心编写如下代码:
1 2 3 4 5 | if (clickedSquare.piece.instanceOf(Rook)) { return Rook.getLegalDestinationSquares(clickedSquare); } else if (clickedSquare.piece.instanceOf(Bishop)) { return Bishop.getLegalDestinationSquares(clickedSquare); } else if... |
这似乎真的很糟糕。 必须有一种方法可以更好地符合OOP,但我仍在学习。
谢谢您的帮助,
马里奥格斯
您无需创建该if语句。只需获取当前字段并调用诸如(getLegalMoves())之类的方法即可。
如果字段为空-返回允许移动的空列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public abstract class Piece { public abstract List<Field> getFieldsAllowed(Field field); } public class Rook extends Piece { @Override public List<Field> getFieldsAllowed(Field field) { // TODO Auto-generated method stub return null; } } public class Field { public Piece getPiece() { // get current piece } } |
这样的事情。尝试找到自己的解决方案。这是不完美的。
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 | public final class Point { public final int x, y; public Point (int x, int y){ this.x = x; this.y = y; } } public abstract class Piece { private Point location; protected Piece (Point initial){ this.location = initial; } public Point getLocation(){ return location; } public Point setLocation(Point location){ this.location = location; } public abstract List<Point> getLegalMoves (); } public final class Rook { public Rook (Point initial){ super(initial); } public List<Point> getLegalMoves (){ // you know the current location, and you know you are a Rook, // so you have all you need to determine the possible points where // this Rook can go to } } |
然后在其他代码中,您可以执行以下操作:
1 | List<Point> legalMoves = clickedSquare.piece.getLegalMoves(); |
这显然是对其作用的实际部分的抽象。
如果确实需要将静态方法用于其他目的,则可以在每个类(如Rook)中定义它们。将实例方法委托给静态方法,以避免代码重复。像这样:
1 2 3 4 5 6 7 8 9 10 11 12 | public final class Rook { // constructor etc. public List<Point> getLegalMoves (){ return Rook.getLegalMoves (getLocation()); } public static List<Point> getLegalMoves(Point start){ // you know the location (start), and you know this method is for a Rook, // so you have all you need to determine the possible end points } } |
但是,如果不需要该静态方法,则不要使用甚至不要编写它(或者至少不要在类的API中公开它)。否则,班级的用户将开始滥用它,最终将按照您在开始帖子中提供的代码编写代码-数不清的if-elses。
通过使用此解决方案,您将来可以添加更多具体的子类(
来自OOD的有一些批评家。
如果Rook,Bishop等是:
1 2 3 4 5 6 7 | public class Rook extends Piece { @Override public String getLegalDestinationSquares() { // returns all leagal Rook squers return null; } } |
和件是:
1 2 3 |
然后,您可以像在您的示例中那样:
1 | return clickedSquare.piece.getLegalDestinationSquares(); |
返回字符串仅是示例,可能您应该返回正方形的集合。