예제 #1
0
        public static void Main(string[] args)
        {
            CurrentBoard      = new Board();
            CurrentGameStatus = GameStatus.Inactive;
            PieceMoves.InitiateChessPieceMoves();
            PiecePseudoLegalMoves.GeneratePseudoLegalMoves(CurrentBoard);
            PieceLegalMoves.GenerateLegalMoves(CurrentBoard);
            EngineStopTokenSource = new CancellationTokenSource();
            BoardOrientation      = PieceColour.White;
            WhiteClock            = new ChessClock(PieceColour.White, new TimeSpan(0, 30, 0));
            BlackClock            = new ChessClock(PieceColour.Black, new TimeSpan(0, 30, 0));
            StrengthValue         = 7;
            CurrentMode           = GameMode.OnePlayer;
            CurrentGameHistory    = new GameHistory();

            Application.Init();
            win = new MainWindow();
            win.UpdateClock(WhiteClock);
            win.UpdateClock(BlackClock);
            win.InitWidgets();
            win.Show();
            Application.Run();

            /*
             * UCITransceiver uci = new UCITransceiver ("./stockfish_6_x64");
             * uci.Init ();
             * Console.WriteLine (uci.EngineName);
             * Console.WriteLine (uci.EngineAuthor);
             * uci.SendPosition ("rn2kbnr/ppq2pp1/2p1p2p/7P/3P4/3Q1NN1/PPP2PP1/R1B1K2R w KQkq - 0 11");
             * uci.Go ();
             * Thread.Sleep (5000);
             * Console.WriteLine (uci.StopAndGetBestMove ());
             * uci.Quit ();
             */
        }
예제 #2
0
 protected void OnResetBoard(object sender, EventArgs e)
 {
     MainClass.CurrentBoard      = new Board();
     MainClass.CurrentGameStatus = GameStatus.Inactive;
     MainClass.ResetClock();
     PiecePseudoLegalMoves.GeneratePseudoLegalMoves(MainClass.CurrentBoard);
     PieceLegalMoves.GenerateLegalMoves(MainClass.CurrentBoard);
     MainClass.CurrentGameHistory = new GameHistory();
     ClearGameHistoryView();
     RedrawBoard();
 }
예제 #3
0
        public void UndoMove(byte originalSource, byte originalDestination, Piece capturedPiece,
                             PieceType?originalPromoteTo = null)
        {
            Piece movingPiece = Squares [originalDestination].Piece;

            // Special rules for castling
            if (movingPiece.Type == PieceType.King &&
                Array.IndexOf(castleDestinations, originalDestination) != -1 &&
                capturedPiece != null &&
                capturedPiece.Colour == movingPiece.Colour)
            {
                Square castleRookSquare = originalDestination - originalSource > 0 ?
                                          Squares [originalDestination - 1] : Squares [originalDestination + 1];
                Squares [originalSource].Piece      = movingPiece;
                Squares [originalDestination].Piece = null;
                Squares [originalDestination - originalSource > 0 ?
                         originalDestination + 1 :
                         originalDestination - 2].Piece = castleRookSquare.Piece;
                castleRookSquare.Piece = null;
            }
            else
            {
                if (originalPromoteTo != null)
                {
                    Squares [originalSource].Piece = new Piece(movingPiece.Colour, PieceType.Pawn);
                }
                else
                {
                    Squares [originalSource].Piece = movingPiece;
                }
                Squares [originalDestination].Piece = capturedPiece;
            }

            if (PlayerToMove == PieceColour.White)
            {
                PlayerToMove = PieceColour.Black;
            }
            else
            {
                PlayerToMove = PieceColour.White;
            }
            PiecePseudoLegalMoves.GeneratePseudoLegalMoves(this);
        }
예제 #4
0
        protected void OnImportPGN(object sender, EventArgs e)
        {
            var fc = new FileChooserDialog("Choose a PGN file to open.",
                                           this,
                                           FileChooserAction.Open,
                                           "Cancel", ResponseType.Cancel,
                                           "Open", ResponseType.Accept);

            if (fc.Run() == (int)ResponseType.Accept)
            {
                MainClass.CurrentGameHistory = GameHistory.importPGN(File.ReadAllText(fc.Filename));
                string pgn = MainClass.CurrentGameHistory.ToPGNString();
                int    indexOfMovesStart = pgn.IndexOf("1.");
                if (indexOfMovesStart > 0)
                {
                    GameHistoryView.Buffer.Text = pgn.Substring(indexOfMovesStart);
                }

                // Load the FEN from the last move
                FENParser parser = new FENParser(MainClass.CurrentGameHistory.GetLastMove().FEN);
                MainClass.CurrentBoard      = parser.GetBoard();
                MainClass.CurrentGameStatus = GameStatus.Inactive;
                PiecePseudoLegalMoves.GeneratePseudoLegalMoves(MainClass.CurrentBoard);
                PieceLegalMoves.GenerateLegalMoves(MainClass.CurrentBoard);
                Gtk.Application.Invoke(delegate {
                    RedrawBoard();
                });

                MainClass.CurrentGameStatus = GameStatus.Inactive;
                GameStatus currentStatus = MainClass.CurrentBoard.CheckForMate();
                if (currentStatus != GameStatus.Inactive && currentStatus != GameStatus.Active)
                {
                    Gtk.Application.Invoke(delegate {
                        ShowGameOverDialog(currentStatus);
                    });
                }
                MainClass.ResetClock();
                UpdateMaterialDifference(MainClass.CurrentBoard);
            }
            fc.Destroy();
        }
예제 #5
0
        /**
         * @fn UndoMove
         * @brief Undoes a move.
         *
         * Undoes a move by doing the complete reverse of MakeMove and then
         * regenerating legal moves.
         */

        public void UndoMove(byte originalSource, byte originalDestination, bool[] lastCastles,
                             PieceType?originalPromoteTo = null)
        {
            Piece movingPiece = Squares[originalDestination].Piece;

            // Special rules for castling
            if (movingPiece.Type == PieceType.King &&
                Array.IndexOf(castleDestinations, originalDestination) != -1)
            {
                Square castleRookSquare = originalDestination - originalSource > 0 ?
                                          Squares[originalDestination - 1] : Squares[originalDestination + 1];
                Squares[originalSource].Piece      = movingPiece;
                Squares[originalDestination].Piece = null;
                Squares[originalDestination - originalSource > 0 ?
                        originalDestination + 1 :
                        originalDestination - 2].Piece = castleRookSquare.Piece;
                castleRookSquare.Piece = null;
                BlackCastledR          = lastCastles[0];
                WhiteCastledR          = lastCastles[1];
                BlackCastledL          = lastCastles[2];
                WhiteCastledL          = lastCastles[3];
            }
            else
            {
                Squares[originalSource].Piece      = movingPiece;
                Squares[originalDestination].Piece = null;
            }

            if (PlayerToMove == PieceColour.White)
            {
                PlayerToMove = PieceColour.Black;
            }
            else
            {
                PlayerToMove = PieceColour.White;
            }
            PiecePseudoLegalMoves.GeneratePseudoLegalMoves(this);
            PieceLegalMoves.GenerateLegalMoves(this);
        }
예제 #6
0
        // Returns value of captured piece, for use in DummyBoard.UndoMove
        public new Piece MakeMove(byte source, byte destination, PieceType?promoteTo = null)
        {
            Piece movingPiece   = Squares [source].Piece;
            Piece capturedPiece = null;

            // Special rules for castling
            if (movingPiece.Type == PieceType.King &&
                (source == 4 || source == 60) &&
                Array.IndexOf(castleDestinations, destination) != -1)
            {
                Square castleRookSquare = destination - source > 0 ?
                                          Squares [destination + 1] : Squares [destination - 2];
                capturedPiece = castleRookSquare.Piece;
                Squares [destination].Piece = movingPiece;
                Squares [source].Piece      = null;
                Squares [destination - source > 0 ?
                         destination - 1 :
                         destination + 1].Piece = castleRookSquare.Piece;
                castleRookSquare.Piece          = null;
            }
            else
            {
                // Handle en passant.
                if (Squares [source].Piece.Type == PieceType.Pawn)
                {
                    if (Array.IndexOf(enPassantStartSquares, source) > -1 && Array.IndexOf(enPassantEndSquares, destination) > -1)
                    {
                        EnPassantColour = Squares [source].Piece.Colour;
                        EnPassantSquare = EnPassantColour == PieceColour.White ? (byte)(destination + 8) : (byte)(destination - 8);
                    }
                    else
                    {
                        EnPassantSquare = 0;
                    }
                }

                capturedPiece = Squares [destination].Piece;
                switch (promoteTo)
                {
                case PieceType.Bishop:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Bishop);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Knight:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Knight);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Rook:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Rook);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Queen:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Knight);
                    Squares [source].Piece      = null;
                    break;

                default:
                    // Handle en passant capture
                    if (movingPiece.Type == PieceType.Pawn && destination == EnPassantSquare && EnPassantSquare != 0)
                    {
                        byte captureSquare = EnPassantColour == PieceColour.White ? (byte)(destination - 8) : (byte)(destination + 8);
                        Squares [destination].Piece = movingPiece;
                        capturedPiece = Squares [captureSquare].Piece;
                        Squares [captureSquare].Piece = null;
                        Squares [source].Piece        = null;
                    }
                    else
                    {
                        Squares [destination].Piece = movingPiece;
                        Squares [source].Piece      = null;
                    }
                    break;
                }
            }

            if (PlayerToMove == PieceColour.White)
            {
                PlayerToMove = PieceColour.Black;
            }
            else
            {
                PlayerToMove = PieceColour.White;
            }
            if (!(movingPiece.Type == PieceType.Pawn &&
                  ((int)(destination / 8) == 0 ||
                   (int)(destination / 8) == 7)))
            {
                PiecePseudoLegalMoves.GeneratePseudoLegalMoves(this);
            }
            return(capturedPiece);
        }
예제 #7
0
        /**
         * @fn MakeMove
         * @brief Makes a move.
         *
         * Makes a move, switches the @c PlayerToMove variable,
         * and updates piece legal moves.
         */
        public MoveResult MakeMove(byte source, byte destination, PieceType?promoteTo = null)
        {
            MoveResult ret = MoveResult.None;

            if (!IsMoveValid(source, destination))
            {
                throw new InvalidOperationException("Invalid move entered.");
            }
            Piece movingPiece = Squares [source].Piece;

            // Forbid castling if the king moves.
            if (movingPiece.Type == PieceType.King)
            {
                if (movingPiece.Colour == PieceColour.White)
                {
                    WhiteCastledR = true;
                    WhiteCastledL = true;
                }
                else
                {
                    BlackCastledR = true;
                    BlackCastledL = true;
                }
            }

            if (movingPiece.Type == PieceType.Rook)
            {
                if (source == 0)
                {
                    BlackCastledL = true;
                }
                else if (source == 7)
                {
                    BlackCastledR = true;
                }
                else if (source == 56)
                {
                    WhiteCastledL = true;
                }
                else if (source == 63)
                {
                    WhiteCastledR = true;
                }
            }

            // Special rules for castling
            if (movingPiece.Type == PieceType.King &&
                (source == 4 || source == 60) &&
                Array.IndexOf(castleDestinations, destination) != -1)
            {
                ret = destination - source > 0 ? MoveResult.KingsideCastle : MoveResult.QueensideCastle;
                Square castleRookSquare = destination - source > 0 ?
                                          Squares [destination + 1] : Squares [destination - 2];
                Squares [destination].Piece = movingPiece;
                Squares [source].Piece      = null;
                Squares [destination - source > 0 ?
                         destination - 1 :
                         destination + 1].Piece = castleRookSquare.Piece;
                castleRookSquare.Piece          = null;
            }
            else
            {
                // Handle pawn moves
                if (Squares [source].Piece.Type == PieceType.Pawn)
                {
                    ret = MoveResult.PawnMove;
                    // Handle en passant creation
                    if (Array.IndexOf(enPassantStartSquares, source) > -1 && Array.IndexOf(enPassantEndSquares, destination) > -1)
                    {
                        EnPassantColour = Squares [source].Piece.Colour;
                        EnPassantSquare = EnPassantColour == PieceColour.White ? (byte)(destination + 8) : (byte)(destination - 8);
                    }
                }
                if (Squares [destination].Piece != null)
                {
                    ret = MoveResult.Capture;
                }
                switch (promoteTo)
                {
                case PieceType.Bishop:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Bishop);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Knight:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Knight);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Rook:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Rook);
                    Squares [source].Piece      = null;
                    break;

                case PieceType.Queen:
                    Squares [destination].Piece = new Piece(movingPiece.Colour, PieceType.Queen);
                    Squares [source].Piece      = null;
                    break;

                default:
                    // Handle en passant capture
                    if (movingPiece.Type == PieceType.Pawn && destination == EnPassantSquare && EnPassantSquare != 0)
                    {
                        byte captureSquare = EnPassantColour == PieceColour.White ? (byte)(destination - 8) : (byte)(destination + 8);
                        Squares [destination].Piece   = movingPiece;
                        Squares [captureSquare].Piece = null;
                        Squares [source].Piece        = null;
                        ret             = MoveResult.Capture;
                        EnPassantSquare = 0;
                    }
                    else
                    {
                        Squares [destination].Piece = movingPiece;
                        Squares [source].Piece      = null;
                        if (movingPiece.Type != PieceType.Pawn)
                        {
                            EnPassantSquare = 0;
                        }
                    }
                    break;
                }

                Gtk.Application.Invoke(delegate {
                    MainClass.win.UpdateMaterialDifference(new Board(this));
                });
            }

            if (PlayerToMove == PieceColour.White)
            {
                PlayerToMove = PieceColour.Black;
            }
            else
            {
                PlayerToMove = PieceColour.White;
            }
            PiecePseudoLegalMoves.GeneratePseudoLegalMoves(this);
            PieceLegalMoves.GenerateLegalMoves(this);
            return(ret);
        }
예제 #8
0
        public static GameHistory importPGN(string PGN)
        {
            GameHistory newGameHistory = new GameHistory();
            //Parse tag pairs first
            string startingFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";

            while (PGN.Contains("["))
            {
                string tagPair = PGN.Substring(PGN.IndexOf('[') + 1, PGN.IndexOf(']') - PGN.IndexOf('[') - 1);
                PGN = PGN.Substring(PGN.IndexOf(']') + 1);

                switch (tagPair.Substring(0, tagPair.IndexOf(' ')))
                {
                case "Event":
                    newGameHistory.Event = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "Site":
                    newGameHistory.Site = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "Date":
                    newGameHistory.Date = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "Round":
                    newGameHistory.Round = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "White":
                    newGameHistory.White = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "Black":
                    newGameHistory.Black = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "Result":
                    newGameHistory.Result = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                case "FEN":
                    startingFEN = tagPair.Substring(tagPair.IndexOf('"') + 1).TrimEnd('"');
                    break;

                default:
                    break;
                }
            }
            //Remove comments from PGN
            while (PGN.Contains("{"))
            {
                PGN = PGN.Remove(PGN.IndexOf('{'), PGN.IndexOf('}') - PGN.IndexOf('{') + 1);
            }

            //Take in moves one by one
            FENParser importFEN = new FENParser(startingFEN);
            Board     gameBoard = importFEN.GetBoard();

            PiecePseudoLegalMoves.GeneratePseudoLegalMoves(gameBoard);
            PieceLegalMoves.GenerateLegalMoves(gameBoard);

            List <Tuple <Move, string> > possibleMoveNotations = getPossibleMoveNotations(gameBoard);

            string[] tokens = PGN.Split(null);

            for (int i = 0; i < tokens.Length; i++)
            {
                char[] trimChars    = { '!', '?' };
                char[] checkChars   = { '+', '#' };
                string moveNotation = tokens[i].Trim(trimChars);

                if (moveNotation.Contains('.'))
                {
                    moveNotation = moveNotation.Substring(moveNotation.IndexOf('.') + 1);
                }

                if (moveNotation.Length != 0)
                {
                    //Console.WriteLine("***" + moveNotation + "***"); //debugging output
                    for (int j = 0; j < possibleMoveNotations.Count; j++)
                    {
                        //Console.Write(possibleMoveNotations[j].Item2 + " ");
                        if (moveNotation.Equals(possibleMoveNotations[j].Item2) || moveNotation.Equals(possibleMoveNotations[j].Item2.Trim(checkChars)))
                        {
                            gameBoard.MakeMove(possibleMoveNotations[j].Item1.Source, possibleMoveNotations[j].Item1.Destination, possibleMoveNotations[j].Item1.PromoteTo);
                            newGameHistory.AddMove(possibleMoveNotations[j].Item1, gameBoard.ToFEN().Split(' ')[0]);
                            possibleMoveNotations = getPossibleMoveNotations(gameBoard);
                            break;
                        }
                    }
                    //Console.WriteLine(""); //debugging output
                }
            }
            return(newGameHistory);
        }