java - 如何克隆对象以移动某些内容并查看移动是否有效? ( java 、国际象棋)

标签 java oop class object chess

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

我通过单击一个上面有棋子的正方形来移动,然后该正方形被选中,然后单击我想要移动棋子的位置。有时,在国际象棋中,一步棋可能无法响应过牌或对自己的王造成过牌,因此是非法的。我发现,决定移动是否非法的最佳方法是在“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 结构的相同引用。 (更改克隆的主板会更改原始主板。)

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

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

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

相关文章:

java - Hibernate - 如何在不映射到特定类的情况下执行命名 native 查询

java - Solr 无法完全导入 cassandra DB

c++ - 禁止在类内使用方法

java - 从属性文件中读取内容

java - 在 Groovy 中重新加载类

java - 调用静态方法时的类实例

java - 对于用户数据库的“Use In Activity_main”类型,未定义 getactivity() 方法

c++ - C++中的静态和动态解析

java - 如何创建公共(public)类的新对象

java - Android Java - 运行时错误