Beispiel #1
0
        private void ProcessBestMove(string line, bool tryToPlay)
        {
            try
            {
                Move bestMove = NotationUtils.ParseMoveString(Board, line.Split(';')[0]);

                TargetPiece    = bestMove.PieceName;
                TargetPosition = bestMove.Position;
                TargetMove     = bestMove;
            }
            catch (Exception)
            {
                TargetPiece = PieceName.INVALID;
            }

            if (tryToPlay && CurrentTurnIsEngineAI && CurrentGameSettings.GameMode == GameMode.Play && null != TargetMove)
            {
                if (TargetMove.IsPass)
                {
                    SendCommandInternal("pass");
                }
                else
                {
                    SendCommandInternal("play {0}", NotationUtils.ToBoardSpaceMoveString(Board, TargetMove));
                }
            }
        }
Beispiel #2
0
        private void Play(string moveString)
        {
            if (null == _gameBoard)
            {
                throw new NoBoardException();
            }

            if (_gameBoard.GameIsOver)
            {
                throw new GameIsOverException();
            }

            Move move = null;

            try
            {
                move = NotationUtils.ParseMoveString(_gameBoard, moveString);
            }
            catch (Exception)
            {
                throw new InvalidMoveException(move);
            }

            NotationUtils.TryNormalizeBoardSpaceMoveString(moveString, out moveString);

            _gameBoard.Play(move, moveString);

            StopPonder();

            ConsoleOut(_gameBoard.ToGameString());
        }
Beispiel #3
0
            public void Parse(string s)
            {
                if (string.IsNullOrWhiteSpace(s))
                {
                    throw new ArgumentNullException(nameof(s));
                }

                s = s.Trim();

                string[] vals = s.Split('\t');

                Board             = GameBoard.ParseGameString(vals[0]);
                InvalidMoveString = vals[1];
                InvalidMove       = NotationUtils.ParseMoveString(Board, vals[1]);
            }
Beispiel #4
0
            public void Parse(string s)
            {
                if (string.IsNullOrWhiteSpace(s))
                {
                    throw new ArgumentNullException(nameof(s));
                }

                s = s.Trim();

                string[] vals = s.Split('\t');

                Board = GameBoard.ParseGameString(vals[0]);

                ValidMoveStrings = vals[1].Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                ValidMoves       = new Move[ValidMoveStrings.Length];

                for (int i = 0; i < ValidMoveStrings.Length; i++)
                {
                    ValidMoves[i] = NotationUtils.ParseMoveString(Board, ValidMoveStrings[i]);
                }
            }
Beispiel #5
0
        public static GameRecording LoadSGF(Stream inputStream, string fileName = null)
        {
            if (null == inputStream)
            {
                throw new ArgumentNullException(nameof(inputStream));
            }

            GameMetadata metadata = new GameMetadata();

            List <string> moveList = new List <string>();

            Dictionary <string, Stack <string> > backupPositions = new Dictionary <string, Stack <string> >();

            string rawResult         = "";
            bool   lastMoveCompleted = true;
            bool   whiteTurn         = true;

            using (StreamReader sr = new StreamReader(inputStream))
            {
                string line = null;
                while ((line = sr.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        // Line has contents
                        Match m = null;
                        if ((m = Regex.Match(line, @"SU\[(.*)\]")).Success)
                        {
                            metadata.SetTag("GameType", m.Groups[1].Value.ToUpper().Replace("HIVE", EnumUtils.NoExpansionsString).Replace("-", "+"));
                        }
                        else if ((m = Regex.Match(line, @"EV\[(.*)\]")).Success)
                        {
                            metadata.SetTag("Event", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"PC\[(.*)\]")).Success)
                        {
                            metadata.SetTag("Site", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"RO\[(.*)\]")).Success)
                        {
                            metadata.SetTag("Round", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"DT\[(.+)\]")).Success)
                        {
                            string rawDate = m.Groups[1].Value;
                            metadata.SetTag("SgfDate", rawDate);

                            rawDate = Regex.Replace(rawDate, @"(\D{3}) (\D{3}) (\d{2}) (\d{2}):(\d{2}):(\d{2}) (.{3,}) (\d{4})", @"$1 $2 $3 $4:$5:$6 $8");

                            if (DateTime.TryParseExact(rawDate, SgfDateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsed))
                            {
                                metadata.SetTag("Date", parsed.ToString("yyyy.MM.dd"));
                            }
                            else
                            {
                                foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures))
                                {
                                    if (DateTime.TryParseExact(rawDate, SgfDateFormats, ci, DateTimeStyles.None, out parsed))
                                    {
                                        metadata.SetTag("Date", parsed.ToString("yyyy.MM.dd"));
                                        break;
                                    }
                                }
                            }
                        }
                        else if ((m = Regex.Match(line, @"P0\[id ""(.*)""\]")).Success)
                        {
                            metadata.SetTag("White", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"P1\[id ""(.*)""\]")).Success)
                        {
                            metadata.SetTag("Black", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"RE\[(.+)\]")).Success)
                        {
                            rawResult = m.Groups[1].Value;
                            metadata.SetTag("SgfResult", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"GN\[(.+)\]")).Success)
                        {
                            metadata.SetTag("SgfGameName", m.Groups[1].Value);
                        }
                        else if ((m = Regex.Match(line, @"((move (w|b))|(dropb)|(pdropb)) ([a-z0-9]+) ([a-z] [0-9]+) ([a-z0-9\\\-\/\.]*)", RegexOptions.IgnoreCase)).Success)
                        {
                            // Initial parse
                            string movingPiece = m.Groups[m.Groups.Count - 3].Value.ToLower();
                            string destination = m.Groups[m.Groups.Count - 1].Value.ToLower().Replace("\\\\", "\\");

                            string backupPos = m.Groups[m.Groups.Count - 2].Value;

                            // Remove unnecessary numbers
                            movingPiece = movingPiece.Replace("m1", "m").Replace("l1", "l").Replace("p1", "p");
                            destination = destination.Replace("m1", "m").Replace("l1", "l").Replace("p1", "p");

                            // Add missing color indicator
                            if (movingPiece == "b1" || movingPiece == "b2" || !(movingPiece.StartsWith("b") || movingPiece.StartsWith("w")))
                            {
                                movingPiece = (whiteTurn ? "w" : "b") + movingPiece;
                            }

                            // Fix missing destination
                            if (destination == ".")
                            {
                                if (moveList.Count == 0)
                                {
                                    destination = "";
                                }
                                else
                                {
                                    destination = backupPositions[backupPos].Peek();
                                }
                            }

                            // Remove move that wasn't commited
                            if (!lastMoveCompleted)
                            {
                                moveList.RemoveAt(moveList.Count - 1);
                            }

                            moveList.Add(string.Format("{0} {1}", movingPiece, destination));

                            foreach (Stack <string> stack in backupPositions.Values)
                            {
                                if (stack.Count > 0 && stack.Peek() == movingPiece)
                                {
                                    stack.Pop();
                                    break;
                                }
                            }

                            if (!backupPositions.ContainsKey(backupPos))
                            {
                                backupPositions.Add(backupPos, new Stack <string>());
                            }

                            backupPositions[backupPos].Push(movingPiece);

                            lastMoveCompleted = false;
                        }
                        else if ((m = Regex.Match(line, @"P(0|1)\[[0-9]+ pass\]")).Success)
                        {
                            moveList.Add(NotationUtils.BoardSpacePass);

                            lastMoveCompleted = false;
                        }
                        else if ((m = Regex.Match(line, @"P(0|1)\[[0-9]+ done\]")).Success)
                        {
                            lastMoveCompleted = true;
                            whiteTurn         = !whiteTurn;
                        }
                        else if ((m = Regex.Match(line, @"P(0|1)\[[0-9]+ resign\]")).Success)
                        {
                            rawResult = m.Groups[1].Value == "0" ? BoardState.BlackWins.ToString() : BoardState.WhiteWins.ToString();
                        }
                    }
                }
            }

            GameBoard gameBoard = new GameBoard(metadata.GameType);

            foreach (string moveString in moveList)
            {
                Move move = null;
                try
                {
                    move = NotationUtils.ParseMoveString(gameBoard, moveString);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Unable to parse '{0}'.", moveString), ex);
                }

                gameBoard.TrustedPlay(move, NotationUtils.NormalizeBoardSpaceMoveString(moveString));
            }

            // Set result
            if (rawResult.Contains(metadata.White))
            {
                metadata.SetTag("Result", BoardState.WhiteWins.ToString());
            }
            else if (rawResult.Contains(metadata.Black))
            {
                metadata.SetTag("Result", BoardState.BlackWins.ToString());
            }
            else if (rawResult == "The game is a draw")
            {
                metadata.SetTag("Result", BoardState.Draw.ToString());
            }
            else if (Enum.TryParse(rawResult, out BoardState parsed))
            {
                metadata.SetTag("Result", parsed.ToString());
            }
            else
            {
                metadata.SetTag("Result", gameBoard.BoardState.ToString());
            }

            return(new GameRecording(gameBoard, GameRecordingSource.SGF, metadata)
            {
                FileName = fileName?.Trim()
            });
        }
Beispiel #6
0
        public static GameRecording LoadPGN(Stream inputStream, string fileName = null)
        {
            if (null == inputStream)
            {
                throw new ArgumentNullException(nameof(inputStream));
            }

            GameMetadata metadata = new GameMetadata();

            List <string> moveList = new List <string>();

            string rawResult = "";

            string multiLineCommentary = null;

            using (StreamReader sr = new StreamReader(inputStream, Encoding.ASCII))
            {
                string line = null;
                while ((line = sr.ReadLine()) != null)
                {
                    line = line.Trim();

                    if (null != multiLineCommentary)
                    {
                        // Line is part of multiline commentary
                        multiLineCommentary += Environment.NewLine + line;

                        if (multiLineCommentary.EndsWith("}"))
                        {
                            // End of multiline commentary
                            metadata.SetMoveCommentary(moveList.Count, multiLineCommentary);
                            multiLineCommentary = null;
                        }
                    }
                    else if (line.StartsWith("[") && line.EndsWith("]"))
                    {
                        // Line is a tag
                        KeyValuePair <string, string> kvp = ParsePGNTag(line);
                        if (kvp.Key == "Result")
                        {
                            rawResult = kvp.Value;
                        }
                        else
                        {
                            metadata.SetTag(kvp.Key, kvp.Value);
                        }
                    }
                    else if (line.StartsWith("{") && line.EndsWith("}"))
                    {
                        // Line is a single line of commentary
                        metadata.SetMoveCommentary(moveList.Count, line);
                    }
                    else if (line.StartsWith("{") && null == multiLineCommentary)
                    {
                        multiLineCommentary = line;
                    }
                    else if (!string.IsNullOrWhiteSpace(line))
                    {
                        // Line is a move or result
                        if (Enum.TryParse(line, out BoardState lineResult))
                        {
                            rawResult = lineResult.ToString();
                        }
                        else
                        {
                            // Not a result, add as moveString
                            moveList.Add(line.TrimStart('.', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'));
                        }
                    }
                }
            }

            GameBoard gameBoard = new GameBoard(metadata.GameType);

            foreach (string moveString in moveList)
            {
                Move move = null;
                try
                {
                    move = NotationUtils.ParseMoveString(gameBoard, moveString);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Unable to parse '{0}'.", moveString), ex);
                }

                gameBoard.TrustedPlay(move, moveString);
            }

            // Set result
            if (Enum.TryParse(rawResult, out BoardState result))
            {
                metadata.SetTag("Result", result.ToString());
            }
            else
            {
                metadata.SetTag("Result", gameBoard.BoardState.ToString());
            }

            return(new GameRecording(gameBoard, GameRecordingSource.PGN, metadata)
            {
                FileName = fileName?.Trim()
            });
        }