为什么设置器在特定选择中无效?

huangapple go评论74阅读模式
英文:

Why does a setter not work with a specific selection?

问题

抱歉,你提供的文本中包含代码,根据你的要求,我将只返回翻译好的部分。

抱歉标题措辞不当,但我无法确定如何恰当地概括问题。

我创建了一个国际象棋游戏,棋盘上保存着位置。棋子不知道它们的位置,除了国王。每当国王移动时,它的位置会通过一个简单的 setter 进行更新-

Gameflow.java

public static void movePiece(Player player, int pieceSelection, int action) {
    int x = pieceSelection / 10;
    int y = pieceSelection % 10;
    Board board = Board.boardConstructor(); // 棋盘是一个 Singleton
    Piece piece = Board.squares[x][y].getPiece();
    ...
    if (piece.getType().equals(Type.KING)) {              
        King king = (King) piece;
        king.setXY(endX, endY);
        System.out.println("国王移动到 " + king.getX() + king.getY()); // 打印旧位置
    }
}

King.java

public class King extends Piece {
    ...
    public void setXY(int x, int y) {        
        this.x = x;
        this.y = y;
        System.out.println("国王现在的位置是 " + this.x + this.y); // 打印新位置
    }
}

在 King.java 的 setter 内部的 println 输出了预期结果,但国王的位置未在其他地方更新

我为什么更新的位置没有被保存困扰不已,但我仍然能够通过改变一行代码来解决问题-

Gameflow.java

public static void movePiece(Player player, int pieceSelection, int action) {
    if (piece.getType().equals(Type.KING)) {                
        King king = player.getKing(); // <-- 改变了我选择国王的方式
        king.setXY(endX, endY);
        System.out.println("国王移动到 " + king.getX() + king.getY()); // 正确地打印
    }
}

这是复制棋子并通过玩家获取国王的代码

Player.java

private Player(String name, boolean isWhite) {
    this.name = name;
    this.isWhite = isWhite;
    if (isWhite) {
        team = createPieces(6);
    } else {
        team = createPieces(0);
    }
}

public static Piece[] createPieces(int start) {
    Piece[] team = new Piece[16];       
    int count = 0;
    int end = start + 2;
    for (int i = start; i < end; i++) {
        for (int j = 0; j < 8; j++) {
            team[count] = Board.squares[i][j].getPiece();
            count++;
        }
    }
    return team;
}

public King getKing() {
    Piece theKing = Arrays.stream(team).filter(x -> x.getType() == Type.KING).findFirst()
            .orElse(null);
    return (King) theKing;
}

我的问题得到了解决,但我对此一无所知。为什么那修复了我的代码?为什么之前它不起作用?

Piece 是一个抽象类,team 是玩家棋子的数组。

英文:

Sorry for the poorly worded title but I couldn't figure out how to properly summarize the problem.

I created a chess game where the location is kept by the Board. The pieces do not know their location, with the exception of the King. Any time the King moves, its location is updated with a simple setter-

Gameflow.java

    public static void movePiece(Player player, int pieceSelection, int action) {
        int x = pieceSelection / 10;
        int y = pieceSelection % 10;
        Board board = Board.boardConstructor(); //board is a Singleton
        Piece piece = Board.squares[x][y].getPiece();   
        ...
           if (piece.getType().equals(Type.KING)) {              
                King king = (King) piece;
                king.setXY(endX, endY);
                System.out.println(&quot;King moved to &quot; + king.getX() + king.getY()); //prints old location
            }

King.java

public class King extends Piece {
    ...
    public void setXY(int x, int y) {        
        this.x = x;
        this.y = y;
        System.out.println(&quot;The King&#39;s location is now &quot; + this.x + this.y); //prints new location
    }

The println inside the setter in King.java outputted as expected but the King's location was not being updated elsewhere

I was bamboozled as to why the updated location was not being saved but I nevertheless was able to fix the problem by changing one line-

Gameflow.java

    public static void movePiece(Player player, int pieceSelection, int action) {
            if (piece.getType().equals(Type.KING)) {                
                King king = player.getKing(); // &lt;-- changed how I select the King
                king.setXY(endX, endY);
                System.out.println(&quot;King moved to &quot; + king.getX() + king.getY()); //prints correctly
            }

Here is my code that copies the pieces and grabs the king via the player

Player.java

   private Player(String name, boolean isWhite) {
        this.name = name;
        this.isWhite = isWhite;
        if (isWhite) {
            team = createPieces(6);
        } else {
            team = createPieces(0);
        }
    }

    public static Piece[] createPieces(int start) {
        Piece[] team = new Piece[16];       
        int count = 0;
        int end = start + 2;
        for (int i = start; i &lt; end; i++) {
            for (int j = 0; j &lt; 8; j++) {
                team[count] = Board.squares[i][j].getPiece();
                count++;
            }
        }
        return team;
    }

    public King getKing() {
        Piece theKing = Arrays.stream(team).filter(x -&gt; x.getType() == Type.KING).findFirst()
                .orElse(null);
        return (King) theKing;
    }

My problem is fixed but I am none the wiser. Why did that fix my code? Why was it not working earlier?

Piece is an abstract class, team is an array of the player's pieces.

答案1

得分: 3

很难在不看 Board 的情况下说,但我看到了一些警告信号:对 Board.boardConstructor() 的调用听起来像是在获取一个新的棋盘,而不是现有的棋盘。在代码中,你几乎肯定是在使用不同的 piece 实例。尝试用以下代码替换来获取国王:

King king = player.getKing(); // <-- 改变了选择国王的方式
System.out.println(Integer.toHexString(System.identityHashCode(piece)) + "\t" 
    + Integer.toHexString(System.identityHashCode(king)));

如果打印出来的两个哈希码不同,那就表明它们是不同的棋子实例,问题很可能出在其他地方的逻辑。

英文:

It's hard to say without looking at Board, but I see a number of warning signs: The call to Board.boardConstructor() sounds like it's getting a new board, rather than the existing board. You're almost certainly working with a different instance of a piece in the code. Try replacing your code to get the king with the following:

King king = player.getKing(); // &lt;-- changed how I select the King
System.out.println(Integer.toHexString(System.identityHashCode(piece) + &quot;\t&quot; 
    + Integer.toHexString(System.identityHashCode(king)));

if the two hash codes printed differ, that indicates that they're different instances of the piece and the logic elsewhere is to blame.

答案2

得分: 1

Don Hosek指出了我的问题的来源,但我仍然需要进一步调查来确定原因,所以我将他的代码分别插入了我的棋盘(Board)和每个团队(Team)。我期望找到一组32个哈希码被打印两次,但实际上结果是64个不同的哈希码,也就是2组唯一的值。

在进一步使用哈希码后,我发现是棋盘上的棋子(Pieces)在发生变化。它们只在第一次移动之前改变了一次,这给了我一个很强的线索,说明了问题所在。

正如通常情况下最令人困惑的错误一样,答案非常简单。最初这是一个Java终端游戏,我将其迁移到了Spring/React,在这个过程中,我调换了涉及创建新游戏的两行代码的位置(初始化棋盘和玩家)。解决方案只是将它们互换回来。

我不知道在创建棋手之前创建玩家是如何避免在所有棋子都由棋盘实例化的情况下在棋盘之前创建玩家会引发更严重的错误,我非常非常惊讶,这个小问题竟然是从如此严重的错误中产生的唯一显著影响。

英文:

Don Hosek pointed out where my problem was coming from but I still needed to investigate further to determine the why so I plugged his code into both my Board and each Team. I expected to find one set of 32 hash codes being printed twice, but instead the result was 64 distinct hash codes, aka 2 sets of unique values.

After further use of the hash codes, I found that it was the Pieces on the Board that were mutating. They changed only once, before the first move, which gave me a strong clue as to the problem.

As is often the case with the most confusing errors, the answer was exceedingly simple. Originally this was a Java terminal game that I moved to Spring/React and while doing so, I transposed two lines of code involved in the creation of a new Game (initialization of the Board and of the Players). The solution was merely swapping them back.

I don't know how I didn't get a more critical error by creating Players before the Board when all the Pieces are instantiated by the Board, and I'm very, very surprised that this small issue was the only noticeable effect from such a serious bug.

huangapple
  • 本文由 发表于 2020年10月28日 02:53:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64561133.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定