コード例 #1
0
    public void DisplayEnclosedArea(EnclosedArea enclosedArea)
    {
        ClearInspectorWindow();
        currentDisplay = InspectorText.Area;

        inspectorWindowTitle.text = $"Enclosure {enclosedArea.id + 1}";

        // THe composition is a list of float value in the order of the AtmoshpereComponent Enum
        float[] terrainComposition = enclosedArea.terrainComposition;

        string displayText = "";

        // Atmospheric info
        //displayText += "Atmospheric composition: \n";
        //foreach (var (value, index) in atmosphericComposition.WithIndex())
        //{
        //    displayText += $"{((AtmosphereComponent)index).ToString()} : {value}\n";
        //}

        foreach (var(value, index) in terrainComposition.WithIndex())
        {
            if (value == 0)
            {
                continue;
            }
            displayText += $"{((TileType)index).ToString()} : {value}\n";
        }

        //displayText += "\n";
        //displayText += $"Population count: {enclosedArea.populations.Count}\n";
        //displayText += $"Total animal count: {enclosedArea.animals.Count}\n";
        //displayText += $"Food Source count: {enclosedArea.foodSources.Count}\n";

        this.inspectorWindowText.text = displayText;
    }
コード例 #2
0
        public override string ToString()
        {
            StringBuilder lStringBuilder = new StringBuilder();

            lStringBuilder.AppendLine(".." + Defender.ToString2() + " Color Enclosed Region #" + _RegionNbr + " At: " + Board.Coord.ToString(Members[0].MemberList[0]));

            lStringBuilder.Append("....Members Block: (" + Members.Count + ") ");
            foreach (GoBlockBase lGoBlockBase in Members)
            {
                lStringBuilder.Append(Board.Coord.ToString(lGoBlockBase.Members.GetFirst()) + " ");
            }
            lStringBuilder.AppendLine();

            lStringBuilder.Append("....Neighbors Blocks: (" + Neighbors.Count + ") ");
            foreach (GoBlockBase lGoBlockBase in Neighbors)
            {
                lStringBuilder.Append(Board.Coord.ToString(lGoBlockBase.Members.GetFirst()) + " ");
            }
            lStringBuilder.AppendLine();

            lStringBuilder.Append("....Enclosing Blocks: (" + EnclosingBlocks.Count + ") ");
            foreach (GoBlockBase lGoBlock in EnclosingBlocks)
            {
                lStringBuilder.Append(Board.Coord.ToString(lGoBlock.Members.GetFirst()) + " ");
            }
            lStringBuilder.AppendLine();

            lStringBuilder.Append("....Interior Defender Blocks: (" + InteriorDefenderBlocks.Count + ") ");
            foreach (GoBlockBase lGoBlock in InteriorDefenderBlocks)
            {
                lStringBuilder.Append(Board.Coord.ToString(lGoBlock.Members.GetFirst()) + " ");
            }
            lStringBuilder.AppendLine();

            lStringBuilder.Append("....Interior Attacker Blocks: (" + InteriorAttackerBlocks.Count + ") ");
            foreach (GoBlockBase lGoBlock in InteriorAttackerBlocks)
            {
                lStringBuilder.Append(Board.Coord.ToString(lGoBlock.Members.GetFirst()) + " ");
            }
            lStringBuilder.AppendLine();

            lStringBuilder.AppendLine("....Is Small Enclosed: " + IsSmall.ToString());
            //			lStringBuilder.AppendLine("....Total Empty Region: ");
            //			lStringBuilder.AppendLine(TotalEmptyRegion.ToString());

            lStringBuilder.AppendLine("....Is 1-Vital: " + Is1Vital.ToString());
            lStringBuilder.AppendLine("....Is 2-Vital: " + Is2Vital.ToString());

            lStringBuilder.AppendLine("....Has Interior: " + (EmptyArea.HasInterior() ? "Yes" : "No"));
            //			lStringBuilder.Append("Accessible Liberties:\n" + AccessibleLiberties.ToString());
            lStringBuilder.Append("Empty Area:\n" + EmptyArea.ToString());
            lStringBuilder.Append("Attackers Eye Area:\n" + AttackersEyeArea.ToString());
            lStringBuilder.Append("Enclosed Region:\n" + EnclosedArea.ToString());


            return(lStringBuilder.ToString().TrimEnd('\n'));
        }
コード例 #3
0
    /// <summary>
    /// Call this to update all the enclosed areas and create an EnclosedArea data structure to hold its information.
    /// </summary>
    /// <remarks>
    /// This is using a flood fill (https://en.wikipedia.org/wiki/Flood_fill) to find enclosed areas.
    /// Assumptions: the reserve is bordered by walls
    /// NOTE: this assumption does not hold up for some reserves, such as Level2E2 and Level2E3
    /// </remarks>
    public void UpdateEnclosedAreas(bool isUpdate = true)
    {
        // non-wall tiles
        HashSet <Vector3Int> accessed = new HashSet <Vector3Int>();
        // wall or null tiles
        HashSet <Vector3Int> unaccessible = new HashSet <Vector3Int>();
        // walls
        Stack <Vector3Int> walls = new Stack <Vector3Int>();

        List <EnclosedArea> newEnclosedAreas = new List <EnclosedArea>();

        // Initial flood fill
        this.enclosedAreaCount = 0;
        EnclosedArea area = new EnclosedArea(this.enclosedAreaCount);

        newEnclosedAreas.Add(area);

        // If startingPositions is empty on start, startingPositions will contain gridSystem.startTile by default.
        foreach (var startingPos in startingPositions)
        {
            if (area.coordinates.Count > 0)
            {
                this.enclosedAreaCount++;
                area = new EnclosedArea(this.enclosedAreaCount);
                newEnclosedAreas.Add(area);
            }
            this.FloodFill(startingPos, accessed, unaccessible, walls, enclosedAreaCount, area, isUpdate);

            Vector3Int curPos = startingPos;
            while (walls.Count > 0)
            {
                if (area.coordinates.Count != 0)
                {
                    this.enclosedAreaCount++;
                    area = new EnclosedArea(this.enclosedAreaCount);
                    newEnclosedAreas.Add(area);
                }

                curPos = walls.Pop();

                this.FloodFill(curPos + Vector3Int.left, accessed, unaccessible, walls, this.enclosedAreaCount, area, isUpdate);
                this.FloodFill(curPos + Vector3Int.up, accessed, unaccessible, walls, this.enclosedAreaCount, area, isUpdate);
                this.FloodFill(curPos + Vector3Int.right, accessed, unaccessible, walls, this.enclosedAreaCount, area, isUpdate);
                this.FloodFill(curPos + Vector3Int.down, accessed, unaccessible, walls, this.enclosedAreaCount, area, isUpdate);
            }
        }

        // Not initializing: update the areas based on the previous ones
        if (isUpdate)
        {
        }

        this.internalEnclosedAreas = newEnclosedAreas;
        this.UpdatePublicEnclosedAreas();
    }
コード例 #4
0
    private void logAtmoesphereChange(EnclosedArea enclosedArea)
    {
        LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"Atmospheric composition changed at enclose area {enclosedArea.id}!");

        if (!this.enclosedAreaLogs.ContainsKey(enclosedArea))
        {
            this.enclosedAreaLogs.Add(enclosedArea, new List<LogEntry>());
        }

        this.enclosedAreaLogs[enclosedArea].Add(newLog);
        this.worldLog.Add(newLog);
    }
コード例 #5
0
    private void logNewCreation(object creation)
    {
        if (creation.GetType() == typeof(Population))
        {
            Population population = (Population)creation;

            if (!this.populationLogs.ContainsKey(population))
            {
                this.populationLogs.Add(population, new List<LogEntry>());
            }

            LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"New {population.species.SpeciesName} created!");

            this.populationLogs[population].Add(newLog);
            this.worldLog.Add(newLog);
        }
        else if (creation.GetType() == typeof(FoodSource))
        {
            FoodSource foodSource = (FoodSource)creation;

            if (!this.foodSourceLogs.ContainsKey(foodSource))
            {
                this.foodSourceLogs.Add(foodSource, new List<LogEntry>());
            }

            LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"New {foodSource.Species.SpeciesName} created!");

            this.foodSourceLogs[foodSource].Add(newLog);
            this.worldLog.Add(newLog);
        }
        else if (creation.GetType() == typeof(EnclosedArea))
        {
            EnclosedArea enclosedArea = (EnclosedArea)creation;

            // Don't log empty enclosed area
            if (enclosedArea.coordinates.Count == 0)
            {
                return;
            }

            if (!this.enclosedAreaLogs.ContainsKey(enclosedArea))
            {
                this.enclosedAreaLogs.Add(enclosedArea, new List<LogEntry>());
            }

            LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"Enclosed area {enclosedArea.id} created");

            this.enclosedAreaLogs[enclosedArea].Add(newLog);
            this.worldLog.Add(newLog);
        }
    }
コード例 #6
0
    private void logLiquidChange(Vector3Int cellPos)
    {
        enclosureSystem.UpdateEnclosedAreas();
        EnclosedArea enclosedArea = this.enclosureSystem.GetEnclosedAreaByCellPosition(cellPos);

        if (!this.enclosedAreaLogs.ContainsKey(enclosedArea))
        {
            this.enclosedAreaLogs.Add(enclosedArea, new List<LogEntry>());
        }

        LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"Liquid composition changed at enclose area {enclosedArea.id}!");
        this.enclosedAreaLogs[enclosedArea].Add(newLog);
        this.worldLog.Add(newLog);
    }
コード例 #7
0
    public void AddCoordinate(Coordinate coordinate, int tileType, EnclosedArea prevArea = null)
    {
        if (GameManager.Instance.m_tileDataController.IsCellinGrid(coordinate.x, coordinate.y))
        {
            TileData tileData = GameManager.Instance.m_tileDataController.GetTileData(new UnityEngine.Vector3Int(coordinate.x, coordinate.y, 0));

            this.coordinates.Add(coordinate);

            if (tileData.Animal)
            {
                this.animals.Add(tileData.Animal.GetComponent <Animal>());

                Population population = tileData.Animal.GetComponent <Animal>().PopulationInfo;

                if (!this.populations.Contains(population))
                {
                    this.populations.Add(population);
                }
            }
            if (tileData.Food)
            {
                this.foodSources.Add(tileData.Food.GetComponent <FoodSource>());
            }

            // TODO: If an enclosure is not contained entirely within walls (IE if any tile touches an empty space), then set this.isEnclosed to false
            // NOTE: This code works, but will fail if the level is not entirely surrounded by walls and is not square-shaped
            if (tileType != (int)TileType.Wall && GameManager.Instance.m_tileDataController.IsCellOnGridEdge(coordinate.x, coordinate.y))
            {
                isEnclosed = false;
            }
        }

        this.terrainComposition[tileType]++;

        if (prevArea != null)
        {
            if (previousArea.ContainsKey(prevArea.id))
            {
                previousArea[prevArea.id]++;
            }
            else
            {
                previousArea.Add(prevArea.id, 1);
            }
        }
    }
コード例 #8
0
    private void logTerrainChange(List<Vector3Int> changedTiles)
    {
        List<byte> seenEnclosedAreaIds = new List<byte>();

        foreach (Vector3Int pos in changedTiles)
        {
            EnclosedArea enclosedArea = this.enclosureSystem.GetEnclosedAreaByCellPosition(pos);

            if (!seenEnclosedAreaIds.Contains(enclosedArea.id))
            {
                if (!this.enclosedAreaLogs.ContainsKey(enclosedArea))
                {
                    this.enclosedAreaLogs.Add(enclosedArea, new List<LogEntry>());
                }

                LogEntry newLog = new LogEntry(Math.Round(Time.time, 0, MidpointRounding.AwayFromZero).ToString(), $"Terrain changed in enclosed area {enclosedArea.id}");
                this.enclosedAreaLogs[enclosedArea].Add(newLog);
                this.worldLog.Add(newLog);

                seenEnclosedAreaIds.Add(enclosedArea.id);
            }
        }
    }
コード例 #9
0
    /// <summary>
    /// Recursive flood fill.
    /// </summary>
    /// <param name="cur">Start location</param>
    /// <param name="accessed">Accessed cells</param>
    /// <param name="unaccessible">Unaccessible cells</param>
    /// <param name="walls">wall cells</param>
    /// <param name="atmosphereCount">index of the enclosed area</param>
    private void FloodFill(Vector3Int start, HashSet <Vector3Int> accessed, HashSet <Vector3Int> unaccessible, Stack <Vector3Int> walls, byte atmosphereCount, EnclosedArea enclosedArea, bool isUpdate)
    {
        if (accessed.Contains(start) || unaccessible.Contains(start))
        {
            // checked before, move on
            return;
        }

        // Using iterative approach due to stack overflow with large maps
        Stack <Vector3Int> stack = new Stack <Vector3Int>();

        stack.Push(start);

        Vector3Int cur;

        while (stack.Count > 0)
        {
            cur = stack.Pop();


            if (accessed.Contains(cur) || unaccessible.Contains(cur))
            {
                // checked before, move on
                continue;
            }

            // check if tilemap has tile
            GameTile tile = GameManager.Instance.m_tileDataController.GetGameTileAt(cur);
            if (tile != null)
            {
                if (tile.type != TileType.Wall)
                {
                    // Mark the cell
                    accessed.Add(cur);

                    // Updating enclosed area
                    if (isUpdate && this.positionToEnclosedArea.ContainsKey(cur) && this.GetEnclosedAreaById(this.positionToEnclosedArea[cur]) != null)
                    {
                        // Add the tile and tell the enclosed area what the previous area is
                        enclosedArea.AddCoordinate(new EnclosedArea.Coordinate(cur.x, cur.y), (int)tile.type, this.GetEnclosedAreaById(this.positionToEnclosedArea[cur]));
                    }
                    // Initial round
                    else
                    {
                        enclosedArea.AddCoordinate(new EnclosedArea.Coordinate(cur.x, cur.y), (int)tile.type, null);
                    }

                    this.positionToEnclosedArea[cur] = atmosphereCount;
                    stack.Push(cur + Vector3Int.left);
                    stack.Push(cur + Vector3Int.up);
                    stack.Push(cur + Vector3Int.right);
                    stack.Push(cur + Vector3Int.down);
                }
                else
                {
                    walls.Push(cur);
                    unaccessible.Add(cur);
                }
            }
            else
            {
                unaccessible.Add(cur);
            }
        }
    }