/// <summary> /// Do a move, return the taken piece /// </summary> /// <param name="move"></param> /// <returns></returns> public Piece?DoMove(Move move, Func <Position, Piece.PieceType> promote) { var taken = this[move.To]; var mover = this[move.From].Value; mover.HasEverMoved = true; var promotionRank = mover.Owner == Piece.Colour.White ? 7 : 0; if (mover.Type == Piece.PieceType.Pawn && move.To.Rank == promotionRank) { mover.Type = promote(move.To); } this[move.To] = mover; this[move.From] = null; if (Detect2KingsStalemate()) { Stalemate?.Invoke(); } return(taken); }
public IEnumerable <Move> GetMoves(Piece.Colour player) { var moves = GetPositions(player) .Select(position => GetMoves(position)) .SelectMany(x => x); if (!moves.Any()) { var kingpos = KingPosition(player); if (UnderAttack(kingpos, player.Opposite())) { Checkmate?.Invoke(player.Opposite()); } else { Stalemate?.Invoke(); } } return(moves); }
public async override void _Ready() { bool gameRunning = true; Board = new Board(); Board.Checkmate += winner => { gameRunning = false; GD.Print($"Checkmate! {winner} wins."); Checkmate?.Invoke(winner); }; Board.Stalemate += () => { gameRunning = false; GD.Print("Stalemate!"); Stalemate?.Invoke(); }; UI = GetNode <UI>("UI"); var squares = GetNode <Control>("Squares"); var colour = Piece.Colour.Black; for (int i = 0; i < Board.Size; i++) { for (int j = 0; j < Board.Size; j++) { var square = new SquareNode(this, colour, new Position(j, i)); square.Clicked += position => { SquareClicked?.Invoke(position); }; Squares[j, i] = square; squares.AddChild(square); colour = colour.Opposite(); } colour = colour.Opposite(); } // WhitePlayer = new HumanPlayer(this, Piece.Colour.White); //BlackPlayer = new HumanPlayer(this, Piece.Colour.Black); //WhitePlayer = new RandomPlayer(this, Piece.Colour.White); //BlackPlayer = new RandomPlayer(this, Piece.Colour.Black); //WhitePlayer = new AIPlayer(this, Piece.Colour.White); // BlackPlayer = new AIPlayer(this, Piece.Colour.Black); var drawer = new PieceDrawer(this); squares.AddChild(drawer); CurrentPlayer = Piece.Colour.White; while (true) { LegalMoves = Board.GetMoves(CurrentPlayer).ToHashSet(); if (!gameRunning) { break; } var move = await Current.GetMoveAsync(); await Task.Delay(10); GD.Print($"{CurrentPlayer} wants to move {move}"); await Task.Run(() => Board.DoMove(move, p => Current.Promote(p).Result)); drawer.Update(); CurrentPlayer = CurrentPlayer.Opposite(); } }