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

embedded/2024/10/18 12:30:05/

中国象棋

  • 一级目录
    • 二级目录
      • 三级目录
  • 棋类游戏的难度等级
  • 自我对弈代码
    • 游戏管理器
    • 棋子和格子
    • 棋子移动类
    • 棋子规则类
    • 检测将军类
    • 悔棋
    • 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 联网 3public 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黑falsepublic bool gameOver;//游戏结束不能走棋/// <summary>/// 资源/// </summary>public GameObject gridGo;//格子public Sprite[] sprites;//所有棋子的spritepublic 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 updatevoid Start(){//仅做测试chessPeople = 2;ResetGame();  }// Update is called once per framevoid 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 updatevoid 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;//棋子原来位置的IDint twoID = chessSteps[f].chessTwoID;//棋子移动到位置的IDGameObject 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;}

在这里插入图片描述


http://www.ppmy.cn/embedded/127777.html

相关文章

SpringBoot+MyBatis+MySQL项目基础搭建

一、新建项目 1.1 新建springboot项目 新建项目 选择SpringBoot&#xff0c;填写基本信息&#xff0c;主要是JDK版本和项目构建方式&#xff0c;此处以JDK17和Maven举例。 1.2 引入依赖 选择SpringBoot版本&#xff0c;勾选Lombok&#xff0c;Spring Web&#xff0c;MyBa…

C#删除dataGridView 选中行

关键在于&#xff1a;从最后一行开始删除。 从前往后删只能删除其中一半&#xff0c;我理解是再remove行的时候dataGridView内部行序列发生了变化&#xff0c;包含在选中行中的特定行会被忽略&#xff0c;从后往前删就可避免这个问题&#xff0c;最后一行的行号影响不到前面的…

OceanBase 从架构到实战应用的技术探索

1. 引言 1.1 OceanBase 简介 OceanBase 是蚂蚁集团自主研发的一款分布式关系型数据库&#xff0c;专为应对金融级别的高并发、高可用性需求而设计。它不仅支持强一致性事务处理&#xff0c;还具备高扩展性&#xff0c;能够应对大规模的数据存储和高频率的查询请求。作为一款新…

截图贴图工具 | PixPin v1.9.0 绿色版

PixPin是一款功能强大且使用简单的截图和贴图工具&#xff0c;它旨在帮助用户提高工作效率。PixPin的主要功能包括截图、贴图、标注、文本识别、长截图和截动图。它允许用户自由选择或自动探测窗口来设定截图范围&#xff0c;精准截取所需内容&#xff0c;并将所截取的图像“贴…

Merlion笔记(二):单变量时间预测

1 简单示例 我们首先导入Merlion的TimeSeries类和M4数据集的数据加载器。然后&#xff0c;我们可以将该数据集中的特定时间序列划分为训练集和测试集。 from merlion.utils import TimeSeries from ts_datasets.forecast import M4time_series, metadata M4(subset"Hou…

数据结构——二叉树(下)

数据结构——二叉树&#xff08;下&#xff09; 文章目录 数据结构——二叉树&#xff08;下&#xff09;一、引言&#xff1a;接上文使用顺序结构的数组存储堆&#xff08;一种二叉树&#xff09;&#xff0c;在这篇文章我们来了解一下堆的应用。 1、堆排序2、TOP-K问题 二、实…

C#学习笔记(二)

第 二 章 命名空间和类、数据类型、变量和代码规范 深水区 一、命名空间 1. 作用与具体表达形式 我们开发一个项目&#xff0c;有时候会有很多的代码&#xff0c;这些代码都分布到不同的类中&#xff0c;也就是类会很多&#xff0c;类多了&#xff0c;就需要划分命名空间来…

一个常见问题:TCP和UDP是否可以使用一个端口

TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;做为两种被广泛使用的协议&#xff0c;它们在处理数据时采用不同的机制&#xff0c;那么有一个问题&#xff0c;在同一系统内&#xff0c;TCP和UDP的服务是否可以使用同一个端口呢&#xf…