Grid/Base/GridFiller.cs
using System;

namespace Sandbox.Grid.Base
{
    /// <summary>
    /// GridFiller – vastaa seinien, kulmien, ulkorajan ja lattian täyttämisestä gridillä.
    /// Sisältää gridin alustuksen, seinien rakentamisen huoneista/lattioista,
    /// kulmien täyttämisen, ulkorajan seinien rakentamisen ja ulkoalueen täyttämisen.
    /// Sisältää myös apumetodit lattian ja seinien tunnistamiseen.
    /// </summary>
    internal class GridFiller
    {
        private readonly char[,] grid;
        private readonly int W;
        private readonly int H;

        public GridFiller(char[,] grid, int w, int h)
        {
            this.grid = grid;
            this.W = w;
            this.H = h;
        }

        /// <summary>
        /// Alustaa gridin tyhjillä merkeillä (' ').
        /// </summary>
        public void InitGrid()
        {
            for (int y = 0; y < H; y++)
                for (int x = 0; x < W; x++)
                    grid[x, y] = ' ';
        }

        /// <summary>
        /// Rakentaa seinät huoneiden sisälattian ('.') ympärille.
        /// </summary>
        public void BuildWallsFromRooms()
        {
            for (int y = 1; y < H - 1; y++)
            {
                for (int x = 1; x < W - 1; x++)
                {
                    if (!IsInteriorFloor(grid[x, y]))
                        continue;

                    TryMakeWall(x + 1, y);
                    TryMakeWall(x - 1, y);
                    TryMakeWall(x, y + 1);
                    TryMakeWall(x, y - 1);
                }
            }
        }

        /// <summary>
        /// Yrittää asettaa seinän tyhjään ruutuun.
        /// </summary>
        public void TryMakeWall(int x, int y)
        {
            if (grid[x, y] == ' ')
                grid[x, y] = '-';
        }

        /// <summary>
        /// Rakentaa seinät kaiken lattian ympärille (ei käytössä pääluokassa, säilytetään).
        /// </summary>
        public void BuildWallsFromFloors()
        {
            for (int y = 1; y < H - 1; y++)
            {
                for (int x = 1; x < W - 1; x++)
                {
                    if (!IsAnyFloor(grid[x, y]))
                        continue;

                    TryMakeWall(x + 1, y);
                    TryMakeWall(x - 1, y);
                    TryMakeWall(x, y + 1);
                    TryMakeWall(x, y - 1);
                }
            }
        }

        /// <summary>
        /// Täyttää seinien väliset tyhjät kulmat seinillä.
        /// Käsittelee sekä suorat että L-kulmat (diagonaalit).
        /// </summary>
        public void FillWallCorners()
        {
            for (int y = 1; y < H - 1; y++)
            {
                for (int x = 1; x < W - 1; x++)
                {
                    if (grid[x, y] != ' ')
                        continue;

                    // vaakaseinät molemmin puolin → täytä kulma
                    if (grid[x - 1, y] == '-' && grid[x + 1, y] == '-')
                    {
                        grid[x, y] = '-';
                        continue;
                    }

                    // pystysuunnassa molemmin puolin
                    if (grid[x, y - 1] == '-' && grid[x, y + 1] == '-')
                    {
                        grid[x, y] = '-';
                        continue;
                    }

                    // L-kulmat (diagonaalit)
                    if (
                        (grid[x - 1, y] == '-' && grid[x, y - 1] == '-') ||
                        (grid[x + 1, y] == '-' && grid[x, y - 1] == '-') ||
                        (grid[x - 1, y] == '-' && grid[x, y + 1] == '-') ||
                        (grid[x + 1, y] == '-' && grid[x, y + 1] == '-')
                    )
                    {
                        grid[x, y] = '-';
                    }
                }
            }
        }

        /// <summary>
        /// Rakentaa ulkorajan seinät ('#') gridin reunoille.
        /// </summary>
        public void BuildOuterBoundaryWall()
        {
            for (int x = 0; x < W; x++)
            {
                grid[x, 0] = '#';
                grid[x, H - 1] = '#';
            }

            for (int y = 0; y < H; y++)
            {
                grid[0, y] = '#';
                grid[W - 1, y] = '#';
            }
        }

        /// <summary>
        /// Täyttää gridin jäljellä olevat tyhjät ruudut ulkolattialla ('.').
        /// </summary>
        public void FillOutsideWithGround()
        {
            for (int y = 0; y < H; y++)
                for (int x = 0; x < W; x++)
                    if (grid[x, y] == ' ')
                        grid[x, y] = '.';
        }

        // --------------------------------------------------
        // Apumetodit
        // --------------------------------------------------

        /// <summary>
        /// Onko merkki talon sisäinen lattia (',').
        /// </summary>
        public bool IsInteriorFloor(char c) => c == ',';

        /// <summary>
        /// Onko merkki mikä tahansa lattia ('.' tai ',').
        /// </summary>
        public bool IsAnyFloor(char c) => c == '.' || c == ',';

        /// <summary>
        /// Onko merkki seinä ('-' tai '#').
        /// </summary>
        public bool IsWall(char c) => c == '-' || c == '#';

        /// <summary>
        /// Koskeeko ruutu seinää neljänsuunnassa.
        /// </summary>
        public bool TouchesWall(int x, int y)
        {
            return IsWall(grid[x - 1, y]) ||
                   IsWall(grid[x + 1, y]) ||
                   IsWall(grid[x, y - 1]) ||
                   IsWall(grid[x, y + 1]);
        }

        /// <summary>
        /// Onko ruutu viereisessä ruudussa jokin annetuista merkeistä.
        /// </summary>
        public bool AdjacentTo(int x, int y, params char[] targets)
        {
            foreach (var t in targets)
            {
                if (grid[x - 1, y] == t ||
                    grid[x + 1, y] == t ||
                    grid[x, y - 1] == t ||
                    grid[x, y + 1] == t)
                    return true;
            }
            return false;
        }
    }
}