我目前正在学习Java并从事课堂作业。我们应该制作国际象棋的“怪异版本”。 就像在原始国际象棋中一样,如果有棋子移动,棋子也不会移动,最明显的例外是马,它可以跳过除国王以外的所有棋子。
我有一个抽象类Piece
,该类被所有作品类型所继承,每种类型都有各自的移动规则。他们中的大多数人都有这种运动限制,因此我在此类中定义了方法:
public boolean freeWayHorizontally(int xO, int yO, int xD) {
//RIGHT
if (xO < xD) {
for (int x = xO + 1; x < xD; x++) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(x, yO);
if (thereIsPiece != null){
return false;
}
}
//LEFT
} else if (xO > xD) {
for (int x = xO - 1; x > xD; x--) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(x, yO);
if (thereIsPiece != null){
return false;
}
}
}
return true;
}
public boolean freeWayVertically(int xO, int yO, int yD) {
//UP
if (yO < yD) {
for (int y = yO + 1; y < yD; y++) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(xO, y);
if (thereIsPiece != null){
return false;
}
}
//DOWN
} else if (yO > yD) {
for (int y = yO - 1; y > yD; y--) {
CrazyPiece thereIsPiece = Simulador.checkIfThereIsPiece(xO, y);
if (thereIsPiece != null){
return false;
}
}
}
return true;
}
thereIsPiece(int x, int y)
是国际象棋Simulator
类的函数,给定棋盘上的某个位置,则将棋子返回该位置。
很明显,这两个接收相同的参数(原点坐标和目标坐标,其中目标坐标之一是工件的原点坐标之一),因此唯一真正改变的是{{1} } 叫做。 编辑:因此,它们被标记为重复项,根据我的告诉,这非常糟糕!
但是,我似乎无法找出一种仅使用以下方法之一来解决此问题的方法; 还可以编辑:我尝试过重载它,但是它只能垂直或水平地工作(可能做错了)。
问题是我需要分别完成这些操作以实现Horse的移动,从而覆盖以下方法:
thereIsPiece()
然后调用自己的移动检查类型,该检查类型也在public boolean freeWayHorizontally(int xO, int yO, int xD) { //Overriden by the Horse class
//RIGHT
if (xO < xD) {
for (int x = xO + 1; x <= xD; x++) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(x, yO);
if (thereIsPiece != null && thereIsPiece.isKing){
return false;
}
}
//LEFT
} else if (xO > xD) {
for (int x = xO - 1; x >= xD; x--) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(x, yO);
if (thereIsPiece != null && thereIsPiece.isKing){
return false;
}
}
}
return true;
}
public boolean freeWayVertically(int xO, int yO, int yD) { //Overriden by the Horse class
//UP
if (yO < yD) {
for (int y = yO + 1; y <= yD; y++) {
CrazyPiece thereIsPiece = Simulador.checkIfTheresPiece(xO, y);
if (thereIsPiece != null && thereIsPiece.isKing){
return false;
}
}
//DOWN
} else if (yO > yD) {
for (int y = yO - 1; y >= yD; y--) {
CrazyPiece thereIsPiece = Simulador.checkIfThereIsPiece(xO, y);
if (thereIsPiece != null && thereIsPiece.isKing){
return false;
}
}
}
return true;
}
类中定义:
Piece
如何避免所有这些重复,甚至使这些验证更好?
答案 0 :(得分:0)
代码的第一个问题是您在Simulador
类上使用不同的方法来检查位置:
// When is checking horizontally
CrazyPiece thereIsPiece = Simulador.pegaPecaPorCoordenada(x, yO);
// When is checking vertically
CrazyPiece thereIsPiece = Simulador.checkIfThereIsPiece(xO, y);
我不明白为什么这不应该是一个单一方法。
我在这里可以看到2个不同的改进点:
例如:
public boolean freeWayHorizontally(int xO, int yO, int xD) {
int destination = xD;
int origin = xO + 1;
if (xO > xD) {
destination = xO - 1;
origin = xD;
}
for (int x = origin; x < destination; x++) {
CrazyPiece thereIsPiece = Simulador.pegaPecaPorCoordenada(x, yO);
if (thereIsPiece != null){
return false;
}
}
return true;
}
当原点位于目的地之前时,您将从原点移到目的地。
当目的地在起点之前时,您只需交换并从目的地移至起点。
我认为您应该添加一个方法:
private boolean checkPositionIsFree(int x, int y) {
return Simulador.pegaPecaPorCoordenada(x, y) != null;
}
现在,在不能合并这两种方法之前,您需要水平放置一个,垂直放置一个。
然后您可以像这样重写您的方法:
public boolean freeWayHorizontally(int xO, int yO, int xD) {
int destination = xD;
int origin = xO + 1;
if (xO > xD) {
destination = xO - 1;
origin = xD;
}
for (int x = origin; x < destination; x++) {
if (checkPositionIsFree(x, yO)){
return false;
}
}
return true;
}
对于马来说,您只需@Override
checkPositionIsFree()
方法就具有适当的条件(在国王身上加支票),一切都会正常工作。
更新
要完全涵盖马箱,您可以使用一种处理输入数据的方法:
@Override
public boolean freeWayHorizontally(int xO, int yO, int xD) {
return super.freeWayHorizontally(xO, yO, xD + 1);
}
通过这种方式,您可以避免重写所有代码。
顺便说一句,您的代码在这里有一些错别字,也许您可以重写它。最好检查这类事情,并拥有有效的代码(在您的情况下)或确切的代码失败,以避免由于错误的错误而浪费vouluntiers时间。