126 lines
3.2 KiB
C#
126 lines
3.2 KiB
C#
using Vector2 = Godot.Vector2;
|
|
using System;
|
|
using System.Collections;
|
|
|
|
public class Player {
|
|
private readonly VirtualBoard board;
|
|
private readonly SelectedPiece selectedNode;
|
|
private readonly MoveRecords<VirtualPiece> moveRecords;
|
|
public EventHandler<VirtualBoard.MoveEventArgs> OnMove;
|
|
public ArrayList pieces = new();
|
|
|
|
public enum PlayerType {
|
|
Human,
|
|
AI
|
|
}
|
|
|
|
public Player(VirtualBoard board, PlayerType type = PlayerType.Human)
|
|
{
|
|
this.board = board;
|
|
this.selectedNode = new SelectedPiece(board);
|
|
this.moveRecords = new MoveRecords<VirtualPiece>(onUndoRecordCallback: (newNode, oldNode, newPos, oldPos) => {
|
|
// GD.Print("Undo: ", newNode, "->", oldNode, ":", newPos, "->", oldPos);
|
|
VirtualPiece newPiece = newNode;
|
|
VirtualPiece oldPiece = oldNode;
|
|
this.board.MovePiece(newPos, oldPos);
|
|
if (newPiece != null) {
|
|
this.board.InsertPiece(newPiece, newPos);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void HandleBoardPosClick(Vector2 clickPos) {
|
|
if (board.ArrPosOutOfRange(clickPos)) return;
|
|
// GD.Print($"VirtualBoard {clickPos} clicked");
|
|
VirtualPiece clickChess = board.GetPiece(clickPos);
|
|
|
|
if (!selectedNode.HasSelected()) {
|
|
// Select piece
|
|
if (clickChess == null) {
|
|
// selectedNode.Clear();
|
|
return;
|
|
}
|
|
selectedNode.SetPos(clickPos);
|
|
} else if (clickChess == selectedNode.GetPiece()) {
|
|
// Unselect piece
|
|
selectedNode.Clear();
|
|
} else {
|
|
// Move piece
|
|
// GD.Print("default MoveFunc Move: ", selectedNode.GetPos(), "->", clickPos);
|
|
MoveAndRecord(clickPos, selectedNode.GetPos());
|
|
}
|
|
}
|
|
|
|
public void MoveAndRecord(Vector2 toPos, Vector2 fromPos) {
|
|
// GD.Print($"{fromPos} move to {toPos}");
|
|
VirtualPiece toChess = board.GetPiece(toPos);
|
|
VirtualPiece fromChess = board.GetPiece(fromPos);
|
|
fromChess?.Selected(false);
|
|
|
|
VirtualPiece NowNode;
|
|
if (toChess != null) {
|
|
NowNode = toChess;
|
|
board.RemovePiece(toPos);
|
|
} else {
|
|
NowNode = toChess;
|
|
}
|
|
moveRecords.AddRecord(NowNode, fromChess, toPos, fromPos);
|
|
|
|
OnMove?.Invoke(this, new VirtualBoard.MoveEventArgs { From = fromPos, To = toPos });
|
|
board.MovePiece(fromPos, toPos);
|
|
|
|
selectedNode.Clear();
|
|
}
|
|
|
|
public void Undo() {
|
|
// ChessPiece selected = selectedNode.GetPiece();
|
|
// selected?.DeSelected();
|
|
selectedNode.Clear();
|
|
moveRecords.Undo();
|
|
}
|
|
|
|
public void ReInit() {
|
|
moveRecords.Clear();
|
|
board.Clear();
|
|
selectedNode.Clear();
|
|
// board.InitChessBoard();
|
|
}
|
|
|
|
private class SelectedPiece {
|
|
// Called when the node enters the scene tree for the first time.
|
|
private Vector2 selectedNodePos = Vector2.Inf;
|
|
private VirtualPiece piece;
|
|
private readonly VirtualBoard board;
|
|
|
|
public SelectedPiece(VirtualBoard board) {
|
|
this.board = board;
|
|
}
|
|
|
|
public void Clear() {
|
|
if (selectedNodePos != Vector2.Inf) {
|
|
selectedNodePos = Vector2.Inf;
|
|
piece.Selected(false);
|
|
}
|
|
}
|
|
|
|
public void SetPos(Vector2 pos) {
|
|
// piece = board.GetNodeFromBoard(pos) as VirtualPiece;
|
|
selectedNodePos = pos;
|
|
piece = board.GetPiece(selectedNodePos);
|
|
piece.Selected(true);
|
|
}
|
|
|
|
public VirtualPiece GetPiece() {
|
|
return piece;
|
|
}
|
|
|
|
public Vector2 GetPos() {
|
|
return selectedNodePos;
|
|
}
|
|
|
|
public bool HasSelected() {
|
|
return selectedNodePos != Vector2.Inf;
|
|
}
|
|
}
|
|
}
|