/// <summary> /// Add a move based on a notation type. /// </summary> /// <param name="move">the string representation of the move(e4, bxd3 or e2-e4 etc.)</param> /// <param name="notationType"></param> public void AddMove(string move, NotationType notationType) { if (notationType == NotationType.Coordinate) { if (move == "0-0") { //cgSimpleMove smove = new cgCastlingMove(0,0,0,0,0); } else if (move == "0-0-0") { } else { byte start = 0; byte end = 0; for (byte i = 0; i < board.SquareNames.Length; i++) { string str = board.SquareNames[i]; if (str == move.Substring(0, 2)) { start = i; } if (str == move.Substring(3, 2)) { end = i; } } cgSimpleMove smove = new cgSimpleMove(start, end); moves.Add(smove); } } }
public NotationValue(string notation, int index, int end) { value = 1; op = Op.Add; type = NotationType.Value; switch (notation[index]) { case '+': { index++; break; } case '-': { op = Op.Sub; index++; break; } case '*': { op = Op.Mul; index++; break; } case '/': { op = Op.Div; index++; break; } case '^': { op = Op.Mod; index++; break; } } if (index <= end && char.IsDigit(notation[index])) { int i = index + 1; while (i <= end && char.IsDigit(notation[i])) i++; value = int.Parse(notation.Substring(index, i - index)); index = i; } if (index <= end && char.IsLetter(notation[index])) { Enum.TryParse<NotationType>(notation.Substring(index, end - index + 1), out type); } }
public void SaveConfig(Stream outputStream) { if (null == outputStream) { throw new ArgumentNullException("outputStream"); } XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) { writer.WriteStartElement("Mzinga.Viewer"); writer.WriteAttributeString("version", AppViewModel.FullVersion); writer.WriteAttributeString("date", DateTime.UtcNow.ToString()); writer.WriteElementString("EngineType", EngineType.ToString()); writer.WriteElementString("EngineCommandLine", EngineCommandLine); writer.WriteElementString("HexOrientation", HexOrientation.ToString()); writer.WriteElementString("NotationType", NotationType.ToString()); writer.WriteElementString("DisablePiecesInHandWithNoMoves", DisablePiecesInHandWithNoMoves.ToString()); writer.WriteElementString("DisablePiecesInPlayWithNoMoves", DisablePiecesInPlayWithNoMoves.ToString()); writer.WriteElementString("HighlightTargetMove", HighlightTargetMove.ToString()); writer.WriteElementString("HighlightValidMoves", HighlightValidMoves.ToString()); writer.WriteElementString("HighlightLastMovePlayed", HighlightLastMovePlayed.ToString()); writer.WriteElementString("BlockInvalidMoves", BlockInvalidMoves.ToString()); writer.WriteElementString("RequireMoveConfirmation", RequireMoveConfirmation.ToString()); writer.WriteEndElement(); } }
public static string ConvertTo(this string expression, NotationType type) { if (expression.HasNotationType(type)) { return(expression); } string prefix = expression.ToPrefixNotation(); switch (type) { case NotationType.Prefix: return(prefix); case NotationType.Infix: return(""); case NotationType.Postfix: return(""); default: throw new ArgumentException("Given type is not allowed."); } // TODO add conversions }
public void SetMove(BoardState state, Move move, NotationType notationType) { if (move.lastTeam == Team.White && !whiteSet) { whiteSet = true; whiteState = state; whiteMove = move; } else if (move.lastTeam == Team.Black && !blackSet) { blackSet = true; blackState = state; blackMove = move; } TextMeshProUGUI toChange = move.lastTeam == Team.White ? whiteText : blackText; string notation = Notation.Get(state, move, board.currentGame.promotions, notationType); toChange.text = notation; if (move.lastTeam == Team.White) { blackText.text = ""; } TextMeshProUGUI deltaTimeToChange = move.lastTeam == Team.White ? whiteDeltaTime : blackDeltaTime; if (deltaTimeToChange != null) { deltaTimeToChange.text = $"+{TimeSpan.FromSeconds(move.duration).ToString(move.duration.GetStringFromSeconds())}"; } }
public void SetNotation(NotationType type) { if (whiteSet) { whiteText.text = Notation.Get(whiteState, whiteMove, board.currentGame.promotions, type); } if (blackSet) { blackText.text = Notation.Get(blackState, blackMove, board.currentGame.promotions, type); } }
public static NotationType Cycle(this NotationType notation) { int id = (int)notation; if (id < (int)NotationType.ICCF) { id++; } else { id = (int)NotationType.LaymanTemporary; } return((NotationType)id); }
public void SaveConfig(Stream outputStream) { if (null == outputStream) { throw new ArgumentNullException(nameof(outputStream)); } XmlWriterSettings settings = new XmlWriterSettings { Indent = true }; using (XmlWriter writer = XmlWriter.Create(outputStream, settings)) { writer.WriteStartElement("Mzinga.Viewer"); writer.WriteAttributeString("version", AppVM.FullVersion); writer.WriteAttributeString("date", DateTime.UtcNow.ToString()); writer.WriteElementString("EngineType", EngineType.ToString()); writer.WriteElementString("EngineCommandLine", EngineCommandLine); writer.WriteElementString("HexOrientation", HexOrientation.ToString()); writer.WriteElementString("NotationType", NotationType.ToString()); writer.WriteElementString("PieceStyle", PieceStyle.ToString()); writer.WriteElementString("PieceColors", PieceColors.ToString()); writer.WriteElementString("DisablePiecesInHandWithNoMoves", DisablePiecesInHandWithNoMoves.ToString()); writer.WriteElementString("DisablePiecesInPlayWithNoMoves", DisablePiecesInPlayWithNoMoves.ToString()); writer.WriteElementString("HighlightTargetMove", HighlightTargetMove.ToString()); writer.WriteElementString("HighlightValidMoves", HighlightValidMoves.ToString()); writer.WriteElementString("HighlightLastMovePlayed", HighlightLastMovePlayed.ToString()); writer.WriteElementString("BlockInvalidMoves", BlockInvalidMoves.ToString()); writer.WriteElementString("RequireMoveConfirmation", RequireMoveConfirmation.ToString()); writer.WriteElementString("AddPieceNumbers", AddPieceNumbers.ToString()); writer.WriteElementString("StackPiecesInHand", StackPiecesInHand.ToString()); writer.WriteElementString("PlaySoundEffects", PlaySoundEffects.ToString()); writer.WriteElementString("ShowBoardHistory", ShowBoardHistory.ToString()); writer.WriteElementString("ShowMoveCommentary", ShowMoveCommentary.ToString()); writer.WriteElementString("FirstRun", FirstRun.ToString()); writer.WriteElementString("CheckUpdateOnStart", CheckUpdateOnStart.ToString()); InternalGameEngineConfig?.SaveGameAIConfig(writer, "InternalGameAI", ConfigSaveType.BasicOptions); writer.WriteEndElement(); } }
/// <summary> /// Add a move based on a notation type. /// </summary> /// <param name="move">the string representation of the move(e4, bxd3 or e2-e4 etc.)</param> /// <param name="notationType"></param> public void AddMove(string move, NotationType notationType) { if (notationType == NotationType.Coordinate) { if (move == "0-0") { //cgSimpleMove smove = new cgCastlingMove(0,0,0,0,0); } else if (move == "0-0-0") { } else { cgSimpleMove smove = new cgSimpleMove(cgGlobal.IndexFromCellName(move.Substring(0, 2)), cgGlobal.IndexFromCellName(move.Substring(3, 2))); moves.Add(smove); } } }
public static bool HasNotationType(this string expression, NotationType type) { if (!expression.CheckSyntax()) { return(false); } switch (type) { case NotationType.Infix: return(expression.IsInfixExpression()); case NotationType.Prefix: return(expression.IsPrefixExpression()); case NotationType.Postfix: return(expression.IsPostfixExpression()); default: return(false); } }
public static string ToNotation(string input, NotationType type) { input ??= ""; //cadena = cadena.ToLowerInvariant(); switch (type) { case NotationType.Camel: input = GetSeparatedStringPhrase(input); input = ToUpperFirstLetterInWord(input) .Replace(" ", "", StringComparison.InvariantCultureIgnoreCase); if (!string.IsNullOrEmpty(input)) { var c = input[0]; c = char.ToLower(c, CultureInfo.InvariantCulture); input = c + input.Remove(0, 1); } break; case NotationType.Pascal: input = GetSeparatedStringPhrase(input); input = ToUpperFirstLetterInWord(input) .Replace(" ", "", StringComparison.InvariantCultureIgnoreCase); break; case NotationType.Lower: input = GetSeparatedStringPhrase(input); input = input.Replace(' ', '_').ToLowerInvariant(); break; case NotationType.Upper: input = GetSeparatedStringPhrase(input); input = input.Replace(' ', '_').ToUpperInvariant(); break; } return(input); }
/// <summary> /// Writes the full game notation from the current moves stored in Moves list. /// </summary> /// <param name="type">What notationtype should it be?</param> /// <param name="formatType">Should it be PGN format or not?</param> /// <returns>A string with full game notation.</returns> public string writeFullNotation(NotationType type, FormatType formatType = FormatType.None) { string str = ""; cgBoard disambiguationBoard = board.duplicate().revertToStart(); if (type == NotationType.Coordinate) { foreach (cgSimpleMove pcem in moves) { str += (disambiguationBoard.SquareNames[pcem.from] + "-" + disambiguationBoard.SquareNames[pcem.to]) + " "; } } if (formatType == FormatType.PGN) { string q = "\""; str = " [Event " + q + "Pro Chess" + q + "]\n"; str += " [Site " + q + "Undefined site" + q + "]\n"; str += " [Date " + q + DateTime.Now + q + "]\n"; str += " [White " + q + "Chessplayer1" + q + "]\n"; str += " [Black " + q + "Chessplayer2" + q + "]\n"; str += " [Result " + q + "1/2-1/2" + q + "]\n"; } if (type == NotationType.Algebraic) { foreach (cgSimpleMove pcem in moves) { if (disambiguationBoard.moves.Count % 2 == 0) { str += (Math.Floor(disambiguationBoard.moves.Count / 2f) + 1).ToString() + ". "; } int typ = Math.Abs(disambiguationBoard.squares[pcem.from]); List <cgSimpleMove> othermoves = disambiguationBoard.findLegalMoves(disambiguationBoard.whiteTurnToMove); List <cgSimpleMove> ambiguousMoves = new List <cgSimpleMove>(); foreach (cgSimpleMove othermove in othermoves) { if (othermove.to == pcem.to && othermove.from != pcem.from && Math.Abs(disambiguationBoard.squares[othermove.from]) == typ) { ambiguousMoves.Add(othermove); } } if (typ == 1 && pcem.capturedType != 0) { str += disambiguationBoard.SquareNames[pcem.from].Substring(0, 1); } if (typ == 2) { str += "R"; } if (typ == 3) { str += "N"; } if (typ == 4) { str += "B"; } if (typ == 5) { str += "Q"; } if (typ == 6 && !(pcem is cgCastlingMove)) { str += "K"; } //if (typ == 6) str += "K"; if (ambiguousMoves.Count > 0 && typ != 1) { bool fileMatch = false; bool rankMatch = false; foreach (cgSimpleMove ambiguousMove in ambiguousMoves) { if (disambiguationBoard.SquareNames[ambiguousMove.from].Substring(0, 1) == disambiguationBoard.SquareNames[pcem.from].Substring(0, 1)) { fileMatch = true; } if (disambiguationBoard.SquareNames[ambiguousMove.from].Substring(1, 1) == disambiguationBoard.SquareNames[pcem.from].Substring(1, 1)) { rankMatch = true; } } if (!fileMatch) { str += disambiguationBoard.SquareNames[pcem.from].Substring(0, 1); } else if (fileMatch && !rankMatch) { str += disambiguationBoard.SquareNames[pcem.from].Substring(1, 1); } else if (fileMatch && rankMatch) { str += disambiguationBoard.SquareNames[pcem.from]; } } if (pcem.capturedType != 0) { str += "x"; } if (pcem is cgCastlingMove) { if (pcem.to == 2 || pcem.to == 58) { str += "O-O-O"; } else { str += "O-O"; } } else { str += disambiguationBoard.SquareNames[pcem.to]; } if (pcem.queened) { str += "=Q"; } str += " "; disambiguationBoard.move(pcem); } } return(str); }
/// <summary> /// Read the notations in the provided string. /// </summary> /// <param name="curgame">the string to decipher.</param> public void Read(string curgame) { int lastIndex = 0; int nextIndex = 0; string move = curgame.Substring(lastIndex, nextIndex); NotationType ntype = NotationType.Algebraic; //= NotationType.Coordinate; //Debug.Log("first move:" + move); //if (move.Contains("-")) ntype = NotationType.Coordinate; moves = new List <cgSimpleMove>(); if (ntype == NotationType.Coordinate) { while (lastIndex != -1) { byte fromp = board.IndexFromCellName(move.Substring(0, 2)); byte top = board.IndexFromCellName(move.Substring(3, 2)); moves.Add(new cgSimpleMove(fromp, top)); nextIndex = curgame.IndexOf(" ", lastIndex + 1); if (nextIndex == -1) { break; } move = curgame.Substring(lastIndex + 1, nextIndex - lastIndex); lastIndex = nextIndex; //Debug.Log("current move being analyzed="+move); } } else if (ntype == NotationType.Algebraic) { cgBoard disambBoard = new cgBoard(); cgSimpleMove chosenMove; while (lastIndex != -1) { chosenMove = null; nextIndex = curgame.IndexOf(" ", nextIndex + 1); if (nextIndex == -1 || lastIndex == -1) { break; } move = curgame.Substring(lastIndex + 1, nextIndex - lastIndex); bool legitMove = (!move.Contains(".") && move.Length > 1 && !move.Contains("\n")) ? true : false; move = move.Trim(' '); //move = move.Trim('\n'); //Debug.Log("trimmed:" + move+" contains .:"+move.Contains(".")+" contains newline:"+move.Contains("\n")+" legit move:"+legitMove); if (move.Contains("{")) { nextIndex = curgame.IndexOf("}", lastIndex + 1); } else if (move.Contains("[")) { nextIndex = curgame.IndexOf("]", lastIndex + 1); } else if (legitMove) { //Debug.Log("found to be legit move."); byte tosquare; byte pushback = 2; byte type = 1; //bool promotion = false; bool shortCastling = (move == "O-O"); bool longCastling = (move == "O-O-O"); if (move.Contains("=")) { //promotion = true; move.Remove(move.IndexOf("="), 2); } else if (move.Contains("+")) { move.Remove(move.IndexOf("+"), 1); } else if (move.Contains("!")) { move.Remove(move.IndexOf("!"), 1); } else if (move.Contains("?")) { move.Remove(move.IndexOf("?"), 1); } tosquare = board.IndexFromCellName(move.Substring(move.Length - pushback, 2)); if (move[0] == 'R') { type = 2; } if (move[0] == 'N') { type = 3; } if (move[0] == 'B') { type = 4; } if (move[0] == 'Q') { type = 5; } if (move[0] == 'K') { type = 6; } List <cgSimpleMove> ambiguousMoves = new List <cgSimpleMove>(); foreach (cgSimpleMove legalMove in disambBoard.findLegalMoves(disambBoard.whiteTurnToMove)) { if (shortCastling && legalMove is cgCastlingMove) { if (legalMove.to == 6 || legalMove.to == 62) { chosenMove = legalMove; break; } } else if (longCastling && legalMove is cgCastlingMove) { if (legalMove.to == 2 || legalMove.to == 58) { chosenMove = legalMove; break; } } if (Math.Abs(disambBoard.squares[legalMove.from]) == type && legalMove.to == tosquare) { ambiguousMoves.Add(legalMove); } } if (ambiguousMoves.Count == 0 && chosenMove == null) { //Debug.WriteLine("found no matching move for the string: " + move+" type:"+type+" tosquare:"+tosquare+" chosenMove:"+chosenMove+" castling:"+shortCastling); break; } else if (ambiguousMoves.Count == 1) { chosenMove = ambiguousMoves[0]; } else if (ambiguousMoves.Count > 1) { //UnityEngine.Debug.Log("2 or mroe ambiguousmoves"); //2 or more ambiguous moves in which the piece type matches and the destination square matches. Further disambiguation needed. List <cgSimpleMove> matching = new List <cgSimpleMove>(); foreach (cgSimpleMove mov in ambiguousMoves) { if (board.SquareNames[mov.from].Contains(move.Substring(1 + (type == 1?-1:0), 1))) { matching.Add(mov); } } if (matching.Count == 1) { chosenMove = matching[0]; //only 1 of the ambiguous moves have the correct rank and/or file. } else { foreach (cgSimpleMove mov in ambiguousMoves) { if (board.SquareNames[mov.from].Contains(move.Substring(1, 2))) { chosenMove = ambiguousMoves[0]; break; } } } } if (chosenMove != null) { disambBoard.move(chosenMove); moves.Add(chosenMove); } } Debug.WriteLine("legitmove:" + legitMove); lastIndex = nextIndex; } } }
public NotationValue(int value, NotationType type, Op op) { this.value = value; this.op = op; this.type = type; }
public static string Get(BoardState boardState, Move move, List <Promotion> promotions, NotationType notationType = NotationType.LongForm) { if (move.lastTeam == Team.None) { return(""); } string fromIndex = move.from.GetKey(); string toIndex = move.to.GetKey(); string piece = GetStringForPiece(move.lastPiece, move.lastTeam, promotions, move); string type = move.capturedPiece.HasValue ? "x" : move.defendedPiece.HasValue ? "d" : "m"; // When using freeplace mode, you can swap non-rook pieces, we want to clearly label that as a swap and not a defend unless a rook is involved if (type == "d" && !HexachessagonEngine.GetRealPiece((move.lastTeam, move.lastPiece), promotions).IsRook()) { type = "-"; } string otherPiece = type switch { "x" => GetStringForPiece(move.capturedPiece.Value, move.lastTeam.Enemy(), promotions, move), string t when(t == "d" || t == "-") => GetStringForPiece(move.defendedPiece.Value, move.lastTeam, promotions, move), _ => "" }; string freePlaced = ""; bool shortFormMod = notationType == NotationType.ShortForm; if (move.from == Index.invalid && move.to == Index.invalid) { // No piece moved - skipped move with free place mode fromIndex = ""; toIndex = ""; piece = ""; type = ""; otherPiece = ""; freePlaced = "skipped"; shortFormMod = false; } else if (move.to == Index.invalid) { // Put in jail with free place mode otherPiece = ""; type = ""; toIndex = ""; freePlaced = " jailed"; shortFormMod = false; } else if (move.from == Index.invalid) { // Freed from jail with free place mode fromIndex = ""; otherPiece = ""; type = ""; freePlaced = " freed to "; shortFormMod = false; } string promo = ""; Team lt = move.lastTeam; Piece lp = move.lastPiece; IEnumerable <Promotion> applicablePromotions = promotions.Where(promo => promo.team == lt && promo.from == lp); if (applicablePromotions.Any()) { Promotion applicablePromo = applicablePromotions.First(); promo = applicablePromo.turnNumber == move.turn + (move.lastTeam == Team.Black).BoolToInt() && move.lastTeam == applicablePromo.team ? $"={applicablePromo.to.GetPieceShortString()}" : ""; } string check = boardState.checkmate != Team.None ? "#" : boardState.check != Team.None ? "+" : ""; // modify for shortform if (notationType == NotationType.ShortForm && shortFormMod) { if (piece == "p") { piece = ""; if (type != "-") { otherPiece = ""; type = type == "x" ? type : ""; fromIndex = type == "x" ? $"{fromIndex.First()}" : ""; } } else { List <Piece> alternatePieces = HexachessagonEngine.GetRealPiece((lt, lp), promotions).GetAlternates().ToList(); foreach (Promotion potentialAlternate in promotions) { if (potentialAlternate.turnNumber < move.turn) { List <Piece?> toAdd = new List <Piece?>(); foreach (Piece alt in alternatePieces) { if (potentialAlternate.to == alt) { toAdd.Add(potentialAlternate.from); } } toAdd.ForEach(p => alternatePieces.Add(p.Value)); if (potentialAlternate.from == lp) { alternatePieces.Add(potentialAlternate.to); } if (potentialAlternate.to == lp) { alternatePieces.Add(potentialAlternate.from); } } } type = type == "m" ? "" : type; if (alternatePieces.Count > 0) { bool fileAmbiguity = false; bool rankAmbiguity = false; foreach (Piece alternate in alternatePieces) { if (boardState.TryGetIndex((lt, alternate), out Index index)) { Piece realPiece = HexachessagonEngine.GetRealPiece((lt, alternate), promotions); var possibleMovesConcerningHex = MoveGenerator.GetAllPossibleMoves(index, realPiece, lt, boardState, promotions, true) .Where(kvp => kvp.target != null && kvp.target == move.to); if (MoveValidator.ValidateMoves(possibleMovesConcerningHex, (lt, alternate), boardState, promotions).Any()) { if (index.col == move.from.col) { rankAmbiguity = true; } if (index.row == move.from.row) { fileAmbiguity = true; } } } } if (fileAmbiguity && rankAmbiguity) { fromIndex = move.from.GetKey(); } else if (fileAmbiguity) { fromIndex = $"{move.from.GetLetter()}"; } else if (rankAmbiguity) { fromIndex = $"{move.from.GetNumber()}"; } else { fromIndex = ""; } } else { fromIndex = ""; } } } return($"{piece}{fromIndex}{type}{otherPiece}{freePlaced}{toIndex}{promo}{check}"); }