Commit 184c8379 authored by 刘家荣's avatar 刘家荣 💬
Browse files

feat(undo & some tests)

parent ac27e216
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
package controller;


import model.AI;
import model.History;
import model.dataType.*;
import model.game.*;
@@ -58,6 +59,9 @@ public enum ChessClickController {
                if(step != null) {
                    History.instance.steps.add(step);
                    firstId = -1;
                    if(Game.instance.gameType == GameType.LOCAL_AI){
                        AI.instance.start();
                    }
                }
            }
        }
+4 −3
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package model.dataType;

import model.game.Chess;
import model.game.Chessboard;
import model.game.Game;

/**
 * 记录一步行棋
@@ -24,9 +25,9 @@ public class EatStep extends Step {
    public final int burySquareId;
    
    public EatStep(int srcChessId, int dstChessId, int burySquareId) {
        if (Chessboard.getInstance().getSquareById(srcChessId) instanceof Chess
            && Chessboard.getInstance().getSquareById(dstChessId) instanceof Chess
            && !(Chessboard.getInstance().getSquareById(burySquareId) instanceof Chess)){
        if (Game.instance.chessboard.getSquareById(srcChessId) instanceof Chess
            && Game.instance.chessboard.getSquareById(dstChessId) instanceof Chess
            && !(Game.instance.chessboard.getSquareById(burySquareId) instanceof Chess)){
            this.srcChessId = srcChessId;
            this.dstChessId = dstChessId;
            this.burySquareId = burySquareId;
+40 −0
Original line number Diff line number Diff line
@@ -195,6 +195,46 @@ public class Chessboard implements Serializable, Cloneable {
        }
    }
    
    
    public Step revertMove(Square square1, Square square2, Square square3) {
        //移动的不是棋子,返回空
        if(!(square1 instanceof Chess chess1)) return null;
        
        Site site1 = chess1.site;
        Site site2 = square2.site;
        Site site3 = null;
        boolean mode = square3 != null;
        if(mode) {
            //被吃子是空格,返回空
            if(!(square2 instanceof Chess chess2)) return null;
            site3 = square3.site;
        }
        
        //交换Square的Location成员变量
        square2.setLocation(site1);
        if(mode) {
            square1.setLocation(site3);
            square3.setLocation(site2);
        }else{
            square2.setLocation(site1);
        }
        
        //依据Location成员变量,更新idGrid
        idGrid[site1.y][site1.x] = square2.id;
        if(mode)
            idGrid[site3.y][site3.x] = chess1.id;
        else
            idGrid[site2.y][site2.x] = chess1.id;
        
        //Return
        if(mode){
            this.getSideStack(site2.plate).updateIdGrid(square3);
            return new EatStep(chess1.id, square2.id, square3.id);
        }else {
            return new MoveStep(chess1.id, square2.id);
        }
    }

    @Override
    public Chessboard clone() {
        try {
+53 −8
Original line number Diff line number Diff line
@@ -70,12 +70,6 @@ public class Game implements Cloneable{
                chessboard.getSquareById(eatStep.srcChessId),
                chessboard.getSquareById(eatStep.dstChessId));
        }
        if(res != null){
            if(this.gameType == GameType.LOCAL_AI){
                AI ai = new AI();
                ai.start();
            }
        }
        return res;
    }
    
@@ -102,20 +96,71 @@ public class Game implements Cloneable{
        return step;
    }
    
    public Step revertStep(Step step){
        Step res = null;
        if(step instanceof FlipStep flipStep){
            res = revertFlip(chessboard.getSquareById(flipStep.srcChessId));
        }
        if (step instanceof MoveStep moveStep){
            res = revertMove(
                chessboard.getSquareById(moveStep.srcChessId),
                chessboard.getSquareById(moveStep.dstSquareId),
                null);
        }
        if (step instanceof EatStep eatStep){
            res = revertMove(
                chessboard.getSquareById(eatStep.srcChessId),
                chessboard.getSquareById(eatStep.dstChessId),
                chessboard.getSquareById(eatStep.burySquareId));
        }
        return res;
    }
    
    public Step revertFlip(Square square){
        if(!(square instanceof Chess chess))
            return null;
        chess.setReversal(false);
        currentColor = currentColor == ChessColor.BLACK ? ChessColor.RED : ChessColor.BLACK;
        return new FlipStep(chess.id);
    }
    
    /**
     * 撤销一次移动,失败就返回空;
     */
    public Step revertMove(Square srcSquare, Square dstSquare, Square burySquare){
        Step step = this.chessboard.revertMove(srcSquare, dstSquare, burySquare);
        if(step != null){
            if(step instanceof EatStep eatStep && dstSquare instanceof Chess dstChess) {
                scoreboard[dstChess.chessColor == ChessColor.RED ? 0 : 1] -= dstChess.chessType.points;
            }
        }
        currentColor = currentColor == ChessColor.BLACK ? ChessColor.RED : ChessColor.BLACK;
        return step;
    }
    
    @Override
    public Game clone() {
        try {
            Game clone = (Game) super.clone();
            
            // 就这?直接反射
            Field f = this.getClass().getDeclaredField("chessboard");
            f.setAccessible(true);
            f.set(clone, this.chessboard.clone());
            f.setAccessible(false);
            
            // 就这?
            f = this.getClass().getDeclaredField("msgList");
            f.setAccessible(true);
            f.set(clone, new ArrayList<>(this.msgList));
            f.setAccessible(false);
            
            // 就这?
            f = this.getClass().getDeclaredField("scoreboard");
            f.setAccessible(true);
            f.set(clone, this.scoreboard.clone());
            f.setAccessible(false);
            
            return clone;
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
+9 −9
Original line number Diff line number Diff line
@@ -4,32 +4,32 @@ import java.util.ArrayList;
/**
 * 结论:别调数组的Clone方法,除非是基本类型的数组
 */
public class CloneTest implements Cloneable{
public class ArrayAndListCloneTest implements Cloneable{
    
    public static void main(String[] args) {
        ArrayList<CloneTest> arr = new ArrayList<>();
        ArrayList<ArrayAndListCloneTest> arr = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            arr.add(new CloneTest());
            arr.add(new ArrayAndListCloneTest());
        }
        ArrayList<CloneTest> arr2 = (ArrayList<CloneTest>) arr.clone();
        ArrayList<ArrayAndListCloneTest> arr2 = (ArrayList<ArrayAndListCloneTest>) arr.clone();
        System.out.println(arr.get(1));
        System.out.println(arr2.get(1));
    }
    
    public static void main0(String[] args) {
        CloneTest[] arr = new CloneTest[5];
        ArrayAndListCloneTest[] arr = new ArrayAndListCloneTest[5];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new CloneTest();
            arr[i] = new ArrayAndListCloneTest();
        }
        CloneTest[] arr2 = arr.clone();
        ArrayAndListCloneTest[] arr2 = arr.clone();
        System.out.println(arr[1]);
        System.out.println(arr2[1]);
    }
    
    @Override
    public CloneTest clone() {
    public ArrayAndListCloneTest clone() {
        try {
            return (CloneTest) super.clone();
            return (ArrayAndListCloneTest) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
Loading