【中国象棋】unity中国象棋自我对弈

中国象棋

  • 一级目录
    • 二级目录
      • 三级目录
  • 棋类游戏的难度等级
  • 自我对弈代码
    • 游戏管理器
    • 棋子和格子
    • 棋子移动类
    • 棋子规则类
    • 检测将军类
    • 悔棋
    • UI类

一级目录

二级目录

三级目录

棋类游戏的难度等级

1、跳棋、五子棋:一星
2、中国象棋、国际象棋:三星
3、围棋:四星

自我对弈代码

游戏管理器

/// <summary>
/// 存储数据、游戏引用、游戏资源、模式切换与控制
/// </summary>
public class Chess_Manage : MonoBehaviour
{
    public static Chess_Manage Instance { get; private set; }

    public int chessPeople;//当前对战人数,PVE 1 PVP 2 联网 3

    public int currentLevel;//当前难度 1.简单 2.一般 3.困难

    /// <summary>
    /// 数据
    /// </summary>
    public int[,] chessBoard;//当前棋盘的状况
    public GameObject[,] boardGrid;//棋盘上的所有格子
    private const float gridWidth = 80f;
    private const float gridHeight = 80f;
    private const int gridTotalNum = 90;

    /// <summary>
    /// 开关
    /// </summary>
    public bool chessMove;//该哪方走,红true黑false
    public bool gameOver;//游戏结束不能走棋

    /// <summary>
    /// 资源
    /// </summary>
    public GameObject gridGo;//格子
    public Sprite[] sprites;//所有棋子的sprite
    public GameObject chessGo;//棋子
    public GameObject canMovePosUIGo;//可以移动到的位置显示

    /// <summary>
    /// 引用
    /// </summary>
    [HideInInspector]
    public GameObject boardGo;//棋盘
    public GameObject[] boardGos;//0.单机 1.联网
    [HideInInspector]
    public ChessOrGrid lastChessOrGrid;//上一次点击到的对象(格子或者棋子)
    public Chess_Rules rules;//规则类
    public MovingOfChess movingOfChess;//移动类
    public Checkmate checkmate;//将军检测类
    public ChessReseting chessReseting;//悔棋类
    public GameObject eatChessPool;//被吃掉棋子存放的棋子池
    public GameObject clickChessUIGo;//选中棋子的UI显示
    public GameObject lastPosUIGo;//棋子移动前的位置UI显示
    public GameObject canEatPosUIGo;//可以吃掉该棋子的UI显示
    private Stack<GameObject> canMoveUIStack;//移动位置UI显示游戏物体的对象池
    private Stack<GameObject> currentCanMoveUIStack;//当次移动位置UI已经显示出来的游戏物体栈

    private void Awake()
    {
        Instance = this;
    }

    // Start is called before the first frame update
    void Start()
    {
        //仅做测试
        chessPeople = 2;
        ResetGame();  
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    /// <summary>
    /// 重置游戏
    /// </summary>
    public void ResetGame()
    {
        chessMove = true;
        //初始化棋盘
        chessBoard = new int[10, 9]
        {
            {2,3,6,5,1,5,6,3,2},
            {0,0,0,0,0,0,0,0,0},
            {0,4,0,0,0,0,0,4,0},
            {7,0,7,0,7,0,7,0,7},
            {0,0,0,0,0,0,0,0,0},
            {0,0,0,0,0,0,0,0,0},
            {14,0,14,0,14,0,14,0,14},
            {0,11,0,0,0,0,0,11,0},
            {0,0,0,0,0,0,0,0,0},
            {9,10,13,12,8,12,13,10,9}
        };
        boardGrid = new GameObject[10, 9];
        if (chessPeople == 1||chessPeople==2)
        {
            boardGo = boardGos[0];
        }
        else
        {
            boardGo = boardGos[1];
        }
        InitGrid();
        InitChess();
        //规则类对象
        rules = new Chess_Rules();
        //移动类对象
        movingOfChess = new MovingOfChess(this);
        //将军检测对象
        checkmate = new Checkmate();
        //悔棋类对象
        chessReseting = new ChessReseting();
        chessReseting.resetCount = 0;
        chessReseting.chessSteps = new ChessReseting.Chess[400];
        //移动UI显示的栈
        canMoveUIStack = new Stack<GameObject>();
        for (int i = 0; i < 40; i++)
        {
            canMoveUIStack.Push(Instantiate(canMovePosUIGo));
        }
        currentCanMoveUIStack = new Stack<GameObject>();
    }
    /// <summary>
    /// 实例化格子
    /// </summary>
    private void InitGrid()
    {
        float posX = 0, posY = 0;
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                GameObject itemGo = Instantiate(gridGo);
                itemGo.transform.SetParent(boardGo.transform);
                itemGo.name = "Item[" + i.ToString() + "," + j.ToString() + "]";
                itemGo.transform.localPosition = new Vector3(posX,posY,0);
                posX += gridWidth;
                if (posX>=gridWidth*9)
                {
                    posY -= gridHeight;
                    posX = 0;
                }
                itemGo.GetComponent<ChessOrGrid>().xIndex = i;
                itemGo.GetComponent<ChessOrGrid>().yIndex = j;
                boardGrid[i, j] = itemGo;
            }
        }
    }
    /// <summary>
    /// 实例化棋子
    /// </summary>
    private void InitChess()
    {
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                GameObject item = boardGrid[i, j];
                switch (chessBoard[i,j])
                {
                    case 1:
                        CreateChess(item,"b_jiang",sprites[0],false);
                        break;
                    case 2:
                        CreateChess(item, "b_ju", sprites[1], false);
                        break;
                    case 3:
                        CreateChess(item, "b_ma", sprites[2], false);
                        break;
                    case 4:
                        CreateChess(item, "b_pao", sprites[3], false);
                        break;
                    case 5:
                        CreateChess(item, "b_shi", sprites[4], false);
                        break;
                    case 6:
                        CreateChess(item, "b_xiang", sprites[5], false);
                        break;
                    case 7:
                        CreateChess(item, "b_bing", sprites[6], false);
                        break;
                    case 8:
                        CreateChess(item, "r_shuai", sprites[7], true);
                        break;
                    case 9:
                        CreateChess(item, "r_ju", sprites[8], true);
                        break;
                    case 10:
                        CreateChess(item, "r_ma", sprites[9], true);
                        break;
                    case 11:
                        CreateChess(item, "r_pao", sprites[10], true);
                        break;
                    case 12:
                        CreateChess(item, "r_shi", sprites[11], true);
                        break;
                    case 13:
                        CreateChess(item, "r_xiang", sprites[12], true);
                        break;
                    case 14:
                        CreateChess(item, "r_bing", sprites[13], true);
                        break;
                    default:
                        break;
                }
            }
        }
    }
    /// <summary>
    /// 生成棋子游戏物体
    /// </summary>
    /// <param name="gridItem">作为父对象的格子</param>
    /// <param name="name">棋子名称</param>
    /// <param name="chessIcon">棋子标志样式</param>
    /// <param name="ifRed">是否为红色棋子</param>
    private void CreateChess(GameObject gridItem,string name,Sprite chessIcon,bool ifRed)
    {
        GameObject item = Instantiate(chessGo);
        item.transform.SetParent(gridItem.transform);
        item.name = name;
        item.GetComponent<Image>().sprite = chessIcon;
        item.transform.localPosition = Vector3.zero;
        item.transform.localScale = Vector3.one;
        item.GetComponent<ChessOrGrid>().isRed = ifRed;
    }
    /// <summary>
    /// 被吃掉棋子的处理方法
    /// </summary>
    /// <param name="itemGo">被吃掉棋子的游戏物体</param>
    public void BeEat(GameObject itemGo)
    {
        itemGo.transform.SetParent(eatChessPool.transform);
        itemGo.transform.localPosition = Vector3.zero;
    }
    /// <summary>
    /// 单机重玩方法
    /// </summary>
    public void Replay()
    {
        HideLastPositionUI();
        HideClickUI();
        HideCanEatUI();
        ClearCurrentCanMoveUIStack();
        lastChessOrGrid = null;
        for (int i = chessReseting.resetCount; i >0; i--)
        {
            chessReseting.ResetChess();
        }
    }

    #region 关于游戏进行中UI显示隐藏的方法

    /// <summary>
    /// 显示隐藏点击选中棋子的UI
    /// </summary>
    /// <param name="targetTrans"></param>
    public void ShowClickUI(Transform targetTrans)
    {
        clickChessUIGo.transform.SetParent(targetTrans);
        clickChessUIGo.transform.localPosition = Vector3.zero;
    }
    public void HideClickUI()
    {
        clickChessUIGo.transform.SetParent(eatChessPool.transform);
        clickChessUIGo.transform.localPosition = Vector3.zero;
    }
    /// <summary>
    /// 显示隐藏棋子移动前的位置UI
    /// </summary>
    /// <param name="showPosition"></param>
    public void ShowLastPositionUI(Vector3 showPosition)
    {
        lastPosUIGo.transform.position = showPosition;
    }
    public void HideLastPositionUI()
    {
        lastPosUIGo.transform.localPosition = new Vector3(100,100,100);
    }
    /// <summary>
    /// 隐藏可以吃掉该棋子的UI显示
    /// </summary>
    public void HideCanEatUI()
    {
        canEatPosUIGo.transform.SetParent(eatChessPool.transform);
        canEatPosUIGo.transform.localPosition = Vector3.zero;
    }
    /// <summary>
    /// 当前选中棋子可以移动到的位置UI显示与隐藏
    /// </summary>
    /// <returns></returns>
    public GameObject PopCanMoveUI()
    {
        GameObject itemGo = canMoveUIStack.Pop();
        currentCanMoveUIStack.Push(itemGo);
        itemGo.SetActive(true);
        return itemGo;
    }
    public void PushCanMoveUI(GameObject itemGo)
    {
        canMoveUIStack.Push(itemGo);
        itemGo.transform.SetParent(eatChessPool.transform);
        itemGo.SetActive(false);
    }
    public void ClearCurrentCanMoveUIStack()
    {
        while (currentCanMoveUIStack.Count>0)
        {
            PushCanMoveUI(currentCanMoveUIStack.Pop());
        }
    }

    #endregion

    
}

棋子和格子

挂载到棋子和格子的预制体上。
在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class ChessOrGrid : MonoBehaviour
{
    //格子索引
    public int xIndex, yIndex;
    //是红棋还是黑棋
    public bool isRed;
    //是否是格子
    public bool isGrid;
    //游戏管理的引用
    private Chess_Manage gameManager;
    //将来移动的时候需要设置的父对象,如果当前对象是棋子,那么需要
    //得到的不是它本身而是它的父对象
    private GameObject gridGo;

    // Start is called before the first frame update
    void Start()
    {
        gameManager = Chess_Manage.Instance;
        gridGo = gameObject;
    }
    /// <summary>
    /// 点击棋子格子时触发的检测方法
    /// </summary>
    public void ClickCheck()
    {
        if (gameManager.gameOver)
        {
            return;
        }
        int itemColorId;
        if (isGrid)
        {
            itemColorId = 0;
        }
        else
        {
            gridGo = transform.parent.gameObject;//得到他的父容器
            ChessOrGrid chessOrGrid = gridGo.GetComponent<ChessOrGrid>();
            xIndex = chessOrGrid.xIndex;
            yIndex = chessOrGrid.yIndex;
            if (isRed)
            {
                itemColorId = 2;
            }
            else
            {
                itemColorId = 1;
            }
        }
        GridOrChessBehavior(itemColorId,xIndex,yIndex);
    }
    /// <summary>
    /// 格子与棋子行为逻辑
    /// </summary>
    /// <param name="itemColorID">格子颜色ID</param>
    /// <param name="x">当前格子的X索引</param>
    /// <param name="y">当前格子的Y索引</param>
    private void GridOrChessBehavior(int itemColorID,int x,int y)
    {
        int FromX, FromY, ToX, ToY;
        gameManager.HideCanEatUI();
        switch (itemColorID)
        {
            //空格子
            case 0:
                gameManager.ClearCurrentCanMoveUIStack();
                ToX = x;
                ToY = y;
                //第一次点到空格子
                if (gameManager.lastChessOrGrid == null)
                {
                    gameManager.lastChessOrGrid = this;
                    return;
                }
                if (gameManager.chessMove)//红色轮次
                {
                    if (gameManager.lastChessOrGrid.isGrid)//上一次点击是否为格子
                    {
                        return;
                    }
                    if (!gameManager.lastChessOrGrid.isRed)//上一次选中是否为黑色
                    {
                        gameManager.lastChessOrGrid = null;
                        return;
                    }
                    FromX = gameManager.lastChessOrGrid.xIndex;
                    FromY = gameManager.lastChessOrGrid.yIndex;
                    //当前的移动是否合法
                    bool canMove = gameManager.rules.IsValidMove(gameManager.chessBoard,FromX,FromY,ToX,ToY);
                    if (!canMove)
                    {
                        return;
                    }
                    //棋子进行移动
                    int chessOneID = gameManager.chessBoard[FromX, FromY];
                    int chessTwoID = gameManager.chessBoard[ToX, ToY];
                    gameManager.chessReseting.AddChess(gameManager.chessReseting.resetCount,FromX,FromY,ToX,ToY,chessOneID,chessTwoID);
                    gameManager.movingOfChess.IsMove(gameManager.lastChessOrGrid.gameObject,gridGo,FromX,FromY,ToX,ToY);
                    Chess_UIManage.Instance.ShowTip("黑方走");
                    gameManager.checkmate.JudgeIfCheckmate();
                    gameManager.chessMove = false;
                    gameManager.lastChessOrGrid = this;
                    gameManager.HideClickUI();
                }
                else//黑色轮次
                {
                    if (gameManager.lastChessOrGrid.isGrid)
                    {
                        return;
                    }
                    if (gameManager.lastChessOrGrid.isRed)
                    {
                        gameManager.lastChessOrGrid = null;
                        return;
                    }
                    FromX = gameManager.lastChessOrGrid.xIndex;
                    FromY = gameManager.lastChessOrGrid.yIndex;
                    bool canMove = gameManager.rules.IsValidMove(gameManager.chessBoard,FromX,FromY,ToX,ToY);
                    if (!canMove)
                    {
                        return;
                    }
                    int chessOneID = gameManager.chessBoard[FromX, FromY];
                    int chessTwoID = gameManager.chessBoard[ToX, ToY];
                    gameManager.chessReseting.AddChess(gameManager.chessReseting.resetCount, FromX, FromY, ToX, ToY, chessOneID, chessTwoID);
                    gameManager.movingOfChess.IsMove(gameManager.lastChessOrGrid.gameObject,gridGo,FromX,FromY,ToX,ToY);
                    Chess_UIManage.Instance.ShowTip("红方走");
                    gameManager.checkmate.JudgeIfCheckmate();
                    gameManager.chessMove = true;
                    gameManager.lastChessOrGrid = this;
                    gameManager.HideClickUI();
                }
                break;
            //黑色棋子
            case 1:
                gameManager.ClearCurrentCanMoveUIStack();
                if (!gameManager.chessMove)//黑色轮次
                {
                    FromX = x;
                    FromY = y;
                    gameManager.movingOfChess.ClickChess(FromX,FromY);
                    gameManager.lastChessOrGrid = this;
                    gameManager.ShowClickUI(transform);
                }
                else//红色轮次
                {
                    //红色棋子将要吃黑色棋子
                    if (gameManager.lastChessOrGrid==null)
                    {
                        return;
                    }
                    if (!gameManager.lastChessOrGrid.isRed)
                    {
                        gameManager.lastChessOrGrid = this;
                        return;
                    }
                    FromX = gameManager.lastChessOrGrid.xIndex;
                    FromY = gameManager.lastChessOrGrid.yIndex;
                    ToX = x;
                    ToY = y;
                    bool canMove = gameManager.rules.IsValidMove(gameManager.chessBoard,FromX,FromY,ToX,ToY);
                    if (!canMove)
                    {
                        return;
                    }
                    int chessOneID = gameManager.chessBoard[FromX, FromY];
                    int chessTwoID = gameManager.chessBoard[ToX, ToY];
                    gameManager.chessReseting.AddChess(gameManager.chessReseting.resetCount, FromX, FromY, ToX, ToY, chessOneID, chessTwoID);
                    gameManager.movingOfChess.IsEat(gameManager.lastChessOrGrid.gameObject,gameObject, FromX, FromY, ToX, ToY);
                    gameManager.chessMove = false;
                    Chess_UIManage.Instance.ShowTip("黑色走");
                    gameManager.lastChessOrGrid = null;
                    gameManager.checkmate.JudgeIfCheckmate();
                    gameManager.HideClickUI();
                }
                break;
            //红色棋子
            case 2:
                gameManager.ClearCurrentCanMoveUIStack();
                if (gameManager.chessMove)//红色轮次
                {
                    FromX = x;
                    FromY = y;
                    gameManager.movingOfChess.ClickChess(FromX, FromY);
                    gameManager.lastChessOrGrid = this;
                    gameManager.ShowClickUI(transform);
                }
                else//黑色轮次
                {
                    //黑吃红
                    if (gameManager.lastChessOrGrid==null)
                    {
                        return;
                    }
                    if (gameManager.lastChessOrGrid.isRed)
                    {
                        gameManager.lastChessOrGrid = this;
                        return;
                    }
                    FromX = gameManager.lastChessOrGrid.xIndex;
                    FromY = gameManager.lastChessOrGrid.yIndex;
                    ToX = x;
                    ToY = y;
                    bool canMove = gameManager.rules.IsValidMove(gameManager.chessBoard,FromX,FromY,ToX,ToY);
                    if (!canMove)
                    {
                        return;
                    }
                    int chessOneID = gameManager.chessBoard[FromX, FromY];
                    int chessTwoID = gameManager.chessBoard[ToX, ToY];
                    gameManager.chessReseting.AddChess(gameManager.chessReseting.resetCount, FromX, FromY, ToX, ToY, chessOneID, chessTwoID);
                    gameManager.movingOfChess.IsEat(gameManager.lastChessOrGrid.gameObject,gameObject,FromX,FromY,ToX,ToY);
                    gameManager.chessMove = true;
                    gameManager.lastChessOrGrid = null;
                    Chess_UIManage.Instance.ShowTip("红方走");
                    gameManager.checkmate.JudgeIfCheckmate();
                    gameManager.HideClickUI();
                }
                break;
            default:
                break;
        }
    }
}

棋子移动类

///
/// 棋子的移动类
///
public class MovingOfChess
{
private Chess_Manage gameManager;

public MovingOfChess(Chess_Manage mGameManager)
{
    gameManager = mGameManager;
}

/// <summary>
/// 棋子的移动方法
/// </summary>
/// <param name="chessGo">要移动的棋子游戏物体</param>
/// <param name="targetGrid">要移动到的格子游戏物体</param>
/// <param name="x1"></param>
/// <param name="y1"></param>
/// <param name="x2"></param>
/// <param name="y2"></param>
public void IsMove(GameObject chessGo,GameObject targetGrid,int x1,int y1,int x2,int y2)
{
    gameManager.ShowLastPositionUI(chessGo.transform.position);
    chessGo.transform.SetParent(targetGrid.transform);
    chessGo.transform.localPosition = Vector3.zero;
    gameManager.chessBoard[x2, y2] = gameManager.chessBoard[x1, y1];
    gameManager.chessBoard[x1, y1] = 0;
}
/// <summary>
/// 棋子的吃子方法
/// </summary>
/// <param name="firstChess">想要移动的棋子</param>
/// <param name="secondChess">想要吃掉的棋子</param>
/// <param name="x1"></param>
/// <param name="y1"></param>
/// <param name="x2"></param>
/// <param name="y2"></param>
public void IsEat(GameObject firstChess,GameObject secondChess, int x1, int y1, int x2, int y2)
{
    gameManager.ShowLastPositionUI(firstChess.transform.position);
    GameObject secondChessGrid = secondChess.transform.parent.gameObject;//得到了第二个棋子的父对象
    firstChess.transform.SetParent(secondChessGrid.transform);
    firstChess.transform.localPosition = Vector3.zero;
    gameManager.chessBoard[x2, y2] = gameManager.chessBoard[x1, y1];
    gameManager.chessBoard[x1, y1] = 0;
    gameManager.BeEat(secondChess);
}
/// <summary>
/// 判断当前点击到的是什么类型的棋子从而执行相应方法
/// </summary>
/// <param name="fromX"></param>
/// <param name="fromY"></param>
public void ClickChess(int fromX,int fromY)
{
    int chessID = gameManager.chessBoard[fromX,fromY];
    switch (chessID)
    {
        case 1://黑将
            GetJiangMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 8://红帅
            GetShuaiMove(gameManager.chessBoard,fromX,fromY);
            break;
        case 2://黑車
        case 9:
            GetJuMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 3://黑马
        case 10:
            GetMaMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 4://黑炮
        case 11:
            GetPaoMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 5://黑士
            GetB_ShiMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 12://红仕
            GetR_ShiMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 6://黑象
        case 13:
            GetXiangMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 7://黑卒
            GetB_BingMove(gameManager.chessBoard, fromX, fromY);
            break;
        case 14://红兵
            GetR_BingMove(gameManager.chessBoard, fromX, fromY);
            break;
        default:
            break;
    }
}

#region 得到对应种类的棋子当前可以移动的所有路径
/// <summary>
/// 将
/// </summary>
/// <param name="position"></param>
/// <param name="fromX"></param>
/// <param name="fromY"></param>
private void GetJiangMove(int[,] position,int fromX,int fromY)
{
    for (int x = 0; x < 3; x++)
    {
        for (int y = 3; y < 6; y++)
        {
            if (gameManager.rules.IsValidMove(position,fromX,fromY,x,y))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
    }
}
/// <summary>
/// 帅
/// </summary>
private void GetShuaiMove(int[,] position, int fromX, int fromY)
{
    for (int x= 7; x < 10; x++)
    {
        for (int y = 3; y < 6; y++)
        {
            if (gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
    }
}
/// <summary>
/// 红黑車
/// </summary>
/// <param name="position"></param>
/// <param name="fromX"></param>
/// <param name="fromY"></param>
private void GetJuMove(int[,] position,int fromX,int fromY)
{
    int x, y;
    int chessID;
    //得到当前选中棋子的ID,目的是为了遍历时判断第一个不为空格子的棋子跟我们是否是同一边
    chessID = position[fromX, fromY];
    //右
    x = fromX;
    y = fromY + 1;
    while (y<9)
    {
        if (position[x,y]==0)//当前遍历到的位置ID是否为0(即空格子)
        {
            GetCanMovePos(position,fromX,fromY,x,y);
        }
        else//不为空格子
        {
            if (!gameManager.rules.IsSameSide(chessID,position[x,y]))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
            break;
        }
        y++;
    }
    //左
    x = fromX;
    y = fromY - 1;
    while (y>=0)
    {
        if (position[x, y] == 0)//当前遍历到的位置ID是否为0(即空格子)
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
        else//不为空格子
        {
            if (!gameManager.rules.IsSameSide(chessID, position[x, y]))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
            break;
        }
        y--;
    }
    //下
    x = fromX + 1;
    y = fromY;
    while (x<10)
    {
        if (position[x, y] == 0)//当前遍历到的位置ID是否为0(即空格子)
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
        else//不为空格子
        {
            if (!gameManager.rules.IsSameSide(chessID, position[x, y]))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
            break;
        }
        x++;
    }
    //上
    x = fromX - 1;
    y = fromY;
    while (x>=0)
    {
        if (position[x, y] == 0)//当前遍历到的位置ID是否为0(即空格子)
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
        else//不为空格子
        {
            if (!gameManager.rules.IsSameSide(chessID, position[x, y]))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
            break;
        }
        x--;
    }
}
/// <summary>
/// 红黑马
/// </summary>
private void GetMaMove(int[,] position, int fromX, int fromY)
{
    int x, y;
    //竖日
    //右下
    x = fromX + 2;
    y = fromY + 1;
    if ((x<10&&y<9)&&gameManager.rules.IsValidMove(position,fromX,fromY,x,y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //右上
    x = fromX - 2;
    y = fromY + 1;
    if ((x >=0&& y < 9) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左下
    x = fromX + 2;
    y = fromY - 1;
    if ((x < 10 && y >=0) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左上
    x = fromX - 2;
    y = fromY - 1;
    if ((x >=0 && y >=0) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //横日
    //右下
    x = fromX + 1;
    y = fromY + 2;
    if ((x < 10 && y < 9) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //右上
    x = fromX - 1;
    y = fromY + 2;
    if ((x >=0 && y < 9) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左下
    x = fromX + 1;
    y = fromY - 2;
    if ((x < 10 && y >=0) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左上
    x = fromX - 1;
    y = fromY - 2;
    if ((x >=0 && y >=0) && gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
}
/// <summary>
/// 红黑炮
/// </summary>
private void GetPaoMove(int[,] position, int fromX, int fromY)
{
    int x, y;
    bool flag;//是否满足翻山的条件
    int chessID;
    chessID = position[fromX, fromY];
    //右
    x = fromX;
    y = fromY + 1;
    flag = false;
    while (y<9)
    {
        //是空格子
        if (position[x,y]==0)
        {
            //在未达成翻山条件前,显示所有可以移动的路径,达成之后
            //不可空翻
            if (!flag)
            {
                GetCanMovePos(position,fromX,fromY,x,y);
            }
        }
        //是棋子
        else
        {
            //条件未满足时,开启条件的满足,可翻山
            if (!flag)
            {
                flag = true;
            }
            //已开启,判断当前是否为同一方,如果是,此位置不可以移动
            //如果不是,则此子可吃,即可移动到此位置,则需显示
            //结束当前遍历
            else
            {
                if (!gameManager.rules.IsSameSide(chessID,position[x,y]))
                {
                    GetCanMovePos(position,fromX,fromY,x,y);
                }
                break;
            }
        }
        y++;
    }
    //左
    y = fromY - 1;
    flag = false;
    while (y>=0)
    {
        if (position[x,y]==0)
        {
            if (!flag)
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
        else
        {
            if (!flag)
            {
                flag = true;
            }
            else
            {
                if (!gameManager.rules.IsSameSide(chessID,position[x,y]))
                {
                    GetCanMovePos(position,fromX,fromY,x,y);
                }
                break;
            }
        }
        y--;
    }
    //下
    x = fromX + 1;
    y = fromY;
    flag = false;
    while (x<10)
    {
        //是空格子
        if (position[x, y] == 0)
        {
            //在未达成翻山条件前,显示所有可以移动的路径,达成之后
            //不可空翻
            if (!flag)
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
        //是棋子
        else
        {
            //条件未满足时,开启条件的满足,可翻山
            if (!flag)
            {
                flag = true;
            }
            //已开启,判断当前是否为同一方,如果是,此位置不可以移动
            //如果不是,则此子可吃,即可移动到此位置,则需显示
            //结束当前遍历
            else
            {
                if (!gameManager.rules.IsSameSide(chessID, position[x, y]))
                {
                    GetCanMovePos(position, fromX, fromY, x, y);
                }
                break;
            }
        }
        x++;
    }
    //上
    x = fromX - 1;
    flag = false;
    while (x>=0)
    {
        //是空格子
        if (position[x, y] == 0)
        {
            //在未达成翻山条件前,显示所有可以移动的路径,达成之后
            //不可空翻
            if (!flag)
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
        //是棋子
        else
        {
            //条件未满足时,开启条件的满足,可翻山
            if (!flag)
            {
                flag = true;
            }
            //已开启,判断当前是否为同一方,如果是,此位置不可以移动
            //如果不是,则此子可吃,即可移动到此位置,则需显示
            //结束当前遍历
            else
            {
                if (!gameManager.rules.IsSameSide(chessID, position[x, y]))
                {
                    GetCanMovePos(position, fromX, fromY, x, y);
                }
                break;
            }
        }
        x--;
    }
}
/// <summary>
/// 黑士
/// </summary>
private void GetB_ShiMove(int[,] position, int fromX, int fromY)
{
    for (int x = 0; x < 3; x++)
    {
        for (int y = 3; y < 6; y++)
        {
            if (gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
    }
}
/// <summary>
/// 红仕
/// </summary>
private void GetR_ShiMove(int[,] position, int fromX, int fromY)
{
    for (int x = 7; x < 10; x++)
    {
        for (int y = 3; y < 6; y++)
        {
            if (gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
            {
                GetCanMovePos(position, fromX, fromY, x, y);
            }
        }
    }
}
/// <summary>
/// 红相黑象
/// </summary>
private void GetXiangMove(int[,] position, int fromX, int fromY)
{
    int x, y;
    //右下走
    x = fromX + 2;
    y = fromY + 2;
    if (x < 10 && y < 9&&gameManager.rules.IsValidMove(position,fromX,fromY,x,y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //右上走
    x = fromX - 2;
    y = fromY + 2;
    if (x >= 0 && y < 9&&gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左下走
    x = fromX + 2;
    y = fromY - 2;
    if (x < 10 && y >= 0&&gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //左上走
    x = fromX - 2;
    y = fromY - 2;
    if (x >= 0 && y >= 0&&gameManager.rules.IsValidMove(position, fromX, fromY, x, y))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
}
/// <summary>
/// 黑卒
/// </summary>
private void GetB_BingMove(int[,] position, int fromX, int fromY)
{
    int x, y;
    int chessID;
    chessID = position[fromX, fromY];
    x = fromX + 1;
    y = fromY;
    if (x<10&&!gameManager.rules.IsSameSide(chessID,position[x,y]))
    {
        GetCanMovePos(position, fromX, fromY, x, y);
    }
    //过河后
    if (fromX>4)
    {
        x = fromX;
        y = fromY + 1;//右边
        if (y<9&& !gameManager.rules.IsSameSide(chessID, position[x, y]))
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
        y = fromY - 1;//左边
        if (y>=0 && !gameManager.rules.IsSameSide(chessID, position[x, y]))
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
    }
}
/// <summary>
/// 红兵
/// </summary>
private void GetR_BingMove(int[,] position, int fromX, int fromY)
{
    int x, y;
    int chessID;
    chessID = position[fromX, fromY];
    x = fromX - 1;
    y = fromY;
    if (x>0&&!gameManager.rules.IsSameSide(chessID,position[x,y]))
    {
        GetCanMovePos(position,fromX,fromY,x,y);
    }
    //过河后
    if (fromX<5)
    {
        x = fromX;
        y = fromY + 1;//右边
        if (y<9&&!gameManager.rules.IsSameSide(chessID,position[x,y]))
        {
            GetCanMovePos(position,fromX,fromY,x,y);
        }
        y = fromY - 1;//左边
        if (y>=0&&!gameManager.rules.IsSameSide(chessID, position[x, y]))
        {
            GetCanMovePos(position, fromX, fromY, x, y);
        }
    }
}
#endregion
/// <summary>
/// 把传递进来的一个可移动路径显示出来
/// </summary>
/// <param name="positon"></param>
/// <param name="fromX"></param>
/// <param name="fromY"></param>
/// <param name="toX"></param>
/// <param name="toY"></param>
private void GetCanMovePos(int[,] positon,int fromX,int fromY,int toX,int toY)
{
    if (!gameManager.rules.KingKill(positon,fromX,fromY,toX,toY))
    {
        return; 
    }
    GameObject item;
    if (positon[toX,toY]==0)//是空格子,可移动的位置
    {
        item = gameManager.PopCanMoveUI();
    }
    else//是棋子,代表此棋子可吃
    {
        item = gameManager.canEatPosUIGo;
    }
    item.transform.SetParent(gameManager.boardGrid[toX,toY].transform);
    item.transform.localPosition = Vector3.zero;
    item.transform.localScale = Vector3.one;
}

}

棋子规则类

/// <summary>
/// 棋子的规则类
/// </summary>
public class Chess_Rules
{
    /// <summary>
    /// 检查当前此次移动是否合法
    /// </summary>
    /// <param name="position">当前棋盘的状况</param>
    /// <param name="FromX">来的位置X索引</param>
    /// <param name="FromY">来的位置Y索引</param>
    /// <param name="ToX">去的位置X索引</param>
    /// <param name="ToY">去的位置Y索引</param>
    /// <returns></returns>
    public bool IsValidMove(int [,] position,int FromX,int FromY,int ToX,int ToY)
    {
        int moveChessID, targetID;
        moveChessID = position[FromX, FromY];
        targetID = position[ToX, ToY];
        if (IsSameSide(moveChessID,targetID))
        {
            return false;
        }
        return IsVaild(moveChessID,position,FromX,FromY,ToX,ToY);
    }
    /// <summary>
    /// 判断选中的两个游戏物体是否同为空格,同为红棋或者同为黑棋
    /// </summary>
    /// <returns></returns>
    public bool IsSameSide(int x,int y)
    {
        if (IsBlack(x)&&IsBlack(y)||IsRed(x)&&IsRed(y))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    /// <summary>
    /// 判断当前游戏物体是否是黑棋
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    public bool IsBlack(int x)
    {
        if (x>0&&x<8)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    /// <summary>
    /// 判断当前游戏物体是否是红棋
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    public bool IsRed(int x)
    {
        if (x>=8&&x<15)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    /// <summary>
    /// 所有种类棋子的走法是否合法
    /// </summary>
    /// <param name="moveChessID"></param>
    /// <param name="postion"></param>
    /// <param name="FromX"></param>
    /// <param name="FromY"></param>
    /// <param name="ToX"></param>
    /// <param name="ToY"></param>
    public bool IsVaild(int moveChessID,int[,] position,int FromX,int FromY,int ToX,int ToY)
    {
        //目的地与原位置相同
        if (FromX==ToX&&FromY==ToY)
        {
            return false;
        }
        //将帅是否在同一直线上
        if (!KingKill(position,FromX,FromY,ToX,ToY))
        {
            return false;
        }
        int i = 0, j = 0;
        switch (moveChessID)
        {
            //分红黑棋子处理的情况
            case 1://黑将
                //出九宫格
                if (ToX>2||ToY>5||ToY<3)
                {
                    return false;
                }
                //横纵移动只能是一个单元格
                if ((Mathf.Abs(ToX-FromX)+Mathf.Abs(ToY-FromY))>1)
                {
                    return false;
                }
                break;
            case 8://红帅
                //出九宫格
                if (ToX <7 || ToY > 5 || ToY < 3)
                {
                    return false;
                }
                //横纵移动只能是一个单元格
                if ((Mathf.Abs(ToX - FromX) + Mathf.Abs(ToY - FromY)) > 1)
                {
                    return false;
                }
                break;
            case 5://黑士
                //出九宫格
                if (ToX > 2 || ToY > 5 || ToY < 3)
                {
                    return false;
                }
                //士走斜线
                if (Mathf.Abs(FromX-ToX)!=1||Mathf.Abs(FromY-ToY)!=1)
                {
                    return false;
                }
                break;
            case 12://红仕
                //出九宫格
                if (ToX <7 || ToY > 5 || ToY < 3)
                {
                    return false;
                }
                //士走斜线
                if (Mathf.Abs(FromX - ToX) != 1 || Mathf.Abs(FromY - ToY) != 1)
                {
                    return false;
                }
                break;
            case 6://黑象
                //象不能过河
                if (ToX>4)
                {
                    return false;
                }
                //象走田
                if (Mathf.Abs(FromX-ToX)!=2||Mathf.Abs(FromY-ToY)!=2)
                {
                    return false;
                }
                //塞象眼
                if (position[(FromX+ToX)/2,(FromY+ToY)/2]!=0)
                {
                    return false;
                }
                break;
            case 13://红相
                //象不能过河
                if (ToX <5)
                {
                    return false;
                }
                //象走田
                if (Mathf.Abs(FromX - ToX) != 2 || Mathf.Abs(FromY - ToY) != 2)
                {
                    return false;
                }
                //塞象眼
                if (position[(FromX + ToX) / 2, (FromY + ToY) / 2] != 0)
                {
                    return false;
                }
                break;
            case 7://黑卒
                //兵不回头
                if (ToX<FromX)
                {
                    return false;
                }
                //兵过河前只能走竖线
                if (FromX<5&&FromX==ToX)
                {
                    return false;
                }
                //兵只能走一格
                if (ToX-FromX+Mathf.Abs(ToY-FromY)>1)
                {
                    return false;
                }
                break;
            case 14://红兵
                //兵不回头
                if (ToX > FromX)
                {
                    return false;
                }
                //兵过河前只能走竖线
                if (FromX >4 && FromX == ToX)
                {
                    return false;
                }
                //兵只能走一格
                if (FromX-ToX + Mathf.Abs(ToY - FromY) > 1)
                {
                    return false;
                }
                break;
            //不分红黑棋子处理的情况
            case 2:
            case 9://红黑車
                //車走直线
                if (FromY!=ToY&&FromX!=ToX)
                {
                    return false;
                }
                //判断当前移动路径上是否有其他棋子
                if (FromX==ToX)//走横线
                {
                    if (FromY<ToY)//右走
                    {
                        for (i = FromY+1; i < ToY; i++)
                        {
                            if (position[FromX,i]!=0)//代表移动路径上有棋子
                            {
                                return false;
                            }
                        }
                    }
                    else//左走
                    {
                        for (i = ToY+1; i < FromY; i++)
                        {
                            if (position[FromX,i]!=0)
                            {
                                return false;
                            }
                        }
                    }
                }
                else//走竖线
                {
                    if (FromX < ToX)//下走
                    {
                        for (j = FromX+1; j < ToX; j++)
                        {
                            if (position[j,FromY]!=0)
                            {
                                return false;
                            }
                        }
                    }
                    else//上走
                    {
                        for (j = ToX+1; j < FromX; j++)
                        {
                            if (position[j,FromY]!=0)
                            {
                                return false;
                            }
                        }
                    }
                }
                break;
            case 3:
            case 10://红黑马
                //马走日字
                //竖日                                                
                if (!((Mathf.Abs(ToY-FromY)==1&&Mathf.Abs(ToX-FromX)==2)||
                //横日    
                    (Mathf.Abs(ToY-FromY)==2&&Mathf.Abs(ToX-FromX)==1)))
                {
                    return false;
                }
                //马蹩腿
                if (ToY-FromY==2)//右横日
                {
                    i = FromY + 1;
                    j = FromX;
                }
                else if (FromY-ToY==2)//左横日
                {
                    i = FromY - 1;
                    j = FromX;
                }
                else if (ToX-FromX==2)//下竖日
                {
                    i = FromY;
                    j = FromX + 1;
                }
                else if (FromX-ToX==2)//上竖日
                {
                    i = FromY;
                    j = FromX - 1;
                }
                if (position[j,i]!=0)
                {
                    return false;
                }
                break;
            case 4:
            case 11://红黑炮
                //炮走直线
                if (FromY!=ToY&&FromX!=ToX)
                {
                    return false;
                }
                //炮是走棋还是翻山吃子
                //炮移动
                if (position[ToX,ToY]==0)
                {
                    if (FromX==ToX)//炮走横线
                    {
                        if (FromY<ToY)//右走
                        {
                            for (i = FromY+1; i < ToY; i++)
                            {
                                if (position[FromX,i]!=0)
                                {
                                    return false;
                                }
                            }
                        }
                        else//左走
                        {
                            for (i = ToY+1; i < FromY; i++)
                            {
                                if (position[FromX,i]!=0)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                    else//炮走竖线
                    {
                        if (FromX<ToX)//下走
                        {
                            for (j = FromX+1; j < ToX; j++)
                            {
                                if (position[j,FromY]!=0)
                                {
                                    return false;
                                }
                            }
                        }
                        else//上走
                        {
                            for (j = ToX+1; j < FromX; j++)
                            {
                                if (position[j,FromY]!=0)
                                {
                                    return false;
                                }
                            }
                        }
                    }
                }
                //炮翻山吃子
                else
                {
                    int count = 0;
                    if (FromX==ToX)//走横线
                    {
                        if (FromY<ToY)//右走
                        {
                            for (i = FromY+1; i < ToY; i++)
                            {
                                if (position[FromX,i]!=0)
                                {
                                    count++;
                                }
                            }
                            if (count!=1)
                            {
                                return false;
                            }
                        }
                        else//左走
                        {
                            for (i = ToY+1; i < FromY; i++)
                            {
                                if (position[FromX,i]!=0)
                                {
                                    count++;
                                }
                            }
                            if (count!=1)
                            {
                                return false;
                            }
                        }
                    }
                    else//走竖线
                    {
                        if (FromX<ToX)//下走
                        {
                            for (j = FromX+1; j < ToX; j++)
                            {
                                if (position[j,FromY]!=0)
                                {
                                    count++;
                                }
                            }
                            if (count!=1)
                            {
                                return false;
                            }
                        }
                        else//上走
                        {
                            for (j = ToX+1; j < FromX; j++)
                            {
                                if (position[j,FromY]!=0)
                                {
                                    count++;
                                }
                            }
                            if (count!=1)
                            {
                                return false;
                            }
                        }
                    }
                }
                break;
            default:
                break;
        }
        return true;

    }
    /// <summary>
    /// 判断将帅是否是在同一直线上
    /// </summary>
    /// <param name="position"></param>
    /// <param name="FromX"></param>
    /// <param name="FromY"></param>
    /// <param name="ToX"></param>
    /// <param name="ToY"></param>
    /// <returns></returns>
    public bool KingKill(int[,] position, int FromX, int FromY, int ToX, int ToY)
    {
        int jiangX = 0, jiangY = 0, shuaiX = 0, shuaiY = 0;
        int count = 0;
        //假设的思想
        int[,] position1 = new int[10, 9];
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                position1[i, j] = position[i, j];
            }
        }
        //假设它已经走到了那个位置
        position1[ToX, ToY] = position1[FromX, FromY];
        position1[FromX, FromY] = 0;
        //获取将位置
        for (int i = 0; i < 3; i++)
        {
            for (int j = 3; j < 6; j++)
            {
                if (position1[i,j]==1)
                {
                    jiangX = i;
                    jiangY = j;
                }
            }
        }
        //获取帅位置
        for (int i = 7; i < 10; i++)
        {
            for (int j = 3; j < 6; j++)
            {
                if (position1[i,j]==8)
                {
                    shuaiX = i;
                    shuaiY = j;
                }
            }
        }
        if (jiangY==shuaiY)//将帅在一条直线上
        {
            for (int i = jiangX+1; i < shuaiX; i++)
            {
                if (position1[i,jiangY]!=0)
                {
                    count++;
                }
            }
        }
        else//不在一条直线上
        {
            count = -1;
        }
        if (count==0)//不合法
        {
            return false;
        }
        //其他移动都合法
        return true;
    }
}

检测将军类

/// <summary>
/// 检测是否将军
/// </summary>
public class Checkmate
{
    private Chess_Manage gameManager;
    private Chess_UIManage uiManager;

    private int jiangX, jiangY, shuaiX, shuaiY;

    public Checkmate()
    {
        gameManager = Chess_Manage.Instance;
        uiManager = Chess_UIManage.Instance;
    }

    /// <summary>
    /// 是否将军的检测方法
    /// </summary>
    public void JudgeIfCheckmate()
    {
        GetKingPosition();
        //如果从上边方法遍历获取到的索引位置上没有将,将不存在,已经被吃掉了
        if (gameManager.chessBoard[jiangX,jiangY]!=1)
        {
            uiManager.ShowTip("红色棋子胜利");
            gameManager.gameOver = true;
            return;
        }
        //帅不存在,已经被吃掉了
        else if (gameManager.chessBoard[shuaiX,shuaiY]!=8)
        {
            uiManager.ShowTip("黑色棋子胜利");
            gameManager.gameOver = true;
            return;
        }
        //以下是将军的判定
        bool ifCheckmate;//是否将军
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                switch (gameManager.chessBoard[i,j])
                {
                    case 2:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard,i,j,shuaiX,shuaiY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("帅被車将军了");
                        }
                        break;
                    case 3:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, shuaiX, shuaiY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("帅被马将军了");
                        }
                        break;
                    case 4:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, shuaiX, shuaiY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("帅被炮将军了");
                        }
                        break;
                    case 7:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, shuaiX, shuaiY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("帅被卒将军了");
                        }
                        break;
                    case 9:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, jiangX, jiangY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("将被車将军了");
                        }
                        break;
                    case 10:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, jiangX, jiangY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("将被马将军了");
                        }
                        break;
                    case 11:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, jiangX, jiangY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("将被炮将军了");
                        }
                        break;
                    case 14:
                        ifCheckmate = gameManager.rules.IsValidMove(gameManager.chessBoard, i, j, jiangX, jiangY);
                        if (ifCheckmate)
                        {
                            uiManager.ShowTip("将被兵将军了");
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
    /// <summary>
    /// 获取将帅坐标位置的方法
    /// </summary>
    private void GetKingPosition()
    {
        //获取黑将的坐标
        for (int i = 0; i < 3; i++)
        {
            for (int j = 3; j < 6; j++)
            {
                if (gameManager.chessBoard[i,j]==1)
                {
                    jiangX = i;
                    jiangY = j;
                }
            }
        }
        //获取红帅的坐标
        for (int i = 7; i < 10; i++)
        {
            for (int j = 3; j < 6; j++)
            {
                if (gameManager.chessBoard[i,j]==8)
                {
                    shuaiX = i;
                    shuaiY = j;
                }
            }
        }
    }
}

悔棋

/// <summary>
/// 悔棋类
/// </summary>
public class ChessReseting
{
   private Chess_Manage gameManager;

    //计数器,用来计数当前一共走了几步棋
    public int resetCount;
    //悔棋数组,用来存放所有已经走过的步数用来悔棋
    public Chess[] chessSteps;

    public ChessReseting()
    {
        gameManager = Chess_Manage.Instance;
    }
    /// <summary>
    /// 记录每一步悔棋的具体棋子结构体
    /// </summary>
    public struct Chess
    {
        public ChessSteps from;
        public ChessSteps to;
        public GameObject gridOne;//来的位置所在格子
        public GameObject gridTwo;//去的位置所在格子
        public GameObject chessOne;
        public GameObject chessTwo;
        public int chessOneID;
        public int chessTwoID;
    }
    /// <summary>
    /// 棋子位置
    /// </summary>
    public struct ChessSteps
    {
        public int x;
        public int y;
    }
    /// <summary>
    /// 悔棋方法
    /// </summary>
    public void ResetChess()
    {
        gameManager.HideLastPositionUI();
        gameManager.HideClickUI();
        gameManager.HideCanEatUI();
        if (gameManager.chessPeople==1)//单机PVE
        {

        }
        else if(gameManager.chessPeople==2)//单机PVP
        {
            if (resetCount<=0)//没有下一步棋,不存在悔棋
            {
                return;
            }
            int f = resetCount - 1;//因为索引是从0开始的
            int oneID = chessSteps[f].chessOneID;//棋子原来位置的ID
            int twoID = chessSteps[f].chessTwoID;//棋子移动到位置的ID
            GameObject gridOne, gridTwo, chessOne, chessTwo;
            gridOne = chessSteps[f].gridOne;
            gridTwo = chessSteps[f].gridTwo;
            chessOne = chessSteps[f].chessOne;
            chessTwo = chessSteps[f].chessTwo;
            //Debug.Log(chessSteps [f].from.x + "," + chessSteps [f].from.y + "--" + chessSteps [f].to.x + "," + chessSteps [f].to.y);
            //吃子
            if (chessTwo!=null)
            {
                chessOne.transform.SetParent(gridOne.transform);
                chessTwo.transform.SetParent(gridTwo.transform);
                chessOne.transform.localPosition = Vector3.zero;
                chessTwo.transform.localPosition = Vector3.zero;
                gameManager.chessBoard[chessSteps[f].from.x, chessSteps[f].from.y] = oneID;
                gameManager.chessBoard[chessSteps[f].to.x, chessSteps[f].to.y] = twoID;
            }
            //移动 
            else
            {
                chessOne.transform.SetParent(gridOne.transform);
                chessOne.transform.localPosition = Vector3.zero;
                gameManager.chessBoard[chessSteps[f].from.x, chessSteps[f].from.y] = oneID;
                gameManager.chessBoard[chessSteps[f].to.x, chessSteps[f].to.y] = 0;
            }
            //该黑方走了,但是红方悔棋
            if (gameManager.chessMove==false)
            {
                Chess_UIManage.Instance.ShowTip("红方走");
                gameManager.chessMove = true;
            }
            //该红方走了,但是黑方悔棋
            else
            {
                Chess_UIManage.Instance.ShowTip("黑方走");
                gameManager.chessMove = false;
            }
            resetCount -= 1;
            chessSteps[f] = new Chess();
        }
    }
    /// <summary>
    /// 添加悔棋步骤(用来之后悔棋)
    /// </summary>
    /// <param name="resetStepNum">具体的悔棋步数索引</param>
    /// <param name="fromX"></param>
    /// <param name="fromY"></param>
    /// <param name="toX"></param>
    /// <param name="toY"></param>
    /// <param name="ID1">对应悔棋那一步的第一个棋子ID</param>
    /// <param name="ID2">对应悔棋那一步的第二个ID</param>
    public void AddChess(int resetStepNum,int fromX,int fromY,int toX,int toY,int ID1,int ID2)
    {
        //当前需要记录的这步棋中的数据存入我们的chess结构体里,然后存进结构体数组
        GameObject item1 = gameManager.boardGrid[fromX, fromY];
        GameObject item2 = gameManager.boardGrid[toX, toY];
        chessSteps[resetStepNum].from.x = fromX;
        chessSteps[resetStepNum].from.y = fromY;
        chessSteps[resetStepNum].to.x = toX;
        chessSteps[resetStepNum].to.y = toY;
        chessSteps[resetStepNum].gridOne = item1;
        chessSteps[resetStepNum].gridTwo = item2;
        gameManager.HideCanEatUI();
        gameManager.HideClickUI();
        GameObject firstChess = item1.transform.GetChild(0).gameObject;
        chessSteps[resetStepNum].chessOne = firstChess;
        chessSteps[resetStepNum].chessOneID = ID1;
        chessSteps[resetStepNum].chessTwoID = ID2;
        //如果是吃子
        if (item2.transform.childCount!=0)
        {
            GameObject secondChess = item2.transform.GetChild(0).gameObject;
            chessSteps[resetStepNum].chessTwo = secondChess;
        }
        resetCount++;
        //Debug.Log("第" + resetCount + "步添加");
        //Debug.Log("Item1:" + item1.name);
        //Debug.Log("Item2:" + item2.name);
        //Debug.Log("firstChess:" + firstChess.name);
        //if (chessSteps[resetStepNum].chessTwo != null)
        //{
        //    Debug.Log("secondChess:" + chessSteps[resetStepNum].chessTwo.name);
        //}
    }
}

UI类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 控制页面之间的显示与跳转、按钮的触发方法,在Chess_GameManage之后实例化
/// </summary>
public class Chess_UIManage : MonoBehaviour
{
    #region 游戏中的UI方法
    /// <summary>
    /// 悔棋
    /// </summary>
    public void UnDo()
    {
        chessGameManage.chessReseting.ResetChess();
    }

    /// <summary>
    /// 重玩
    /// </summary>
    public void Replay()
    {
        chessGameManage.Replay();
    }

    /// <summary>
    /// 下棋轮次以及信息的提示
    /// </summary>
    /// <param name="str"></param>
    public void ShowTip(string str)
    {
        //测试
        tipUIText = tipUITexts[0];
        //******
        
        tipUIText.text = str;
    }

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/894761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分享一套SpringBoot+Vue民宿(预约)系统

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue民宿(预约)系统&#xff0c;分享下嘿嘿。 项目介绍 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c…

如何使用Jconsole查看进程里面的多线程的情况

1.代码分析 下面的这个就是使用的我们的start创建新的线程&#xff0c;然后让两个线程交叉运行&#xff08;这个其实是通过我们的结果打印看出来的&#xff09;&#xff0c;我们可以看到这个hello main和这个hello thread是交叉显示打印输出的&#xff1b; 2.JDK软件包 因为上…

IP地理位置定位系统之应用场景划分

IP地理位置定位系统是一个街道级别的、实时的IP地理位置查询系统。该系统采用超高精度IP实时定位技术&#xff0c;通过网络测量和大数据挖掘&#xff0c;对IP的地理位置和相关属性进行测量&#xff0c;在无需硬件支持的条件下&#xff0c;即可对被探测目标终端IP完成定位。 应…

二叉树刷题(JAVA)

引入&#xff1a; 递归是一种在函数定义中使用函数自身的方法。它是一种常见的编程技巧&#xff0c;用于解决可以被分解为相同问题的子问题的问题。 递归函数通常包含两个部分&#xff1a;基本情况和递归情况。 基本情况是指递归函数停止调用自身的条件。当满足基本情况时&a…

流体力学笔记

目录 1、名词2、湍流与涡流3 涡激振动4 压力面与吸力面参考&#xff1a;[空气动力学的“他山之石”](https://zhuanlan.zhihu.com/p/412542513) 1、名词 转列&#xff1a;transition 涡脱落&#xff1a;vortex shedding 涡分离&#xff1a;vortex rupture 气动噪声&#xff1a…

代码训练营 day39|0-1背包问题,LeetCode 416

前言 这里记录一下陈菜菜的刷题记录&#xff0c;主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕&#xff0c;一年车企软件开发经验 代码能力&#xff1a;有待提高 常用语言&#xff1a;C 系列文章目录 第九章 动态规划part03 文章目录 前言系列文章目录第九章 动态…

GDAL+C#实现矢量多边形转栅格

1. 开发环境测试 参考C#配置GDAL环境&#xff0c;确保GDAL能使用&#xff0c;步骤简述如下&#xff1a; 创建.NET Framework 4.7.2的控制台应用 注意&#xff1a; 项目路径中不要有中文&#xff0c;否则可能报错&#xff1a;can not find proj.db 在NuGet中安装GDAL 3.9.1和G…

达梦数据库性能优化

1、SQL执行计划 拿到一条SQL的时候&#xff0c;首先要下达梦手册中提出的有效SQL规范&#xff0c;及是否命中了特殊OR子句的不规范&#xff0c;是否用了复杂的正则表达式&#xff0c;避免重复很高的索引&#xff0c;UINON ALL 是否可以替换UNION操作等,某些场景INSTR函数导致的…

ParallelsDesktop20最新版本虚拟机 一键切换系统 游戏娱乐两不误

让工作生活更高效&#xff1a;Parallels Desktop 20最新版本虚拟机的神奇之处 大家好&#xff01;&#x1f44b; 今天我要跟大家安利一款让我工作效率飞升的神器——Parallels Desktop 20最新版本虚拟机。作为一个日常需要在不同操作系统间来回穿梭的人&#xff0c;这款软件简直…

【升华】python基础包NumPy学习

NumPy是使用Python进行科学计算的基础软件包。除其他外&#xff0c;它包括&#xff1a; 功能强大的N维数组对象。精密广播功能函数。集成 C/C和Fortran 代码的工具。强大的线性代数、傅立叶变换和随机数功能。 # 1、安装包 $ pip install numpy# 2、进入python的交互式界面 $…

从零开始学PHP之helloworld

前言 每一门编程语言的第一个程序就是输出hell world&#xff08;别杠&#xff0c;杠就是你对&#xff09; 开始 上一篇讲完了开发环境的安装&#xff0c;这次讲编辑器的安装&#xff0c;顺带完成上一篇的作业&#xff08;输出hello world&#xff09; 安装PHPstorm 我用的…

前端布局与响应式设计综合指南(末)

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Css篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来Css篇专栏内容:前端布局与响应式设计综合指南(末) 目录 61、为什么要初始化CSS样式 62、CSS3 有哪些新特性 63、…

【python】NumPy(三):文件读写

目录 ​前言 NumPy 常见IO函数 save()和load() savez() loadtxt()和savetxt() 练习 前言 在数据分析中&#xff0c;我们经常需要从文件中读取数据或者将数据写入文件&#xff0c;常见的文件格式有&#xff1a;文本文件txt、CSV格式文件&#xff08;用逗号分隔&#xff…

vue-router钩子中调用ElMessage等样式出错

升级 vue3.5 时遇到奇怪的问题, 页面点击离开没反应 经过排查, 是以下几点相互作用导致此问题 vue 有应用上下文的概念, 例如 runWithContext API,vue-router 在调用钩子时会获取 vue 的应用上下文element-plus 在唤起弹窗时会从 parent 或 应用上下文上拿到 config 信息eleme…

大数据环境 hbase+ phoenix idea

1、选择jdk 2、添加驱动 3、添加数据源

【精选】基于javaweb的流浪动物领养系统(源码+定制+开发)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

《重置MobaXterm密码并连接Linux虚拟机的完整操作指南》

目录 引言 一、双击MobaXterm_Personal_24.2进入&#xff0c;但是忘记密码。 那么接下来请跟着我操作。 二、点击此链接&#xff0c;重设密码。 三、下载完成后&#xff0c;现在把这个exe文件解压。注意解压要与MobaXterm_Personal_24.2.exe在同一目录下哦&#xff0c;不然…

从零入门AI篡改图片检测(金融场景)#Datawhale十月组队学习

1.大赛背景 在全球人工智能发展和治理广受关注的大趋势下&#xff0c;由中国图象图形学学会、蚂蚁集团、云安全联盟CSA大中华区主办&#xff0c;广泛联合学界、机构共同组织发起全球AI攻防挑战赛。本次比赛包含攻防两大赛道&#xff0c;分别聚焦大模型自身安全和大模型生成内容…

pc轨迹回放制作

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 课程主题&#xff1a;pc轨迹回放制作 主要内容&#xff1a;制作车辆轨迹操作页&#xff0c;包括查询条件、动态轨迹回放、车辆轨迹详情表单等 应用场景&#xff1a;车辆…

sqli-labs less-25a

Sqli-labs less-25a 判断注入类型&#xff0c;列数及注入点 构造 http://192.168.140.130/sq/Less-25a/?id1 回显正常 http://192.168.140.130/sq/Less-25a/?id1’ 报错 构造 http://192.168.140.130/sq/Less-25a/?id1 and 11 回显正常 http://192.168.140.130/sq/Less-25a…