feat(chinese-chess): 实现中国象棋核心逻辑和基本功能

- 抽象出 ChessCore 类,包含游戏初始化、行棋逻辑、悔棋等功能
- 重构 Player 类,优化行棋和记录逻辑
- 更新 ChessBoard 和 ChessPiece 类,适应新逻辑
- 移除冗余代码,提高代码可读性和可维护性
This commit is contained in:
ZZY
2024-11-07 20:48:08 +08:00
parent 6daf09b300
commit 8ee9732a6f
9 changed files with 225 additions and 121 deletions

View File

@ -1,29 +1,27 @@
using System.Collections;
using Godot;
using Godot.Collections;
using ChineseChess;
public partial class ChessGame : Node2D {
ChessBoard board;
Global global;
ConfirmationDialog dialog;
private bool isSession = false;
private Player playerSelf;
private Player playerOpponent;
ChessCore Game;
ChessCore.TurnsSideType sideSelf;
ChessCore.TurnsSideType sideOpposite;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
public override void _Ready() {
// Init.Call();
global = GetNode<Global>("/root/Global");
board = GetNode<ChessBoard>("Chessboard");
isSession = global.RPClient.IsOnline();
playerSelf = new Player(board.board, Player.PlayerType.Human);
playerOpponent = new Player(board.board, Player.PlayerType.Human);
InitChessBoard();
GetNode<LineEdit>("Control/VBoxContainer/MarginContainer3/HFlowContainer/LineEdit")
.Text = global.GlobalData["player_color"].AsString();
LineEdit turnSideEdit = GetNode<LineEdit>("Control/VBoxContainer/MarginContainer3/HFlowContainer/LineEdit2");
turnSideEdit.Text = "red";
GD.PrintErr("ChessGame ", global.RPClient.GetUserId(), ":",global.GlobalData["player_color"]);
dialog = new ConfirmationDialog {
@ -33,18 +31,37 @@ public partial class ChessGame : Node2D {
};
AddChild(dialog);
if (global.GlobalData["player_color"].AsString() == "red") {
sideSelf = ChessCore.TurnsSideType.Red;
sideOpposite = ChessCore.TurnsSideType.Black;
} else {
sideSelf = ChessCore.TurnsSideType.Black;
sideOpposite = ChessCore.TurnsSideType.Red;
}
if (isSession) {
Game = new(ChessCore.Mode.MultiMode, sideSelf);
} else {
Game = new(ChessCore.Mode.SingleMode, sideSelf);
}
board.LoadBoard(Game.board);
Game.InitGame();
Game.board.OnMove += (sender, e) => {
turnSideEdit.Text = Game.GetTurnsType() == ChessCore.TurnsSideType.Red ? "red" : "black";
};
board.OnPosClicked += (sender, pos) => {
if (isSession) {
Game.OnPosClicked(pos, ChessCore.PlayerSideType.Self);
var res = global.RPClient.SendSessionToAll(global.sessionId, new Dictionary {
{"type", "mouseClicked"},
{"X", pos.X},
{"Y", pos.Y},
{"id", global.RPClient.GetUserId()}
});
playerSelf.HandleBoardPosClick(pos);
} else {
playerSelf.HandleBoardPosClick(pos);
playerSelf.SetAllowedPieces(null);
Game.OnPosClicked(pos);
}
};
@ -65,44 +82,6 @@ public partial class ChessGame : Node2D {
public override void _Process(double delta) {
}
public void InitChessBoard() {
ArrayList black = InitializePieces("black", 0, new[] {
("车", 0, 0), ("马", 1, 0), ("象", 2, 0),
("士", 3, 0), ("将", 4, 0), ("士", 5, 0),
("象", 6, 0), ("马", 7, 0), ("车", 8, 0),
("炮", 1, 2), ("炮", 7, 2),
("卒", 0, 3), ("卒", 2, 3), ("卒", 4, 3), ("卒", 6, 3), ("卒", 8, 3)
});
ArrayList red = InitializePieces("red", 9, new[] {
("车", 0, -0), ("马", 1, -0), ("象", 2, -0),
("士", 3, -0), ("将", 4, -0), ("士", 5, -0),
("象", 6, -0), ("马", 7, -0), ("车", 8, -0),
("炮", 1, -2), ("炮", 7, -2),
("卒", 0, -3), ("卒", 2, -3), ("卒", 4, -3), ("卒", 6, -3), ("卒", 8, -3)
});
if (global.GlobalData["player_color"].AsString() == "red") {
playerSelf.SetAllowedPieces(red);
playerOpponent.SetAllowedPieces(black);
} else {
playerSelf.SetAllowedPieces(black);
playerOpponent.SetAllowedPieces(red);
}
}
private ArrayList InitializePieces(string color, int baseY, (string label, int x, int y)[] positions) {
ArrayList list = new();
foreach (var (label, x, y) in positions) {
ChessPiece piece = new ChessPiece {
PieceLabel = label,
LabelColor = new Color(color)
};
list.Add(piece.GetVirtualPiece());
board.InsertNode(piece, new Vector2(x, baseY + y));
}
return list;
}
private void SessionMsgHandle(Dictionary msg) {
GD.PrintErr($"session msg: {msg}");
switch (msg["type"].AsString()) {
@ -120,25 +99,17 @@ public partial class ChessGame : Node2D {
}
Vector2 mouseClicked = new(GD.StrToVar(msg["X"].ToString()).AsInt32(),
GD.StrToVar(msg["Y"].ToString()).AsInt32());
playerOpponent.HandleBoardPosClick(mouseClicked);
Game.OnPosClicked(mouseClicked, ChessCore.PlayerSideType.Opponent);
break;
case "undo":
if (msg["id"].ToString() == global.RPClient.GetUserId()) {
break;
}
playerOpponent.Undo();
Game.Undo();
break;
case "reInit":
_ReInit();
Game.ReInit();
break;
}
}
private void _ReInit() {
playerSelf.ReInit();
InitChessBoard();
}
private void BtnOver() {
GD.Print($"BtnOver {isSession}");
if (isSession == false) {
@ -161,13 +132,12 @@ public partial class ChessGame : Node2D {
GD.Print($"Undo {isSession}");
if (isSession) {
playerSelf.Undo();
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
{"type", "undo"},
{"id", global.RPClient.GetUserId()},
});
} else {
playerSelf.Undo();
Game.Undo();
}
}
@ -179,7 +149,7 @@ public partial class ChessGame : Node2D {
{"type", "reInit"},
});
} else {
_ReInit();
Game.ReInit();
}
}
}