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 (); */ }
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(); }
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); }
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(); }
/** * @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); }
// 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); }
/** * @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); }
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); }