Ejemplo n.º 1
0
    /// <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);
            }
        }
    }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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();
            }
        }
Ejemplo n.º 4
0
        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
        }
Ejemplo n.º 5
0
    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())}";
        }
    }
Ejemplo n.º 6
0
    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);
        }
    }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        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();
            }
        }
Ejemplo n.º 9
0
 /// <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);
         }
     }
 }
Ejemplo n.º 10
0
        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);
            }
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
    /// <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);
    }
Ejemplo n.º 13
0
    /// <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;
            }
        }
    }
Ejemplo n.º 14
0
 public NotationValue(int value, NotationType type, Op op)
 {
     this.value = value;
     this.op = op;
     this.type = type;
 }
Ejemplo n.º 15
0
    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}");
    }