Java中的国际象棋游戏:Square类应该有;生成可能的移动”;方法?
我在写一盘棋。我的基本设计是拥有一个由正方形对象组成的二维阵列(8 x 8)。正方形有许多字段:整数高度、整数宽度、工件(如果为空则为null,否则为某些类型的工件对象) 注:车,骑士,主教等,所有扩展件 现在,考虑到我的OOP设计,我有点被弄糊涂了,如何找出什么动作对给定的工件是合法的。下面是我的想法: 1) 用户点击方块 2) 我们确定哪一块在正方形上(如果为空,则返回错误消息) 3) 为那个方块上的那块产生合法的移动 我很担心编写这样的代码:Java中的国际象棋游戏:Square类应该有;生成可能的移动”;方法?,java,Java,我在写一盘棋。我的基本设计是拥有一个由正方形对象组成的二维阵列(8 x 8)。正方形有许多字段:整数高度、整数宽度、工件(如果为空则为null,否则为某些类型的工件对象) 注:车,骑士,主教等,所有扩展件 现在,考虑到我的OOP设计,我有点被弄糊涂了,如何找出什么动作对给定的工件是合法的。下面是我的想法: 1) 用户点击方块 2) 我们确定哪一块在正方形上(如果为空,则返回错误消息) 3) 为那个方块上的那块产生合法的移动 我很担心编写这样的代码: if (clickedSquare.piece
if (clickedSquare.piece.instanceOf(Rook)) {
return Rook.getLegalDestinationSquares(clickedSquare);
} else if (clickedSquare.piece.instanceOf(Bishop)) {
return Bishop.getLegalDestinationSquares(clickedSquare);
} else if...
这看起来很糟糕。一定有一种方法能更好地符合OOP,但我还在学习
谢谢你的帮助,
Mariogs您不需要创建if语句。只需获取字段中的当前片段并调用一些方法,如(getLegalMoves())或其他方法。 如果字段为空-返回允许移动的空列表
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
}
}
公共抽象类片段{
公共摘要列表getFieldsAllowed(字段);
}
公共级车扩展件{
@凌驾
公共列表getFieldsAllowed(字段){
//TODO自动生成的方法存根
返回null;
}
}
公共类字段{
公共件getPiece(){
//获取当前片段
}
}
像这样的。试着找到你自己的解决办法。这一个并不完美。如果Rook、Bishop等:
public class Rook extends Piece {
@Override
public String getLegalDestinationSquares() {
// returns all leagal Rook squers
return null;
}
}
这一部分是:
public abstract class Piece {
public abstract String getLegalDestinationSquares();
}
然后您可以这样做(在您的示例中):
返回字符串只是一个示例,可能您应该返回正方形的集合。公共最终类点{
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
}
}
公共最终int x,y;
公共点(整数x,整数y){
这个.x=x;
这个。y=y;
}
}
公共抽象类文章{
专用点位置;
受保护件(点首字母){
这个位置=初始位置;
}
公共点getLocation(){return location;}
公共点设置位置(点位置){this.location=location;}
公共摘要列表getLegalMoves();
}
公共末级车{
公共车(点首字母){
超级(首字母);
}
公共列表getLegalMoves(){
//你知道现在的位置,你知道你是一辆车,
//所以你有所有你需要确定的可能点
//这辆车可以去
}
}
然后在其他代码中,您可以执行以下操作:
List<Point> legalMoves = clickedSquare.piece.getLegalMoves();
List legalMoves=单击square.piece.getLegalMoves();
很明显,它抽象出了它所作用的实际部分
如果出于其他目的确实需要静态方法,可以在每个类(如Rook)中定义它们。将实例方法委托给静态方法以避免代码重复。像这样:
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
}
}
public final class Rook{
//建造师等。
公共列表getLegalMoves(){
return Rook.getLegalMoves(getLocation());
}
公共静态列表getLegalMoves(点开始){
//您知道位置(开始),并且您知道此方法适用于Rook,
//因此,您已经具备了确定可能的终点所需的一切
}
}
但是,如果不需要该静态方法,则不要使用甚至不要编写它(或者至少不要在类的API中公开它)。否则,类的用户将开始滥用它,最终将按照您在“开始”帖子中提供的方式编写代码——这是不计其数的if elses
通过使用此解决方案,您可以在未来添加更多具体的子类(
Pawn
,King
,…),而无需接触任何现有的代码(现在作用于Piece
),这与您提供的方法相比,为您提供了可维护性优势。来自OOD的一些批评者
Rules
的新类。规则有责任知道他能做什么动作。一个国王(例如)必须知道他是否已经做了一次掷骰来决定他是否可以做一次掷骰,因此他必须知道之前的动作,这打破了-啊,这里我们错过了另一个类:ChessNotation
你的代码正在编译吗?基本上你是在定义工厂。。。那么,它有什么问题吗?单击square.piece.getLegalDestinationSquares(单击square)怎么样?i、 e.创建一个在
Piece
的每个子类型中定义的重载方法,我会将isLegalMove(Piece,Square)放入ChessBoard类。创建一个抽象父类,该父类具有方法getlegaldestationsquares
,并让每个不同的片段实现它。
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
}
}