/// <summary> /// Play a decoded move /// </summary> /// <param name="moveLine"> Move line</param> /// <returns> /// true if succeed, false if failed /// </returns> public bool PlayMove(Style12MoveLine moveLine) { bool bRetVal; string strError; bRetVal = PlayMove(moveLine, true /*bShowError*/, out strError); return(bRetVal); }
/// <summary> /// Process a move line /// </summary> /// <param name="strLine"> Line to analyze</param> /// <returns> /// true if a move line has been found, false if not /// </returns> private bool ProcessSingleMove(string strLine) { bool bRetVal; Style12MoveLine moveLine; int iGameId; string strError; TerminationE eTermination; string strTerminationComment; GameIntf gameIntf; moveLine = Style12MoveLine.ParseLine(strLine, out iGameId, out eTermination, out strTerminationComment, out strError); if (strError != null) { m_ctlMain.Dispatcher.Invoke((Action)(() => { m_ctlMain.ShowError("Error decoding a move - " + strError + "\r\n(" + strLine + ")"); })); bRetVal = true; } else if (moveLine != null || eTermination != TerminationE.None) { bRetVal = true; gameIntf = m_state.FindGameIntf(iGameId); if (gameIntf != null) { if (eTermination == TerminationE.None) { if (!gameIntf.PlayMove(moveLine)) { m_state.TerminateGame(gameIntf, TerminationE.TerminatedWithErr, "", strError); } } else { m_state.TerminateGame(gameIntf, eTermination, strTerminationComment, null); } } } else { bRetVal = false; } return(bRetVal); }
/// <summary> /// Parse a line /// </summary> /// <param name="strLine"> Line to parse</param> /// <param name="iGameId"> Game ID</param> /// <param name="eTermination"> Termination code if error or if game has ended</param> /// <param name="strTerminationComment"> Termination comment if any</param> /// <param name="strError"> Returned error if any. null if no error detected</param> /// <returns> /// Line or null if not a style12 line or error /// </returns> static public Style12MoveLine ParseLine(string strLine, out int iGameId, out TerminationE eTermination, out string strTerminationComment, out string strError) { Style12MoveLine lineRetVal; string[] arrParts; string strFENLine; ChessBoard.PieceE ePiece; int iLine; int iPos; int[] arrIntVal; eTermination = IsMoveTermination(strLine, out iGameId, out strTerminationComment, out strError); if (eTermination != TerminationE.None) { lineRetVal = null; } else { arrParts = GetLineParts(strLine); if (arrParts == null) { lineRetVal = null; } else { lineRetVal = new Style12MoveLine(); iPos = 63; iLine = 0; arrIntVal = new int[11]; while (iLine < 8 && strError == null) { strFENLine = arrParts[iLine + 1]; if (strFENLine.Length != 8) { strError = "Illegal board definition - bad FEN line size"; } else { foreach (char chr in strFENLine) { if (DecodePiece(chr, out ePiece)) { lineRetVal.Board[iPos--] = ePiece; } else { strError = "Illegal board definition - Unknown piece specification '" + chr + "'"; break; } } } iLine++; } if (strError == null) { switch (arrParts[9]) { case "B": lineRetVal.NextMovePlayer = ChessBoard.PlayerE.Black; break; case "W": lineRetVal.NextMovePlayer = ChessBoard.PlayerE.White; break; default: strError = "Next move player not 'B' or 'W'"; break; } if (strError == null) { if (!lineRetVal.SetBoardStateMask(arrParts[11], ChessBoard.BoardStateMaskE.WRCastling) || !lineRetVal.SetBoardStateMask(arrParts[12], ChessBoard.BoardStateMaskE.WLCastling) || !lineRetVal.SetBoardStateMask(arrParts[13], ChessBoard.BoardStateMaskE.BRCastling) || !lineRetVal.SetBoardStateMask(arrParts[14], ChessBoard.BoardStateMaskE.BLCastling) || !Int32.TryParse(arrParts[15], out arrIntVal[0]) || !Int32.TryParse(arrParts[16], out arrIntVal[1]) || !Int32.TryParse(arrParts[19], out arrIntVal[2]) || !Int32.TryParse(arrParts[20], out arrIntVal[3]) || !Int32.TryParse(arrParts[21], out arrIntVal[4]) || !Int32.TryParse(arrParts[22], out arrIntVal[5]) || !Int32.TryParse(arrParts[23], out arrIntVal[6]) || !Int32.TryParse(arrParts[24], out arrIntVal[7]) || !Int32.TryParse(arrParts[25], out arrIntVal[8]) || !Int32.TryParse(arrParts[26], out arrIntVal[9]) || !Int32.TryParse(arrParts[30], out arrIntVal[10])) { strError = "Illegal value in field."; } else if (arrIntVal[2] < -3 || arrIntVal[2] > 2 || arrIntVal[3] < 0 || arrIntVal[9] < 0 || arrIntVal[10] < 0 || arrIntVal[10] > 1) { strError = "Field value out of range."; } else { lineRetVal.WhitePlayerName = arrParts[17]; lineRetVal.BlackPlayerName = arrParts[18]; lineRetVal.IrreversibleMoveCount = arrIntVal[0]; lineRetVal.GameId = arrIntVal[1]; lineRetVal.RelationWithGame = (RelationWithGameE)arrIntVal[2]; lineRetVal.InitialTime = arrIntVal[3]; lineRetVal.IncrementTime = arrIntVal[4]; lineRetVal.WhiteMaterial = arrIntVal[5]; lineRetVal.BlackMaterial = arrIntVal[6]; lineRetVal.WhiteRemainingTime = arrIntVal[7]; lineRetVal.BlackRemainingTime = arrIntVal[8]; lineRetVal.MoveNumber = arrIntVal[9]; lineRetVal.LastMoveVerbose = arrParts[27]; lineRetVal.LastMoveSpan = FICSGame.ParseTime(arrParts[28].Replace("(", "").Replace(")", "")); lineRetVal.LastMoveSAN = arrParts[29]; lineRetVal.IsFlipped = (arrIntVal[9] == 1); iGameId = lineRetVal.GameId; } } if (strError == null) { if (arrParts.Length >= 33 && Int32.TryParse(arrParts[31], out arrIntVal[0]) && Int32.TryParse(arrParts[32], out arrIntVal[1])) { lineRetVal.IsClockTicking = (arrIntVal[0] == 1); lineRetVal.LagInMS = arrIntVal[1]; } else { lineRetVal.IsClockTicking = true; lineRetVal.LagInMS = 0; } } } if (strError != null) { lineRetVal = null; eTermination = TerminationE.TerminatedWithErr; } } } return(lineRetVal); }
/// <summary> /// Play a decoded move /// </summary> /// <param name="moveLine"> Move line</param> /// <param name="bShowError"> True to send the error to the chess board control</param> /// <param name="strError"> Error if any</param> /// <returns> /// true if succeed, false if failed /// </returns> private bool PlayMove(Style12MoveLine moveLine, bool bShowError, out string strError) { bool bRetVal; SrcChess2.MoveExt move; int iHalfMoveCount; strError = null; if (BoardCreated) { if (m_timerMoveTimeout != null) { m_timerMoveTimeout.Change(m_iMoveTimeOut * 1000, System.Threading.Timeout.Infinite); } iHalfMoveCount = m_chessBoard.MovePosStack.Count; if (moveLine.HalfMoveCount != iHalfMoveCount) { if (moveLine.HalfMoveCount != iHalfMoveCount + 1) { strError = "Unsynchronized move - " + moveLine.LastMoveSAN; } else { if (!m_parser.ApplySANMoveToBoard(m_pgnGame, moveLine.LastMoveSAN, out move)) { strError = "Illegal move - " + moveLine.LastMoveSAN; } else { switch (moveLine.NextMovePlayer) { case SrcChess2.ChessBoard.PlayerE.Black: m_spanTotalWhiteTime += moveLine.LastMoveSpan; break; case SrcChess2.ChessBoard.PlayerE.White: m_spanTotalBlackTime += moveLine.LastMoveSpan; break; } if (ChessBoardCtl != null) { ChessBoardCtl.Dispatcher.Invoke((Action)(() => { DoMove(move); ChessBoardCtl.GameTimer.ResetTo(moveLine.NextMovePlayer, m_spanTotalWhiteTime.Ticks, m_spanTotalBlackTime.Ticks); })); } } } } } else { m_queueMove.Enqueue(moveLine); } if (strError == null) { bRetVal = true; } else { if (bShowError) { ShowError(strError); } bRetVal = false; } return(bRetVal); }