/// <summary> /// Parse a single PGN/FEN game /// </summary> /// <param name="strText"> PGN Text</param> /// <param name="bIgnoreMoveListIfFEN"> Ignore the move list if FEN is found</param> /// <param name="listMovePos"> Returned the list of move if not null</param> /// <param name="iSkip"> Number of games skipped</param> /// <param name="iTruncated"> Number of games truncated</param> /// <param name="chessBoardStarting"> Starting board setting. If null, standard board used.</param> /// <param name="eStartingColor"> Starting color</param> /// <param name="strWhitePlayerName"> White pieces player name</param> /// <param name="strBlackPlayerName"> Black pieces player name</param> /// <param name="eWhitePlayerType"> White pieces player type</param> /// <param name="eBlackPlayerType"> Black pieces player type</param> /// <param name="spanWhitePlayer"> Time span for white player</param> /// <param name="spanBlackPlayer"> Time span for black player</param> /// <returns> /// false if the board specified by FEN is invalid. /// </returns> public bool ParseSingle(string strText, bool bIgnoreMoveListIfFEN, List <ChessBoard.MovePosS> listMovePos, out int iSkip, out int iTruncated, out ChessBoard chessBoardStarting, out ChessBoard.PlayerColorE eStartingColor, out string strWhitePlayerName, out string strBlackPlayerName, out PlayerTypeE eWhitePlayerType, out PlayerTypeE eBlackPlayerType, out TimeSpan spanWhitePlayer, out TimeSpan spanBlackPlayer) { bool bRetVal = true; int[] piMoveList; Dictionary <string, string> attrs; listMovePos.Clear(); chessBoardStarting = null; eStartingColor = ChessBoard.PlayerColorE.White; strWhitePlayerName = "Player 1"; strBlackPlayerName = "Player 2"; eWhitePlayerType = PlayerTypeE.Human; eBlackPlayerType = PlayerTypeE.Human; spanWhitePlayer = TimeSpan.Zero; spanBlackPlayer = TimeSpan.Zero; m_strText = strText; m_iPos = 0; m_iSize = strText.Length; iSkip = 0; iTruncated = 0; if (!ParseIfFENLine(strText, out eStartingColor, out chessBoardStarting)) { SkipAltMoveAndRemark(); if (PeekChr() != '\0') { m_iStartPos = m_iPos; bRetVal = ParseNextMoveList(bIgnoreMoveListIfFEN, out piMoveList, out attrs, listMovePos, ref iSkip, ref iTruncated, out chessBoardStarting, out eStartingColor, out strWhitePlayerName, out strBlackPlayerName, out eWhitePlayerType, out eBlackPlayerType, out spanWhitePlayer, out spanBlackPlayer); } } return(bRetVal); }
/// <summary> /// Create a new game using the specified list of moves /// </summary> /// <param name="chessBoardStarting"> Starting board or null if standard board</param> /// <param name="listMove"> List of moves</param> /// <param name="eNextMoveColor"> Color starting to play</param> /// <param name="strWhitePlayerName"> Name of the player playing white pieces</param> /// <param name="strBlackPlayerName"> Name of the player playing black pieces</param> /// <param name="eWhitePlayerType"> Type of player playing white pieces</param> /// <param name="eBlackPlayerType"> Type of player playing black pieces</param> /// <param name="spanPlayerWhite"> Timer for white</param> /// <param name="spanPlayerBlack"> Timer for black</param> public override void CreateGameFromMove(ChessBoard chessBoardStarting, List <MoveExt> listMove, ChessBoard.PlayerE eNextMoveColor, string strWhitePlayerName, string strBlackPlayerName, PlayerTypeE eWhitePlayerType, PlayerTypeE eBlackPlayerType, TimeSpan spanPlayerWhite, TimeSpan spanPlayerBlack) { base.CreateGameFromMove(chessBoardStarting, listMove, eNextMoveColor, strWhitePlayerName, strBlackPlayerName, eWhitePlayerType, eBlackPlayerType, spanPlayerWhite, spanPlayerBlack); if (eWhitePlayerType == PlayerTypeE.Program) { if (eBlackPlayerType == PlayerTypeE.Program) { Father.PlayingMode = MainWindow.PlayingModeE.ComputerPlayBoth; } else { Father.PlayingMode = MainWindow.PlayingModeE.ComputerPlayWhite; } } else if (eBlackPlayerType == PlayerTypeE.Program) { Father.PlayingMode = MainWindow.PlayingModeE.ComputerPlayBlack; } else { Father.PlayingMode = MainWindow.PlayingModeE.PlayerAgainstPlayer; } Father.SetCmdState(); }
/// <summary> /// Parse one game in PGN /// </summary> /// <param name="bIgnoreMoveListIfFEN"> Ignore the move list if FEN is found</param> /// <param name="piMoveList"> Returned move list</param> /// <param name="attrs"> Returned list of attributes for this game</param> /// <param name="listMovePos"> Returned the list of move if not null</param> /// <param name="iSkip"> Number of games skipped</param> /// <param name="iTruncated"> Number of games truncated</param> /// <param name="chessBoardStarting"> Starting board setting. If null, standard board used.</param> /// <param name="eStartingColor"> Starting color</param> /// <param name="strWhitePlayerName"> White pieces player name</param> /// <param name="strBlackPlayerName"> Black pieces player name</param> /// <param name="eWhitePlayerType"> White pieces player type</param> /// <param name="eBlackPlayerType"> Black pieces player type</param> /// <param name="spanWhitePlayer"> Time span for white player</param> /// <param name="spanBlackPlayer"> Time span for black player</param> /// <returns> /// false if invalid board /// </returns> /// <remarks> /// /// The parser understand an extended version of the [TimeControl] tag: /// /// [TimeControl "?:123:456"] where 123 = white tick count, 456 = black tick count (100 nano-sec unit) /// /// The parser also understand the following standard tags: /// /// [White] [Black] [FEN] [WhiteType] [BlackType] /// /// </remarks> private bool ParseNextMoveList(bool bIgnoreMoveListIfFEN, out int[] piMoveList, out Dictionary <string, string> attrs, List <ChessBoard.MovePosS> listMovePos, ref int iSkip, ref int iTruncated, out ChessBoard chessBoardStarting, out ChessBoard.PlayerColorE eStartingColor, out string strWhitePlayerName, out string strBlackPlayerName, out PlayerTypeE eWhitePlayerType, out PlayerTypeE eBlackPlayerType, out TimeSpan spanWhitePlayer, out TimeSpan spanBlackPlayer) { bool bRetVal = true; bool bEndOfMove; bool bFENFound; List <string> arrRawMove; int iMoveIndex; string strMove; string strFEN; string[] arrStr; string[] arrTimeControl; int iTick1; int iTick2; attrs = new Dictionary <string, string>(10); chessBoardStarting = null; eStartingColor = ChessBoard.PlayerColorE.White; piMoveList = null; arrRawMove = new List <string>(256); SkipAltMoveAndRemark(); while (PeekChr() == '[') { ParseAttr(attrs); SkipAltMoveAndRemark(); } strWhitePlayerName = (attrs.ContainsKey("WHITE")) ? attrs["WHITE"] : "Player 1"; strBlackPlayerName = (attrs.ContainsKey("BLACK")) ? attrs["BLACK"] : "Player 2"; if (attrs.ContainsKey("WHITETYPE")) { eWhitePlayerType = (attrs["WHITETYPE"].ToLower() == "program") ? PlayerTypeE.Program : PlayerTypeE.Human; } else { eWhitePlayerType = PlayerTypeE.Human; } if (attrs.ContainsKey("BLACKTYPE")) { eBlackPlayerType = (attrs["BLACKTYPE"].ToLower() == "program") ? PlayerTypeE.Program : PlayerTypeE.Human; } else { eBlackPlayerType = PlayerTypeE.Human; } arrTimeControl = (attrs.ContainsKey("TIMECONTROL")) ? attrs["TIMECONTROL"].Split(':') : null; if (arrTimeControl != null && arrTimeControl.Length == 3 && arrTimeControl[0] == "?" && Int32.TryParse(arrTimeControl[1], out iTick1) && Int32.TryParse(arrTimeControl[2], out iTick2)) { spanWhitePlayer = new TimeSpan(iTick1); spanBlackPlayer = new TimeSpan(iTick2); } else { spanWhitePlayer = TimeSpan.Zero; spanBlackPlayer = TimeSpan.Zero; } bFENFound = attrs.ContainsKey("FEN"); m_chessBoard.ResetBoard(); if (bFENFound) { strFEN = attrs["FEN"]; bRetVal = ParseFEN(strFEN, out eStartingColor, out chessBoardStarting); } if (bRetVal && !(bFENFound && bIgnoreMoveListIfFEN)) { iMoveIndex = 1; bEndOfMove = false; while (!bEndOfMove && ParseRawMove(iMoveIndex, out strMove)) { arrStr = strMove.Split(' '); if (arrStr.Length == 2) { arrRawMove.Add(arrStr[0]); arrRawMove.Add(arrStr[1]); } else if (arrStr.Length == 1) { arrRawMove.Add(arrStr[0]); } else { bEndOfMove = true; } iMoveIndex++; } if (arrRawMove.Count == 0) { if (m_bDiagnose) { throw new PgnParserException("Syntax error", GetCodeInError()); } iSkip++; } CnvRawMoveToPosMove(eStartingColor, arrRawMove, out piMoveList, listMovePos, ref iSkip, ref iTruncated); } return(bRetVal); }
/// <summary> /// Generates the PGN representation of the board /// </summary> /// <param name="chessBoard"> Actual chess board (after the move)</param> /// <param name="bIncludeRedoMove"> true to include redo move</param> /// <param name="strEvent"> Event tag</param> /// <param name="strSite"> Site tag</param> /// <param name="strDate"> Date tag</param> /// <param name="strRound"> Round tag</param> /// <param name="strWhitePlayer"> White player's name</param> /// <param name="strBlackPlayer"> Black player's name</param> /// <param name="eWhitePlayerType"> White player's type</param> /// <param name="eBlackPlayerType"> Black player's type</param> /// <param name="spanWhitePlayer"> Timer for the white</param> /// <param name="spanBlackPlayer"> Timer for the black</param> /// <returns> /// PGN representation of the game /// </returns> public static string GetPGNFromBoard(ChessBoard chessBoard, bool bIncludeRedoMove, string strEvent, string strSite, string strDate, string strRound, string strWhitePlayer, string strBlackPlayer, PlayerTypeE eWhitePlayerType, PlayerTypeE eBlackPlayerType, TimeSpan spanWhitePlayer, TimeSpan spanBlackPlayer) { int iMoveIndex; StringBuilder strBuilder; StringBuilder strBuilderLine; int iOriIndex; int iMoveCount; MovePosStack movePosStack; MoveExt move; string strResult; movePosStack = chessBoard.MovePosStack; iOriIndex = movePosStack.PositionInList; iMoveCount = (bIncludeRedoMove) ? movePosStack.Count : iOriIndex + 1; strBuilder = new StringBuilder(10 * iMoveCount + 256); strBuilderLine = new StringBuilder(256); switch (chessBoard.GetCurrentResult()) { case ChessBoard.GameResultE.Check: case ChessBoard.GameResultE.OnGoing: strResult = "*"; break; case ChessBoard.GameResultE.Mate: strResult = (chessBoard.CurrentPlayer == ChessBoard.PlayerE.White) ? "0-1" : "1-0"; break; case ChessBoard.GameResultE.FiftyRuleRepeat: case ChessBoard.GameResultE.ThreeFoldRepeat: case ChessBoard.GameResultE.TieNoMove: case ChessBoard.GameResultE.TieNoMatePossible: strResult = "1/2-1/2"; break; default: strResult = "*"; break; } chessBoard.UndoAllMoves(); strBuilder.Append("[Event \"" + strEvent + "\"]\n"); strBuilder.Append("[Site \"" + strSite + "\"]\n"); strBuilder.Append("[Date \"" + strDate + "\"]\n"); strBuilder.Append("[Round \"" + strRound + "\"]\n"); strBuilder.Append("[White \"" + strWhitePlayer + "\"]\n"); strBuilder.Append("[Black \"" + strBlackPlayer + "\"]\n"); strBuilder.Append("[Result \"" + strResult + "\"]\n"); if (!chessBoard.StandardInitialBoard) { strBuilder.Append("[SetUp \"1\"]\n"); strBuilder.Append("[FEN \"" + GetFENFromBoard(chessBoard) + "\"]\n"); } strBuilder.Append("[WhiteType \"" + ((eWhitePlayerType == PlayerTypeE.Human) ? "human" : "program") + "\"]\n"); strBuilder.Append("[BlackType \"" + ((eBlackPlayerType == PlayerTypeE.Human) ? "human" : "program") + "\"]\n"); strBuilder.Append("[TimeControl \"?:" + spanWhitePlayer.Ticks.ToString() + ":" + spanBlackPlayer.Ticks.ToString() + "\"]\n"); strBuilder.Append('\n'); iMoveIndex = 0; strBuilderLine.Length = 0; for (iMoveIndex = 0; iMoveIndex < iMoveCount; iMoveIndex++) { if (strBuilderLine.Length > 60) { strBuilder.Append(strBuilderLine); strBuilder.Append("\n"); strBuilderLine.Length = 0; } move = movePosStack[iMoveIndex]; if ((iMoveIndex & 1) == 0) { strBuilderLine.Append(((iMoveIndex + 1) / 2 + 1).ToString()); strBuilderLine.Append(". "); } strBuilderLine.Append(GetPGNMoveFromMove(chessBoard, move, true) + " "); chessBoard.RedoMove(); } strBuilderLine.Append(' '); strBuilderLine.Append(strResult); strBuilder.Append(strBuilderLine); strBuilder.Append('\n'); return(strBuilder.ToString()); }
//********************************************************* // /// <summary> /// Parse a single PGN game /// </summary> /// <param name="strText"> PGN Text</param> /// <param name="bIgnoreMoveListIfFEN"> Ignore the move list if FEN is found</param> /// <param name="listMovePos"> Returned the list of move if not null</param> /// <param name="iSkip"> Number of games skipped</param> /// <param name="iTruncated"> Number of games truncated</param> /// <param name="chessBoardStarting"> Starting board setting. If null, standard board used.</param> /// <param name="eStartingColor"> Starting color</param> /// <param name="strWhitePlayerName"> White pieces player name</param> /// <param name="strBlackPlayerName"> Black pieces player name</param> /// <param name="eWhitePlayerType"> White pieces player type</param> /// <param name="eBlackPlayerType"> Black pieces player type</param> /// <param name="spanWhitePlayer"> Time span for white player</param> /// <param name="spanBlackPlayer"> Time span for black player</param> /// <returns> /// false if the board specified by FEN is invalid. /// </returns> // //********************************************************* public bool ParseSingle(string strText, bool bIgnoreMoveListIfFEN, List<ChessBoard.MovePosS> listMovePos, out int iSkip, out int iTruncated, out ChessBoard chessBoardStarting, out ChessBoard.PlayerColorE eStartingColor, out string strWhitePlayerName, out string strBlackPlayerName, out PlayerTypeE eWhitePlayerType, out PlayerTypeE eBlackPlayerType, out TimeSpan spanWhitePlayer, out TimeSpan spanBlackPlayer) { bool bRetVal = true; int[] piMoveList; Dictionary<string,string> attrs; listMovePos.Clear(); chessBoardStarting = null; eStartingColor = ChessBoard.PlayerColorE.White; strWhitePlayerName = "Player 1"; strBlackPlayerName = "Player 2"; eWhitePlayerType = PlayerTypeE.Human; eBlackPlayerType = PlayerTypeE.Human; spanWhitePlayer = TimeSpan.Zero; spanBlackPlayer = TimeSpan.Zero; m_strText = strText; m_iPos = 0; m_iSize = strText.Length; iSkip = 0; iTruncated = 0; SkipAltMoveAndRemark(); if (PeekChr() != '\0') { m_iStartPos = m_iPos; bRetVal = ParseNextMoveList(bIgnoreMoveListIfFEN, out piMoveList, out attrs, listMovePos, ref iSkip, ref iTruncated, out chessBoardStarting, out eStartingColor, out strWhitePlayerName, out strBlackPlayerName, out eWhitePlayerType, out eBlackPlayerType, out spanWhitePlayer, out spanBlackPlayer); } return(bRetVal); }
//********************************************************* // /// <summary> /// Parse one game in PGN /// </summary> /// <param name="bIgnoreMoveListIfFEN"> Ignore the move list if FEN is found</param> /// <param name="piMoveList"> Returned move list</param> /// <param name="attrs"> Returned list of attributes for this game</param> /// <param name="listMovePos"> Returned the list of move if not null</param> /// <param name="iSkip"> Number of games skipped</param> /// <param name="iTruncated"> Number of games truncated</param> /// <param name="chessBoardStarting"> Starting board setting. If null, standard board used.</param> /// <param name="eStartingColor"> Starting color</param> /// <param name="strWhitePlayerName"> White pieces player name</param> /// <param name="strBlackPlayerName"> Black pieces player name</param> /// <param name="eWhitePlayerType"> White pieces player type</param> /// <param name="eBlackPlayerType"> Black pieces player type</param> /// <param name="spanWhitePlayer"> Time span for white player</param> /// <param name="spanBlackPlayer"> Time span for black player</param> /// <returns> /// false if invalid board /// </returns> /// <remarks> /// /// The parser understand an extended version of the [TimeControl] tag: /// /// [TimeControl "?:123:456"] where 123 = white tick count, 456 = black tick count (100 nano-sec unit) /// /// The parser also understand the following standard tags: /// /// [White] [Black] [FEN] [WhiteType] [BlackType] /// /// </remarks> // //********************************************************* private bool ParseNextMoveList(bool bIgnoreMoveListIfFEN, out int[] piMoveList, out Dictionary<string, string> attrs, List<ChessBoard.MovePosS> listMovePos, ref int iSkip, ref int iTruncated, out ChessBoard chessBoardStarting, out ChessBoard.PlayerColorE eStartingColor, out string strWhitePlayerName, out string strBlackPlayerName, out PlayerTypeE eWhitePlayerType, out PlayerTypeE eBlackPlayerType, out TimeSpan spanWhitePlayer, out TimeSpan spanBlackPlayer) { bool bRetVal = true; bool bEndOfMove; bool bFENFound; List<string> arrRawMove; int iMoveIndex; string strMove; string strFEN; string[] arrStr; string[] arrTimeControl; ChessBoard.BoardStateMaskE eBoardMask; int iEnPassant; int iTick1; int iTick2; attrs = new Dictionary<string,string>(10); chessBoardStarting = null; eStartingColor = ChessBoard.PlayerColorE.White; piMoveList = null; arrRawMove = new List<string>(256); SkipAltMoveAndRemark(); while (PeekChr() == '[') { ParseAttr(attrs); SkipAltMoveAndRemark(); } strWhitePlayerName = (attrs.ContainsKey("WHITE")) ? attrs["WHITE"] : "Player 1"; strBlackPlayerName = (attrs.ContainsKey("BLACK")) ? attrs["BLACK"] : "Player 2"; if (attrs.ContainsKey("WHITETYPE")) { eWhitePlayerType = (attrs["WHITETYPE"].ToLower() == "program") ? PlayerTypeE.Program : PlayerTypeE.Human; } else { eWhitePlayerType = PlayerTypeE.Human; } if (attrs.ContainsKey("BLACKTYPE")) { eBlackPlayerType = (attrs["BLACKTYPE"].ToLower() == "program") ? PlayerTypeE.Program : PlayerTypeE.Human; } else { eBlackPlayerType = PlayerTypeE.Human; } arrTimeControl = (attrs.ContainsKey("TIMECONTROL")) ? attrs["TIMECONTROL"].Split(':') : null; if (arrTimeControl != null && arrTimeControl.Length == 3 && arrTimeControl[0] == "?" && Int32.TryParse(arrTimeControl[1], out iTick1) && Int32.TryParse(arrTimeControl[2], out iTick2)) { spanWhitePlayer = new TimeSpan(iTick1); spanBlackPlayer = new TimeSpan(iTick2); } else { spanWhitePlayer = TimeSpan.Zero; spanBlackPlayer = TimeSpan.Zero; } bFENFound = attrs.ContainsKey("FEN"); m_chessBoard.ResetBoard(); if (bFENFound) { strFEN = attrs["FEN"]; m_chessBoard.OpenDesignMode(); bRetVal = ParseFEN(strFEN, out eStartingColor, out eBoardMask, out iEnPassant); m_chessBoard.CloseDesignMode(eStartingColor, eBoardMask, iEnPassant); if (bRetVal) { chessBoardStarting = m_chessBoard.Clone(); } } if (bRetVal && !(bFENFound && bIgnoreMoveListIfFEN)) { iMoveIndex = 1; bEndOfMove = false; while (!bEndOfMove && ParseRawMove(iMoveIndex, out strMove)) { arrStr = strMove.Split(' '); if (arrStr.Length == 2) { arrRawMove.Add(arrStr[0]); arrRawMove.Add(arrStr[1]); } else if (arrStr.Length == 1) { arrRawMove.Add(arrStr[0]); } else { bEndOfMove = true; } iMoveIndex++; } if (arrRawMove.Count == 0) { if (m_bDiagnose) { throw new PgnParserException("Syntax error", GetCodeInError()); } iSkip++; } CnvRawMoveToPosMove(eStartingColor, arrRawMove, out piMoveList, listMovePos, ref iSkip, ref iTruncated); } return(bRetVal); }