Beispiel #1
0
    public void Init()
    {
        ///
        /// Notice:
        /// This map generator may have issues when edge case occurs.
        /// It'll be manually taken into account so that you don't have to care about that.
        //

        Random rd = new Random((int)DateTime.Now.Ticks);

        // Step 1 : Randomly generate obstacles.
        {
            map.Foreach((i, j, r) =>
            {
                double rate = 1.0 / Config.inst.gridPerObstacles; // 1 obstacle per 5 tiles.
                if (rd.NextDouble() < rate)
                {
                    r.type = Tile.Type.Obstacle;
                }
                return(r);
            });
        }

        List <(int x, int y)> vq = null;

        // Step 2 : Floodfill to find the largest connected componenet in the map.
        {
            bool[,] used = new bool[height, width];
            Ref <int> res = new Ref <int>(0);
            map.Foreach((i, j, r) =>
            {
                if (used[i, j])
                {
                    return(r);
                }

                int cnt  = 0;
                int[] di = new int[] { 1, -1, 0, 0 };
                int[] dj = new int[] { 0, 0, 1, -1 };

                var q = new List <(int x, int y)>();
                q.Add((i, j));
                used[i, j] = true;

                while (cnt != q.Count)
                {
                    var(ci, cj) = q[cnt++];
                    for (int t = 0; t < 4; t++)
                    {
                        var(ni, nj) = (ci + di[t], cj + dj[t]);
                        if (Inside(ni, nj) && map[ni, nj].type != Tile.Type.Obstacle)
                        {
                            if (!used[ni, nj])
                            {
                                q.Add((ni, nj));
                                used[ni, nj] = true;
                            }
                        }
                    }
                }

                if (res.v < cnt)
                {
                    res.v = cnt;
                    vq    = q;
                }
                return(r);
            });
            LogLine("Max connected componenet size: " + vq.Count);
        }

        // Generate resources. Remove collected resources.
        {
            double rate = 1.0 / Config.inst.gridPerResources;
            for (int i = 0; i < vq.Count; i++)
            {
                if (rd.NextDouble() < rate)
                {
                    map[vq[i].x, vq[i].y].type = Tile.Type.Resource;
                    (vq[i], vq[vq.Count - 1])  = (vq[vq.Count - 1], vq[i]);
                    vq.RemoveAt(vq.Count - 1);
                }
            }
        }

        // Generate Factories.
        {
            for (int i = 1; i <= playerCount; i++)
            {
                var(x, y) = vq[rd.Next(0, vq.Count - 1)];
                vq.Remove((x, y));
                map[x, y].type  = Tile.Type.Factory;
                map[x, y].owner = i;
            }
        }

        LogLine("Initial map:");
        LogLine(OutputString(0));
    }