Exemplo n.º 1
0
            static private SnakeInfo CalculatePlayerSnake(
                IReadOnlyDictionary <Point, PointInfo> locationToPointInfoIndex,
                IReadOnlyDictionary <BoardElement, ImmutableHashSet <PointInfo> > boardElementToInfosIndex,
                IReadOnlyList <ISnakeInfo> previousTickSnakeInfos,
                IReadOnlyDictionary <Point, PointInfo> previousTickLocationToPointInfoIndex)
            {
                SnakeInfo playerSnake = default;
                ImmutableHashSet <PointInfo> playerHeads = GetPlayerHeads(boardElementToInfosIndex);
                PointInfo head = playerHeads?.Single();

                if (head != default)
                {
                    playerSnake = new SnakeInfo
                    {
                        FoundHead     = true,
                        FuryTicksLeft = head.BoardElement == BoardElement.HeadEvil ? -1 : 0,
                        IsActive      =
                            head.BoardElement != BoardElement.HeadSleep &&
                            head.BoardElement != BoardElement.HeadDead,
                        IsPlayerSnake = true
                    };

                    playerSnake.AddHead(head.Location);
                }
                else
                {
                    ImmutableHashSet <PointInfo> playerTails = GetPlayerTails(boardElementToInfosIndex);
                    PointInfo tail = playerTails?.SingleOrDefault();
                    if (tail != default)
                    {
                        playerSnake = new SnakeInfo
                        {
                            FoundTail     = true,
                            FuryTicksLeft = -2,
                            IsActive      = tail.BoardElement != BoardElement.TailInactive,
                            IsPlayerSnake = true
                        };

                        playerSnake.AddTail(tail.Location);
                    }
                }

                if (playerSnake == default)
                {
                    playerSnake = new SnakeInfo
                    {
                        FoundHead     = false,
                        FoundTail     = false,
                        IsPlayerSnake = true,
                        FuryTicksLeft = -2,
                        // Неактивного тела не бывает.
                        IsActive = true
                    };

                    playerSnake.AddTail(GetPlayerBodyPart(boardElementToInfosIndex).First().Location);
                }

                bool foundNext = true;

                while (foundNext)
                {
                    foundNext = false;

                    if (playerSnake.FoundHead)
                    {
                        PointInfo currentTail = locationToPointInfoIndex[playerSnake.Tail];
                        if (TryGetNextPlayerPoint(playerSnake, currentTail, out PointInfo newTail, searchForBody: true))
                        {
                            playerSnake.AddTail(newTail.Location);
                            foundNext = true;
                        }
                        else if (TryGetNextPlayerPoint(playerSnake, currentTail, out newTail, searchForTail: true))
                        {
                            playerSnake.AddTail(newTail.Location);
                            playerSnake.FoundTail = true;
                            // Если найдены хвост и голова, значит найдено всё тело.
                        }
                    }