예제 #1
0
 public bool Compare(MoveNotation target)
 {
     if (MoveType != target.MoveType)
     {
         return(false);
     }
     if (MoveType == NotatedMoveType.MoveStack)
     {
         if (UnstackDirection != target.UnstackDirection ||
             Position != target.Position ||
             UnstackCounts.Count != target.UnstackCounts.Count)
         {
             return(false);
         }
         for (int i = 0; i < UnstackCounts.Count; i++)
         {
             if (UnstackCounts[i] != target.UnstackCounts[i])
             {
                 return(false);
             }
         }
         return(true);
     }
     else
     {
         return(StoneType == target.StoneType && Position == target.Position);
     }
 }
예제 #2
0
        public override void ExitSan_move(Generated.TakPGNParser.San_moveContext context)
        {
            var          notationText = context.SYMBOL().GetText();
            MoveNotation notation;

            if (!MoveNotation.TryParse(notationText, out notation))
            {
                throw new ApplicationException("Unrecognized move notation: " + notationText);
            }
            _currentGame.MoveNotations.Add(notation);
            base.ExitSan_move(context);
        }
예제 #3
0
        public static bool TryParse(string s, out MoveNotation notated)
        {
            notated = null;

            // minimum move notation length
            if (s.Length < 2)
            {
                throw new ApplicationException(s + " is too short: " + s.Length.ToString());
            }
            //return false;

            notated      = new MoveNotation();
            notated.Text = s;

            // try to find a direction
            int dirIndex = s.IndexOfAny(Direction.DirName);

            if (dirIndex >= 0)
            {
                notated.UnstackDirection = Array.IndexOf(Direction.DirName, s[dirIndex]);
                notated.MoveType         = NotatedMoveType.MoveStack;

                // direction must be immediately preceded by position
                int positionStart = dirIndex - 2;
                if (positionStart < 0)
                {
                    throw new ApplicationException(s + " doesn't have a valid position before the direction " + notated.UnstackDirection);
                }
                //return false;
                if (!TryParsePosition(s, out notated.Position, index: positionStart))
                {
                    return(false);
                }

                // Pickup count is optional if we're only picking up a single stone
                if (positionStart == 0)
                {
                    notated.PickupCount = 1;
                }

                // Otherwise we need to be able to parse the number of stones picked up
                else if (!int.TryParse(s.Substring(0, positionStart), out notated.PickupCount))
                {
                    throw new ApplicationException("Number of stones picked up doesn't look like an int: " + s.Substring(0, positionStart));
                }
                //return false;

                // Paranoia
                if (notated.PickupCount < 0 || notated.PickupCount > 8)
                {
                    throw new ApplicationException("PickupCount is out of range: " + notated.PickupCount.ToString());
                }
                //return false;

                notated.UnstackCounts = new List <int>(4);
                int remaining = notated.PickupCount;
                for (int i = dirIndex + 1; i < s.Length; i++)
                {
                    int count = (int)(s[i] - '0');
                    if (count < 0 || count > remaining)
                    {
                        throw new ApplicationException("dropped more than remaining: " + count.ToString() + " vs. " + remaining.ToString());
                    }
                    //return false;
                    notated.UnstackCounts.Add(count);
                    remaining -= count;

                    if (remaining == 0)
                    {
                        // optional F, S, or C to indicate the top of the stack at the end of the move
                        if (i < s.Length - 2)
                        {
                            throw new ApplicationException("too many characters at the end of the string!");
                        }
                        //return false;
                        else if (i == s.Length - 2)
                        {
                            var c = s[i + 1];
                            if (c != 'F' && c != 'S' && c != 'C')
                            {
                                throw new ApplicationException("unrecognized stone type, don't know what to do with this");
                            }
                            //return false;
                        }
                        break;
                    }
                }

                // Drop count is optional if we're dropping all the stones we picked up on the first hop
                if (remaining == notated.PickupCount)
                {
                    notated.UnstackCounts.Add(remaining);
                }
                else if (remaining != 0)
                {
                    throw new ApplicationException("didn't drop all stones - remaining count: " + remaining.ToString());
                }
                //return false;
                return(true);
            }
            else
            {
                // no direction found, this must be a placement move
                notated.MoveType = NotatedMoveType.Place;

                if (s.Length > 3)
                {
                    throw new ApplicationException("notation too long for placement");
                }
                //return false;
                if (s.StartsWith("S"))
                {
                    notated.StoneType = Piece.Stone_Standing;
                }
                else if (s.StartsWith("C"))
                {
                    notated.StoneType = Piece.Stone_Cap;
                }
                else if (s.StartsWith("F") || s.Length == 2)
                {
                    notated.StoneType = Piece.Stone_Flat;
                }
                else
                {
                    throw new ApplicationException("unknown stone type prefix");
                }
                //return false;

                if (!TryParsePosition(s, out notated.Position, index: s.Length - 2))
                {
                    return(false);
                }
                return(true);
            }
        }
예제 #4
0
        public static bool TryParse(string s, out MoveNotation notated)
        {
            notated = null;

            // minimum move notation length
            if (s.Length < 2)
            {
                return(false);
            }

            notated      = new MoveNotation();
            notated.Text = s;

            // try to find a direction
            int dirIndex = s.IndexOfAny(Direction.DirName);

            if (dirIndex >= 0)
            {
                notated.UnstackDirection = Array.IndexOf(Direction.DirName, s[dirIndex]);
                notated.MoveType         = NotatedMoveType.MoveStack;

                // direction must be immediately preceded by position
                int positionStart = dirIndex - 2;
                if (positionStart < 0)
                {
                    return(false);
                }
                if (!TryParsePosition(s, out notated.Position, index: positionStart))
                {
                    return(false);
                }

                // Pickup count is optional if we're only picking up a single stone
                if (positionStart == 0)
                {
                    notated.PickupCount = 1;
                }

                // Otherwise we need to be able to parse the number of stones picked up
                else if (!int.TryParse(s.Substring(0, positionStart), out notated.PickupCount))
                {
                    return(false);
                }

                // Paranoia
                if (notated.PickupCount < 0 || notated.PickupCount > 8)
                {
                    return(false);
                }

                notated.UnstackCounts = new List <int>(4);
                int remaining = notated.PickupCount;
                for (int i = dirIndex + 1; i < s.Length; i++)
                {
                    int count = (int)(s[i] - '0');
                    if (count < 0 || count > remaining)
                    {
                        return(false);
                    }
                    notated.UnstackCounts.Add(count);
                    remaining -= count;

                    if (remaining == 0)
                    {
                        // optional F, S, or C to indicate the top of the stack at the end of the move
                        if (i < s.Length - 2)
                        {
                            // too many characters at the end of the string!
                            return(false);
                        }
                        else if (i == s.Length - 2)
                        {
                            var c = s[i + 1];
                            if (c != 'F' && c != 'S' && c != 'C')
                            {
                                // unrecognized stone type, don't know what to do with this
                                return(false);
                            }
                        }
                        break;
                    }
                }

                // Drop count is optional if we're only moving a single stone
                if (notated.UnstackCounts.Count == 0 && remaining > 0)
                {
                    notated.UnstackCounts.Add(remaining);
                    remaining = 0;
                }
                if (remaining != 0)
                {
                    return(false);
                }
                return(true);
            }
            else
            {
                // no direction found, this must be a placement move
                notated.MoveType = NotatedMoveType.Place;

                if (s.Length > 3)
                {
                    return(false);
                }
                if (s.StartsWith("S"))
                {
                    notated.StoneType = Piece.Stone_Standing;
                }
                else if (s.StartsWith("C"))
                {
                    notated.StoneType = Piece.Stone_Cap;
                }
                else if (s.StartsWith("F") || s.Length == 2)
                {
                    notated.StoneType = Piece.Stone_Flat;
                }
                else
                {
                    return(false);
                }

                if (!TryParsePosition(s, out notated.Position, index: s.Length - 2))
                {
                    return(false);
                }
                return(true);
            }
        }