Exemple #1
0
        public static void Erode(char[,] map, char wall = '#', char empty = ' ')
        {
            Coord size = map.GetSize();

            Erode(map, coord => {
                char c = map.At(coord);
                if (c != wall)
                {
                    return(false);
                }
                int count = 0;
                if (coord.row > 0 && map.At(coord + Coord.Up) == wall)
                {
                    ++count;
                }
                if (coord.col > 0 && map.At(coord + Coord.Left) == wall)
                {
                    ++count;
                }
                if (coord.row < size.row - 1 && map.At(coord + Coord.Down) == wall)
                {
                    ++count;
                }
                if (coord.col < size.col - 1 && map.At(coord + Coord.Right) == wall)
                {
                    ++count;
                }
                return(count == 1);
            }, c => map.SetAt(c, empty));
        }
Exemple #2
0
        public Map2d(char[,] m)
        {
            Coord s = m.GetSize();

            SetSize(m.GetSize());
            s.ForEach(c => map.SetAt(c, m.At(c)));
        }
Exemple #3
0
        State IsMapWalkable(Coord position, Coord direction, Coord stepSize, Coord wallSize, char[,] map)
        {
            Coord size = map.GetSize();
            Coord next = position + direction * stepSize;

            if (!next.IsWithin(size))
            {
                return(State.OutOfBounds);
            }
            Coord end = next + direction * wallSize;

            if (!end.IsWithin(size))
            {
                return(State.OutOfBounds);
            }
            char n = map.At(next), e = map.At(end);

            switch (n)
            {
            case Filled:
                switch (e)
                {
                case Filled: return(State.Unclaimed);

                case Walkable: return(State.Wall);

                default: return(State.Unknown);
                }

            case Walkable:
                switch (e)
                {
                case Filled: return(State.Incomplete);

                case Walkable: return(State.Empty);

                default: return(State.Unknown);
                }
            }
            return(State.Unknown);
        }
Exemple #4
0
        //public static void WriteMaze(int width, int height, int startx, int starty,
        //	int stepx, int stepy, int wallx, int wally, int seed, string filename, int erosion = 0, ShowOption option = ShowOption.None) {
        //	WriteMaze(new Coord(width, height), new Coord(startx, starty),
        //		new Coord(stepx, stepy), new Coord(wallx, wally), seed, filename, erosion, option);
        //}
        //public static void WriteMaze(Coord size, Coord start, Coord step, Coord wall, int seed, string filename, int erosion = 0,
        //	ShowOption option = ShowOption.None) {
        //	string maze = CreateMaze(size, start, step, wall, seed, erosion, option);
        //	System.IO.File.WriteAllText(filename, maze);
        //}
        //public static string CreateMaze(Coord size, Coord start, Coord step, Coord wall, int seed, int erosion = 0, ShowOption option = ShowOption.None) {
        //	MazeGenerator mg = new MazeGenerator(seed);
        //	mg.showOption = option;
        //	char[,] map = mg.Generate(size, start, step, wall);
        //	mg.Erode(map, erosion);
        //	if ((mg.showOption & ShowOption.Final) != 0) mg.Show(map);
        //	return ToString(map);
        //}
        public static string ToString(char[,] map)
        {
            StringBuilder sb = new StringBuilder();
            Coord         size = map.GetSize(), cursor;

            for (cursor.row = 0; cursor.row < size.row; ++cursor.row)
            {
                for (cursor.col = 0; cursor.col < size.col; ++cursor.col)
                {
                    sb.Append(map.At(cursor));
                }
                sb.Append('\n');
            }
            return(sb.ToString());
        }
    public void Generate(NonStandard.Data.Random.NumberGenerator random)
    {
        int width = ((stage + 2) * 2) + 1;

        mazeGenerationArguments.size = new Vector2(width, width);
        if (mazeSrc == null)
        {
            int seed = mazeGenerationArguments.seed;
            if (seed < 0)
            {
                seed = (int)GameClock.Time;
            }
            MazeGenerator mg = new MazeGenerator(random.Next);
            char[,] map = mg.Generate(mazeGenerationArguments.size, mazeGenerationArguments.start, mazeGenerationArguments.step, mazeGenerationArguments.wall);
            mg.Erode(map, mazeGenerationArguments.erosion);
            // generate ramps
            Coord          size = map.GetSize();
            List <Coord>[] ramp = new List <Coord> [4];
            for (int r = 0; r < ramp.Length; ++r)
            {
                ramp[r] = new List <Coord>();
            }
            const int W = 0, N = 1, E = 2, S = 3;// todo nwse
            size.ForEach(c => {
                if (c.row == 0 || c.row == size.row - 1 || c.col == 0 || c.col == size.col - 1)
                {
                    return;
                }
                char letter            = map.At(c);
                char n                 = map.At(c + Coord.Up), s = map.At(c + Coord.Down), e = map.At(c + Coord.Right), w = map.At(c + Coord.Left);
                bool createAtDeadEnds  = true;
                bool createAtPeninsula = true;
                if (n == s && e != w)
                {
                    if (letter == e && w == n)
                    {
                        if (letter == ' ' && createAtDeadEnds)
                        {
                            ramp[W].Add(c);
                        }
                        if (letter == '#' && createAtPeninsula)
                        {
                            ramp[E].Add(c);
                        }
                    }
                    if (letter == w && e == n)
                    {
                        if (letter == ' ' && createAtDeadEnds)
                        {
                            ramp[E].Add(c);
                        }
                        if (letter == '#' && createAtPeninsula)
                        {
                            ramp[W].Add(c);
                        }
                    }
                }
                if (e == w && n != s)
                {
                    if (letter == n && s == w)
                    {
                        if (letter == ' ' && createAtDeadEnds)
                        {
                            ramp[S].Add(c);
                        }
                        if (letter == '#' && createAtPeninsula)
                        {
                            ramp[N].Add(c);
                        }
                    }
                    if (letter == s && n == e)
                    {
                        if (letter == ' ' && createAtDeadEnds)
                        {
                            ramp[N].Add(c);
                        }
                        if (letter == '#' && createAtPeninsula)
                        {
                            ramp[S].Add(c);
                        }
                    }
                }
            });
            //ramp[W].ForEach(c => { map.SetAt(c, 'w'); });
            //ramp[N].ForEach(c => { map.SetAt(c, 'n'); });
            //ramp[E].ForEach(c => { map.SetAt(c, 'e'); });
            //ramp[S].ForEach(c => { map.SetAt(c, 's'); });
            int totalRamps = ramp.Sum(r => r.Count);
            for (int i = 0; i < totalRamps && i < stage + 1; ++i)
            {
                int[] r = ramp.GetNestedIndex(random.Next(totalRamps));
                //Debug.Log(r.JoinToString(", "));
                Coord loc = ramp[r[0]][r[1]];
                ramp[r[0]].RemoveAt(r[1]);
                char ch = "wnes"[r[0]];
                map.SetAt(loc, ch);
                --totalRamps;
            }
            this.map = new Map2d(map);
            //Debug.Log(this.map);
        }
        else
        {
            map.LoadFromString(mazeSrc.text);
        }
        seen.Reset();
        int count = map.Height * map.Width;

        while (mazeTiles.Count < count)
        {
            mazeTiles.Add(Instantiate(prefab_mazeTile.gameObject).GetComponent <MazeTile>());
        }
        //int index = 0;
        Vector3 off = new Vector3(map.Width / -2f * tileSize.x, 0, map.Height / -2f * tileSize.z);

        floorTiles = new List <MazeTile>();
        floorTileNeighborHistogram.SetEach(0);
        map.GetSize().ForEach(c => {
            MazeTile mt = GetTile(c);//mazeTiles[index++];
            mt.maze     = this;
            mt.coord    = c;
            Transform t = mt.transform;
            t.SetParent(_t);
            t.localPosition = mt.CalcLocalPosition();
            MazeTile.Kind k = MazeTile.Kind.None;
            switch (map[c])
            {
            case ' ': k = MazeTile.Kind.Floor; break;

            case '#': k = MazeTile.Kind.Wall; break;

            case 'w': k = MazeTile.Kind.RampWest; break;

            case 'n': k = MazeTile.Kind.RampNorth; break;

            case 's': k = MazeTile.Kind.RampSouth; break;

            case 'e': k = MazeTile.Kind.RampEast; break;
            }
            mt.kind = k;
            mt.SetDiscovered(false, null, this);
            if (mt.kind == MazeTile.Kind.Floor)
            {
                floorTiles.Add(mt);
                mt.goalScore = TileScorer(mt, map);
                int index    = (int)mt.goalScore;
                if (index >= floorTileNeighborHistogram.Length)
                {
                    Array.Resize(ref floorTileNeighborHistogram, index + 1);
                }
                ++floorTileNeighborHistogram[index];
            }
            else
            {
                mt.goalScore = float.PositiveInfinity;
            }
        });
        floorTiles.Sort((a, b) => a.goalScore.CompareTo(b.goalScore));
    }