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)); }
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); }