示例#1
0
        public static async Task <ChessBoard> FromStreamAsync(Stream stream)
        {
            bool?hasStarted = null;

            string[]      playerNames     = new string[2];
            PlayerColor[] playerColors    = new PlayerColor[2];
            int           playersReceived = 0;
            string        winner          = null;
            double?       turnTimeLeft    = null;
            List <string> moves           = new List <string>();

            var settings = new XmlReaderSettings()
            {
                Async = true
            };

            using (var xml = XmlReader.Create(stream, settings))
                while (await xml.ReadAsync())
                {
                    if (!xml.IsStartElement())
                    {
                        continue;
                    }
                    if (xml.Name == "Game")
                    {
                        if (hasStarted != null)
                        {
                            throw new InvalidDataException();
                        }
                        hasStarted = xml.GetAttribute("HasStarted") == "true";
                        winner     = xml.GetAttribute("Winner");
                    }
                    else if (xml.Name == "Player")
                    {
                        if (playersReceived >= 2)
                        {
                            throw new InvalidDataException();
                        }
                        playerNames[playersReceived]  = xml.GetAttribute("Name");
                        playerColors[playersReceived] = xml.GetAttribute("Color") == "Black" ? PlayerColor.Black : PlayerColor.White;
                        playersReceived++;
                    }
                    else if (xml.Name == "Turn")
                    {
                        if (turnTimeLeft != null)
                        {
                            throw new InvalidDataException();
                        }
                        string timeLeftString = xml.GetAttribute("TimeLeft");
                        if (!double.TryParse(timeLeftString, out double timeLeftDouble))
                        {
                            throw new InvalidDataException("Invalid turn element!");
                        }
                        turnTimeLeft = timeLeftDouble;
                    }
                    else if (xml.Name == "Board")
                    {
                        while (await xml.ReadAsync())
                        {
                            if (!xml.IsStartElement("Move"))
                            {
                                break;
                            }
                            moves.Add(await xml.ReadElementContentAsStringAsync());
                        }
                    }
                    else
                    {
                        throw new InvalidDataException("Invalid ChessBoard xml!");
                    }
                }

            if (hasStarted == null)
            {
                throw new InvalidDataException();
            }

            //If the game hasn't started, just return an empty ChessBoard
            if (!hasStarted.Value)
            {
                return(new ChessBoard());
            }

            //Validate input when the game has started...
            if (playersReceived != 2)
            {
                throw new InvalidDataException();
            }
            if (playerNames.Any(name => string.IsNullOrWhiteSpace(name)))
            {
                throw new InvalidDataException();
            }
            if (!playerColors.Any(color => color == PlayerColor.White) || !playerColors.Any(color => color == PlayerColor.Black))
            {
                throw new InvalidDataException();
            }

            string whiteName = playerColors[0] == PlayerColor.White ? playerNames[0] : playerNames[1];
            string blackName = playerColors[0] == PlayerColor.White ? playerNames[1] : playerNames[0];

            if (!string.IsNullOrWhiteSpace(winner))
            {
                return(new ChessBoard(whiteName, blackName, winner, moves.ToArray()));
            }

            //Validate input when the game hasn't ended yet...
            if (turnTimeLeft == null)
            {
                throw new InvalidDataException();
            }

            return(new ChessBoard(whiteName, blackName, turnTimeLeft.Value, moves.ToArray()));
        }