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