Ejemplo n.º 1
0
    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));
    }
Ejemplo n.º 2
0
    private bool VisTest(MazeTile mt, int i)
    {
        if (maze.GetTileSrc(mt.coord) == '#')
        {
            int neighborsWhoAreUp = maze.CountDiscoveredNeighborWalls(mt.coord);
            if (neighborsWhoAreUp >= 2)
            {
                mt.SetDiscovered(true, this, maze);
                vision[mt.coord] = true;
                return(true);
            }
        }
        Vector3 p = transform.position;
        Vector3 t = mt.transform.position;//CalcVisibilityTarget();
        Vector2 c = Random.insideUnitCircle;

        t.x += c.x * maze.tileSize.x / 2;
        t.z += c.y * maze.tileSize.z / 2;
        t.y -= 0.0625f;
        Vector3 delta = t - p;
        float   dist  = delta.magnitude;

        if (dist < maze.tileSize.x)
        {
            mt.SetDiscovered(true, this, maze);
            vision[mt.coord] = true;
            return(true);
        }
        if (dist > sc.radius + maze.tileSize.x)
        {
            Blink(); return(true);
        }                                                                // remove from list without resolving visibility
        Ray  r       = new Ray(p, delta / dist);
        bool blocked = Physics.Raycast(r, out RaycastHit rh);

        if (wires != null && i >= 0)
        {
            while (wires.Count <= i)
            {
                wires.Add(Lines.MakeWire().Line(Vector3.zero));
            }
        }
        //Lines.Mak
        if (rh.transform == mt.transform)
        {
            if (wires != null && i >= 0)
            {
                wires[i].Line(p, t, Color.green);
            }
            mt.SetDiscovered(true, this, maze);
            vision[mt.coord] = true;
            return(true);
        }
        else
        {
            if (wires != null && i >= 0)
            {
                wires[i].Line(p, rh.point, Color.red);
            }
        }
        return(false);
    }