【问题标题】:How to convert this method to a boolean如何将此方法转换为布尔值
【发布时间】:2018-11-09 23:06:07
【问题描述】:

我目前正在尝试实现一个国际象棋游戏。我已经对其进行了结构化,以便为每种类型生成可能的移动并将其存储在数组列表中。我的板是一个二维数组。我想知道如何写,如果 xTo yTo(想要移动到的点的坐标)是一个可能的移动,那么可以进行移动,但它不会让我使用数组 list.contains(),任何建议都非常感谢!这是我所拥有的一个例子。 (用户通过终端输入坐标xFrom,yFrom然后xTo yTo) 我现在想知道将其转换为布尔值是否更容易?并摆脱数组列表?

public Board() {
    this.boardsize = DEFAULT_SIZE;

    board = new char[boardsize][boardsize];

    // Clear all playable fields
    for (int x = 0; x < boardsize; x++)
        for (int y = 0; y < boardsize; y++)
            board[x][y] = FREE;

    board[0][7] = BLACKROOK;
    board[2][7] = BLACKBISHOP;
    board[5][7] = BLACKBISHOP;
    board[7][7] = BLACKROOK;
    board[0][0] = WHITEROOK;
    board[2][0] = WHITEBISHOP;
    board[5][0] = WHITEBISHOP;
    board[7][0] = WHITEROOK;

为了车……

public ArrayList<int[]> possibleMoves = new ArrayList<int[]>();


public ArrayList<int[]> generatePossibleMoves(char[][] gameBoard, int xFrom, int yFrom) {
    for (int i = 1; xFrom + i < gameBoard.length; i++) {
        if (getPieceColour(gameBoard, xFrom + i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
            if (gameBoard[xFrom + i][yFrom] != FREE) {
                int[] move = {xFrom + i, yFrom};
                possibleMoves.add(move);
                break;                              //stops iterating here since a rook is not allowed to jump over other pieces
            } else
                {
                int[] move = {xFrom + i, yFrom};
                possibleMoves.add(move);
            }
        }
    }
    for (int i = 1; xFrom - i < gameBoard.length; i++) {
        if (getPieceColour(gameBoard, xFrom - i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
            if (gameBoard[xFrom - i][yFrom] != FREE) {
                int[] move = {xFrom - i, yFrom};
                possibleMoves.add(move);
                break;
            }
            else
                {
                int[] move = {xFrom - i, yFrom};
                possibleMoves.add(move);
            }
        }
    }
    for (int i = 1; yFrom + i < gameBoard.length+1; i++) {       //makes sure the place to be moved is on the board
        if (getPieceColour(gameBoard, xFrom + i, yFrom) != getPieceColour(gameBoard, xFrom, yFrom)) {
            if (gameBoard[xFrom][yFrom+i] != FREE) {
                int[] move = {xFrom, yFrom+i};
                possibleMoves.add(move);
                break;
            }
            else
                {
                int[] move = {xFrom, yFrom+i};
                possibleMoves.add(move);
            }
        }
    }
    for (int i = 1; yFrom- i < gameBoard.length+1; i++)
        if (getPieceColour(gameBoard, xFrom, yFrom - 1) != getPieceColour(gameBoard, xFrom, yFrom)) {
            if (gameBoard[xFrom][yFrom - 1] != FREE) {
                int[] move = {xFrom, yFrom - 1};
                possibleMoves.add(move);
                break;
            } else {
                int[] move = {xFrom, yFrom - 1};
                possibleMoves.add(move);
            }
        }
    return possibleMoves;
}




public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int yTo){
    generatePossibleMoves(gameBoard, xFrom,yFrom);

    if(possibleMoves.contains(xTo,yTo){
        //this is where I'm stuck
    }

}

【问题讨论】:

  • 用 x,y 变量创建一个新的 Point 类,并在这个类上实现 hashcode 和 equals 方法。然后将 possibleMoves 更改为 Set。这将解决您当前的问题。在算法方面,我建议直接进行验证而不生成所有可能的移动。
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange (SE) 网络上发帖,您已在 CC BY-SA 3.0 license 下授予 SE 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 SE 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work? ...

标签: java arrays list chess


【解决方案1】:

要检查移动是否可行,一种方法是将这对夫妇 { xTo, yTo } 与您通过 generatePossibleMoves 函数计算的所有合法移动进行比较:

public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int 
yTo){
       int[] wantedMove = new int[] {xTo, yTo};
       ArrayList<int[]> possibleMoves = generatePossibleMoves(gameBoard, xFrom,yFrom);
       boolean isMoveLegal = possibleMoves.stream().anyMatch(possibleMove -> 
           Arrays.equals(wantedMove, possibleMove));
       return isMoveLegal;
}

【讨论】:

  • 这看起来很棒!但它不喜欢 -> Arrays.equals
  • 您使用的版本可能低于 Java 8。这应该适用于 Java 8+。
【解决方案2】:

我会创建另一个类 Coordinates 来正确实现 equals 方法

public class Coordinates {
    int x = 0;
    int y = 0;

    public Coordinates(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Coordinates other = (Coordinates) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }


}

然后将这个类用于ArrayList的类型

例如

public List<Coordinates> possibleMoves = new ArrayList<Coordinates>();

那么函数就变成了

public boolean moveLegal(char[][] gameBoard, int xFrom, int yFrom, int xTo, int yTo){
    generatePossibleMoves(gameBoard, xFrom,yFrom);
    Coordinates checkCoordinates = new Coordinates (xTo,yTo);
    if(possibleMoves.contains(xTo,yTo){
      ...
    }
}

【讨论】:

  • 最佳实践是将字段类型声明为尽可能通用。这就是为什么我建议您使用List 而不是ArrayList 并将public ArrayList&lt;Coordinates&gt; possibleMoves = new ArrayList&lt;Coordinates&gt;(); 更改为public List&lt;Coordinates&gt; possibleMoves = new ArrayList&lt;Coordinates&gt;();
  • 嗨@ADS 我绝对同意。为了让 MuratK 了解他如何在不过多更改当前代码的情况下使用 contains 方法,我编写了一个快速测试。
  • 当然,不要将我的评论视为人身攻击。我在这里只是为了帮助您改进答案,因为它可以看到很多人,而不仅仅是作者。
  • 我对你们的两个 cmets 都投了赞成票并编辑了我的代码。谢谢!
  • 如果我只使用列表,一切都会正常吗?(对不起,我对编程有点陌生
【解决方案3】:

主要原因是您保存在 possibleMoves 数组中,但试图检查 not 数组。如documentation 中所述,List.contains() 仅接受 1 个参数。由于您将数组放入您的List,因此您可能需要检查数组:if(possibleMoves.contains({xTo,yTo})

但实际上它无法正常工作。您混合了所有棋子的可能移动,因此您可以选择皇后并移动到任何可以到达骑士的点。

题外话: 我建议您使用更多 OOP 风格的方法:使用更少的原始数组和更多反映片段的对象。例如

enum Side { 
   White; Black; 
   public Side opposite() {
      if (this==White) return Black;
      else return White;
   }
}
// in separate file
class Pawn {
  private ChessSquare currentPosition;
  private final Side color;
  public boolean couldMoveTo(ChessSquare another) {
     if (currentPosition.x == another.x) {
       return another.y - currentPosition.y == 1; //TODO check for first move in two sruares
     } else if (another.hasPiece(this.color.opposite())) {
        // TODO allow to take enemy piece in diagonal
     }
  }
 public List<ChessField> possibleMoves() { 
   List<ChessField> result = new ArrayList<>();
   for (currentSquare in ALL_SQUARES) {
     if (couldMoveTo(currentSquare)) result.add(currentSquare)
   }
   return result;
}

我的示例效率低下,可以通过多种方式进行改进。还有许多其他选项如何组织代码结构。我想它展示了如何从这件作品的角度检查一件作品是否可以移动。您还可以在 Pawn 类中隐藏许多细节(如 en passant 规则),同时在上层有清晰的代码。你可以看到possibleMoves() 非常小,实际上可以用于所有片段。

附:国际象棋是一款很棒的游戏,我希望您在创建游戏时能够同时学习国际象棋和 Java。

【讨论】:

  • 谢谢大家的回复,这个方法转换成布尔值会不会更容易?如果可以移动则返回 true,否则返回 false?
  • @Shemar 我只是忘了声明方法couldMoveTo 的返回类型。我更新答案
猜你喜欢
  • 2021-06-27
  • 2016-10-07
  • 2016-05-14
  • 1970-01-01
  • 2013-02-13
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 2015-09-27
相关资源
最近更新 更多