我在Reddit发现了一种奇怪的bug,它发生在我的棋盘游戏中。具体来说,当我执行特定的一系列移动时,某个棋子无法再移动。这些移动是Nc3 d5,NF3 d4,Ne4 e5,Nxe5 f5。奇怪的是,我已经找到了问题的原因,但不知道为什么会这样发生。

当我点击棋子时,程序会注册一个点击,但实际上是点击了棋子后面的方格。即使棋子位于一个更高的层级上,我也可以在它上面放置另一个白色棋子,这是不应该发生的。

另外一个奇怪的事情是,如果黑棋先行并且执行相同的一系列移动(镜像),这个bug就不会发生。

我已经疯了,试图解决这个问题。以下是我的代码:

using System;
using UnityEngine;
using UnityEngine.InputSystem;
using System.Collections;
using System.Collections.Generic;

public class PieceClick : MonoBehaviour
{
    // 变量
    public ListLists> lists;
    public GameObject pieceg;
    public Piece piecef;
    public TurnTracker turnTracker;
    public ListGameObject> Pieces = new ListGameObject>();
    Camera cam;

    private void Awake()
    {
        lists.Pieces.Clear();
        cam = Camera.main;
    }

    public void MouseClick(InputAction.CallbackContext click)
    {
        // 检测是否点击了棋子
        if (click.performed)
        {
            var hit = Physics2D.GetRayIntersection(cam.ScreenPointToRay(Mouse.current.position.ReadValue()));
            GameObject collider = hit.collider.gameObject;
            if (collider == pieceg)
            {
                if ((turnTracker.whiteturn == true && piecef.team == 0) || (turnTracker.whiteturn == false && piecef.team == 1))
                {
                    // 取消选中棋子
                    if (piecef.isSelected == true)
                    {
                        Debug.Log("Deselect!");
                        lists.Pieces.RemoveAt(0);
                        piecef.isSelected = false;
                    }
                    // 选中棋子
                    else if (piecef.isSelected == false)
                    {
                        // 检测是否已经选中了棋子
                        if (lists.Pieces.Count == 1)
                        {
                            lists.Pieces[0].isSelected = false;
                            lists.Pieces.RemoveAt(0);
                            lists.Pieces.Insert(0, piecef);
                            Debug.Log(lists.Pieces.Count);
                            piecef.isSelected = true;
                        }
                        else
                        {
                            lists.Pieces.Insert(0, piecef);
                            Debug.Log(lists.Pieces.Count);
                            piecef.isSelected = true;
                        }
                    }
                }
            }
            // 尝试取下对手的棋子
            else if (lists.Pieces[0] != null)
            {
                // 检测是否可以移动到方格
                bool mc = lists.Pieces[0].MoveCheck(pieceg.transform.position.x, pieceg.transform.position.y, lists.Pieces[0].transform.position.x, lists.Pieces[0].transform.position.y, true);
                if (mc == true)
                {
                    // 取下对手的棋子
                    lists.Pieces[0].transform.position = piecef.transform.position;
                    Destroy(pieceg);
                    lists.Pieces[0].isSelected = false;
                    lists.Pieces.RemoveAt(0);
                    turnTracker.TurnChange();
                }
                else
                {
                    Debug.Log("Invalid");
                }
            }
        }
    }
}

public class SquareClick : MonoBehaviour
{
    // 变量
    public ListLists> lists;
    public TurnTracker turnTracker;
    Camera cam;
    public GameObject square;

    private void Awake()
    {
        cam = Camera.main;
    }

    public void MouseClick(InputAction.CallbackContext click)
    {
        // 检测是否点击了方格
        if (click.performed)
        {
            var hit = Physics2D.GetRayIntersection(cam.ScreenPointToRay(Mouse.current.position.ReadValue()));
            GameObject sq = hit.collider.gameObject;
            if (sq == square)
            {
                Debug.Log("Square");
                // 检测是否可以移动到方格
                bool mc = lists.Pieces[0].MoveCheck(square.transform.position.x, square.transform.position.y, lists.Pieces[0].transform.position.x, lists.Pieces[0].transform.position.y, false);
                if (mc == true)
                {
                    lists.Pieces[0].transform.position = square.transform.position;
                    lists.Pieces[0].isSelected = false;
                    lists.Pieces.Clear();
                    turnTracker.TurnChange();
                }
                else
                {
                    Debug.Log("invalid");
                }
            }
        }
    }
}

public class Knight : Piece
{
    public ListLists> lists;

    public override bool MoveCheck(float sx, float sy, float px, float py, bool isTaking)
    {
        bool mc;
        float xdif = Mathf.Abs(sx - px);
        float ydif = Mathf.Abs(sy - py);
        if ((xdif == 2 && ydif == 1) || (xdif == 1 && ydif == 2))
        {
            mc = true;
        }
        else
        {
            mc = false;
        }
        return mc;
    }
}