我想用Java实现国际象棋作为练习我试图实现一些基本的部分,比如件移动但是我不能用这种方式写这个方法,如果你想要改变你的作品位置,你必须知道还有另一条路要走到新的位置(我们知道只有骑士才能跳过其他部分)。
另一个问题是城堡迁移的实施。
相关代码:
件:
enum Color {BLACK , WHITE}
enum TYPE {ROOK , BISHOP , KNIGHT , QUEEN , KING , PAWN}
public abstract class Piece {
private boolean available;
private char x;
private int y;
Color color;
TYPE type;
public Piece(boolean available, char x, int y, Color color, TYPE type) {
this.available = available;
this.x = x;
this.y = y;
this.color = color;
this.type = type;
}
public boolean validateMove(ChessBoard board,char fromX, int fromY, char toX, int toY) {
if(toX == fromX && toY == fromY)
return false;
if(getX() != fromX || toY != fromY)
return false;
if(toX - 'a' < 0 || toX - 'a' > 7 || toY < 0 || toY > 7 || fromX - 'a' < 0 || fromX - 'a' > 7 || fromY < 0 || fromY > 7)
return false;
protectingTheWay(board);
return true;
}
(以及所有它的吸气和制定者)。
毕晓普:
public class Bishop extends Piece {
public Bishop(boolean available, char x, int y, Color color, TYPE type) {
super(available, x, y, color, type);
}
@Override
public boolean validateMove(ChessBoard board,char fromX, int fromY, char toX, int toY) {
if(super.validateMove(board,fromX, fromY, toX, toY) == false)
return false;
if( abs(toX - 'a' - (fromX - 'a')) == abs(toY - fromY) )
return true;
return false;
}
}
骑士:
public class Knight extends Piece {
public Knight(boolean available, char x, int y, Color color, TYPE type) {
super(available, x, y, color, type);
}
@Override
public boolean validateMove(ChessBoard board,char fromX, int fromY, char toX, int toY) {
if( super.validateMove(board,fromX, fromY, toX, toY) == false)
return false;
if(toX - 'a' != fromX - 'a' - 1 || toX - 'a' != fromX - 'a' + 1 || toX - 'a' != fromX - 'a' + 2 || toX - 'a' != fromX - 'a' - 2)
if(toY != fromY - 2 || toY != fromY + 2 || toY != fromY - 1 || toY != fromY + 1)
return false;
return true;
}
}
和其他部分。
答案 0 :(得分:3)
这听起来像是一个很酷的练习,对我来说,听起来你实际上是一个设计问题,而不是编码问题。即使你不是熟悉设计模式和SOLID的OOP专家,甚至是Long中的多少位,你通常可以通过编写一些描述你正在构建的系统的文本来改善面向对象的应用程序,然后记下该文中的各种名词和动词。
因此,让我们从一个简单(显然不全面)的问题域描述开始:
国际象棋是一种游戏,在一个名为棋盘的棋盘上进行,目标是 在对方球员身边抓住一个特定的棋子 - 他们的 王。有两个玩家,一个玩白色,另一个玩 黑色。每个玩家从固定数量的各种各样的开始 类型(国王就是其中之一)。每件作品只能按预定义移动 方法。当白人玩家合法行动时,游戏开始 每个玩家轮流移动一个棋子直到游戏 结束。当一个人进入检查配对时(意味着他们的 自己的国王将在下一步被对手和对手抓获 国王无法逃脱,阻挡或消除捕获的威胁),何时 有一个平局(任何一个球员都不可能抓住 对手的国王),或者当一个球员向另一个球员投降时(因为 ......原因)。
如果您查看该描述,请记下各种名词和动词。名词是程序中的候选对象,动词是候选操作(方法)。
在上面的代码中,我看到代表一些棋子和棋盘的对象。将您的内容与上面的简单描述进行比较,并问自己缺少哪些其他可能的对象。一个有趣的含义可能是您是否将国际象棋移动视为潜在对象或其他对象可以执行的操作。
具体到您的问题 - 您如何根据拟议系统中的其他对象和方法定义城堡?铸造肯定是一种特定类型的移动,并且对于哪些碎片可以参与其中,开始和结束的位置以及可以执行它的方向存在限制(向左铸造!=右侧铸造)。
答案 1 :(得分:1)
如果我理解你的问题,Knight对象的validateMove工作不正确?如果我误解了,请告诉我。
好的,首先,在Piece对象的validateMove中,我不确定这段代码是做什么的:
if(getX() != fromX || toY != fromY)
return false;
我没有看到实现getX()方法的地方,所以可能存在问题。
另外,我知道这不是Code Review,但是IMO你应该将坐标保持为数字,并且只有当你需要在船上显示它们或者将它们打印到用户或其他任何地方时才将它们解析为字符。
我要说的另一件事是你在Knight的validateMove()中过度复杂化了。例如,我们知道骑士的移动是有效的,如果它在一个方向移动2个空间而在另一个方向移动1个,对吗?所以我们能做的只是检查一下,而且由于你的超级方法检查了板外的坐标,所以应该没有其他问题。例如,您可以这样做:
@Override
public boolean validateMove(ChessBoard board,char fromX, int fromY, char toX, int toY) {
if (!super.validateMove(board,fromX, fromY, toX, toY))
return false;
int xIndex = Math.abs(toX - fromX);
int yIndex = Math.abs(toY - fromY);
if (!(xIndex == 2 && yIndex == 1 || xIndex == 1 && yIndex == 2)) {
return false;
}
return true;
}
如果这对您有用,请告诉我。 :)