gpt4 book ai didi

java - 我如何克隆一个对象来移动某些东西并查看移动是否有效? (Java, 国际象棋)

转载 作者:行者123 更新时间:2023-11-30 07:27:59 26 4
gpt4 key购买 nike

我正在编写一个简单的国际象棋游戏。我不会在这里全部发布,但我会为您提供必要的详细信息。

我通过点击一个上面有棋子的方 block 来移动,然后这个方 block 被选中,然后点击我想要棋子的地方移动。有时在国际象棋中,一步棋可能无法响应检查或对自己的王造成检查,因此是非法的。我发现,确定一步棋是否非法的最佳方法是在“ifBoard”(棋盘的克隆)上移动,如果我认为该棋盘合法,则将真实棋盘设置为 ifBoard。

这是我响应鼠标点击的代码片段(board 是真实的board,destination 是被点击的方 block ,selectedSquare 是之前选择的方 block (如果不为空))

    public void mousePressed(MouseEvent e){
Square selectedSquare = board.selectedSquare();
Square destination = board.getSquare(e.getX(), e.getY());
board.deselect();
if(destination == null){
repaint();
return;
}

if(selectedSquare == null){
System.out.println("SelectedSquare is null");
if(destination.occupiedByTeam(turn)){
System.out.println("destination is occupied by right team and is null");
board.select(destination);
}
}
else{
if(!selectedSquare.occupiedByTeam(turn)){
System.out.println("SelectedSquare not occupied by correct team");
repaint();
return;
}

if(destination.occupiedByTeam(turn)){
System.out.println("ChosenSquare occupied by same team");
board.select(destination);
repaint();
return;
}

//move on a dummy board and check for conflicts
Board ifBoard = (Board)board.clone();

System.out.println(ifBoard.toString());
System.out.println(board.toString());
//check if you can't move due to piece movement limitations
//.place() is a coordinate of the square on the tile system (A-H and 1-8)
if(
!ifBoard.move((int)selectedSquare.place().getX(), (int)selectedSquare.place().getY(), (int)destination.place().getX(), (int)destination.place().getY())
){
repaint();
return;
}

//if moving results in self-check
if(ifBoard.check(turn)){
//don't move
repaint();
return;
}
else{
//move
System.out.println("Board moved!");
board = new Board(ifBoard);
cycleTurns();
}
}

repaint();
}

toString 调用的注册方式不同,但我已将问题缩小到 ifBoard.move() 调用实际上移动了真实的板。

这是 board 类,或者它的一部分。

import java.awt.Color;
import java.lang.Cloneable;
import java.awt.geom.*;
import java.awt.Graphics;
import java.awt.Graphics2D;

public class Board implements Cloneable{
private Square[][] squares;

private Rectangle2D squareWrap;
private Rectangle2D boardBorder;

private Square selectedSquare;

public Board(){
squares = new Square[8][8];
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
squares[i][j] = new Square(new Point2D.Double(i, j));
}
}

boardBorder = new Rectangle2D.Double(Constants.boardX,
Constants.boardY,
Constants.borderWidth * 2 + Constants.boardSide,
Constants.borderHeight * 2 + Constants.boardSide);

squareWrap = new Rectangle2D.Double(Constants.boardX + Constants.borderWidth,
Constants.boardY + Constants.borderHeight,
Constants.boardSide,
Constants.boardSide);

selectedSquare = null;
}

public Object clone() {
Board obj = new Board();
obj.setSquares(this.squares);
obj.setSelectedSquare(this.selectedSquare);

return obj;
}...

我克隆不正确吗?有没有更好的办法?提前谢谢你。

最佳答案

Am I cloning incorrectly? Is there a better way?

克隆方法应始终从调用 super.clone() 开始,原因我不会在本文中详述。

此外,您没有克隆对象的属性(您进行的是浅拷贝而不是深拷贝)。因此,克隆的 Board 将共享squares 结构的相同引用。 (更改克隆板会更改原始板。)

(许多人认为您应该避免同时使用 cloneCloneable。)

如果我是你,我会强烈考虑使 Board 类不可变,并可能采用一些写时复制机制。我相信这会让您省去很多麻烦。

关于java - 我如何克隆一个对象来移动某些东西并查看移动是否有效? (Java, 国际象棋),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9369246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com