我正在编写一个简单的国际象棋游戏。我不会将所有内容都发布在这里,但我会为您提供必要的详细信息。
我通过单击一个上面有棋子的正方形来移动,然后该正方形被选中,然后单击我想要移动棋子的位置。有时,在国际象棋中,一步棋可能无法响应过牌或对自己的王造成过牌,因此是非法的。我发现,决定移动是否非法的最佳方法是在“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() 调用。
这是板类,或其一部分。
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
结构的相同引用。 (更改克隆的主板会更改原始主板。)
(许多人认为您应该同时避免使用 clone
和 Cloneable
。)
如果我是你,我会强烈考虑使 Board 类不可变,并且可能采用某种写时复制机制。我相信这会让你省去很多麻烦。
关于java - 如何克隆对象以移动某些内容并查看移动是否有效? ( java 、国际象棋),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9369246/