using System.Collections; using Godot; using Godot.Collections; public partial class ChessGame : Node2D { ChessBoard board; Global global; ConfirmationDialog dialog; private bool isSession = false; private Player playerSelf; private Player playerOpponent; // Called when the node enters the scene tree for the first time. public override void _Ready() { // Init.Call(); global = GetNode("/root/Global"); board = GetNode("Chessboard"); isSession = global.RPClient.IsOnline(); playerSelf = new Player(board.board, Player.PlayerType.Human); playerOpponent = new Player(board.board, Player.PlayerType.Human); InitChessBoard(); GetNode("Control/VBoxContainer/MarginContainer3/HFlowContainer/LineEdit") .Text = global.GlobalData["player_color"].AsString(); GD.PrintErr("ChessGame ", global.RPClient.GetUserId(), ":",global.GlobalData["player_color"]); dialog = new ConfirmationDialog { DialogAutowrap = true, MinSize = new Vector2I(400, 200), Position = new Vector2I(200, 400), }; AddChild(dialog); board.OnPosClicked += (sender, pos) => { if (isSession) { 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); } }; if (isSession) { GD.Print("ws is connected"); global.RPClient.OnPRCSessionExit += (cmd, code) => { GoHome(); }; global.RPClient.OnPRCSessionRecv += (msg) => { SessionMsgHandle(msg["msg"].AsGodotDictionary()); }; } } // Called every frame. 'delta' is the elapsed time since the previous frame. 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()) { case "over": if (global.RPClient.GetUserId() == msg["id"].AsString()) { break; } dialog.Title = "Opponent Finished"; dialog.DialogText = "Turn On You\n"; dialog.Visible = true; break; case "mouseClicked": if (msg["id"].ToString() == global.RPClient.GetUserId()) { break; } Vector2 mouseClicked = new(GD.StrToVar(msg["X"].ToString()).AsInt32(), GD.StrToVar(msg["Y"].ToString()).AsInt32()); playerOpponent.HandleBoardPosClick(mouseClicked); break; case "undo": if (msg["id"].ToString() == global.RPClient.GetUserId()) { break; } playerOpponent.Undo(); break; case "reInit": _ReInit(); break; } } private void _ReInit() { playerSelf.ReInit(); InitChessBoard(); } private void BtnOver() { GD.Print($"BtnOver {isSession}"); if (isSession == false) { return; } global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{ {"type", "over"}, {"id", global.RPClient.GetUserId()}, }); } public void GoHome() { if (global.RPClient.IsOnline()) { global.RPClient.ExitServer(); } global.GotoScene("res://Main.tscn"); } public void Undo() { GD.Print($"Undo {isSession}"); if (isSession) { playerSelf.Undo(); global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{ {"type", "undo"}, {"id", global.RPClient.GetUserId()}, }); } else { playerSelf.Undo(); } } public void ReInit() { GD.PrintErr($"ReInit {isSession}"); if (isSession) { global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{ {"type", "reInit"}, }); } else { _ReInit(); } } }