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); } }
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); }
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); } }
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); } }