Time for an 2014 update…

This commit is contained in:
Ingy döt Net 2014-01-17 05:32:22 +00:00
parent 372c577f83
commit 09687c4926
2520 changed files with 34227 additions and 7318 deletions

View file

@ -1,21 +1,18 @@
import std.stdio, std.algorithm, std.range, std.random;
alias R = std.array.replicate;
void main() {
enum int w = 14, h = 10;
auto vis = new bool[][](h, w),
hor = iota(h + 1).map!(_ => ["+---"].R(w)).array,
ver = h.iota.map!(_ => ["| "].R(w) ~ "|").array;
import std.stdio, std.algorithm, std.range, std.random;
void walk(in int x, in int y) /*nothrow*/ {
enum uint w = 14, h = 10;
auto vis = new bool[][](h, w),
hor = iota(h + 1).map!(_ => ["+---"].replicate(w)).array,
ver = h.iota.map!(_ => ["| "].replicate(w) ~ "|").array;
void walk(in uint x, in uint y) /*nothrow*/ {
vis[y][x] = true;
static struct P { immutable uint x, y; } // Will wrap-around.
auto d = [P(x-1, y), P(x, y+1), P(x+1, y), P(x, y-1)];
foreach (p; d.randomCover) {
if (p.x >= w || p.y >= h || vis[p.y][p.x]) continue;
if (p.x == x) hor[max(y, p.y)][x] = "+ ";
if (p.y == y) ver[y][max(x, p.x)] = " ";
walk(p.tupleof);
foreach (p; [[x-1,y], [x,y+1], [x+1,y], [x,y-1]].randomCover) {
if (p[0] >= w || p[1] >= h || vis[p[1]][p[0]]) continue;
if (p[0] == x) hor[max(y, p[1])][x] = "+ ";
if (p[1] == y) ver[y][max(x, p[0])] = " ";
walk(p[0], p[1]);
}
}
walk(uniform(0, w), uniform(0, h));

View file

@ -0,0 +1,86 @@
import scala.util.Random
object MazeTypes {
case class Direction(val dx: Int, val dy: Int)
case class Loc(val x: Int, val y: Int) {
def +(that: Direction): Loc = Loc(x + that.dx, y + that.dy)
}
case class Door(val from: Loc, to: Loc)
val North = Direction(0,-1)
val South = Direction(0,1)
val West = Direction(-1,0)
val East = Direction(1,0)
val directions = Set(North, South, West, East)
}
object MazeBuilder {
import MazeTypes._
def shuffle[T](set: Set[T]): List[T] = Random.shuffle(set.toList)
def buildImpl(current: Loc, grid: Grid): Grid = {
var newgrid = grid.markVisited(current)
val nbors = shuffle(grid.neighbors(current))
nbors.foreach { n =>
if (!newgrid.isVisited(n)) {
newgrid = buildImpl(n, newgrid.markVisited(current).addDoor(Door(current, n)))
}
}
newgrid
}
def build(width: Int, height: Int): Grid = {
val exit = Loc(width-1, height-1)
buildImpl(exit, new Grid(width, height, Set(), Set()))
}
}
class Grid(val width: Int, val height: Int, val doors: Set[Door], val visited: Set[Loc]) {
def addDoor(door: Door): Grid =
new Grid(width, height, doors + door, visited)
def markVisited(loc: Loc): Grid =
new Grid(width, height, doors, visited + loc)
def isVisited(loc: Loc): Boolean =
visited.contains(loc)
def neighbors(current: Loc): Set[Loc] =
directions.map(current + _).filter(inBounds(_)) -- visited
def printGrid(): List[String] = {
(0 to height).toList.flatMap(y => printRow(y))
}
private def inBounds(loc: Loc): Boolean =
loc.x >= 0 && loc.x < width && loc.y >= 0 && loc.y < height
private def printRow(y: Int): List[String] = {
val row = (0 until width).toList.map(x => printCell(Loc(x, y)))
val rightSide = if (y == height-1) " " else "|"
val newRow = row :+ List("+", rightSide)
List.transpose(newRow).map(_.mkString)
}
private val entrance = Loc(0,0)
private def printCell(loc: Loc): List[String] = {
if (loc.y == height)
List("+--")
else List(
if (openNorth(loc)) "+ " else "+--",
if (openWest(loc) || loc == entrance) " " else "| "
)
}
def openNorth(loc: Loc): Boolean = openInDirection(loc, North)
def openWest(loc: Loc): Boolean = openInDirection(loc, West)
private def openInDirection(loc: Loc, dir: Direction): Boolean =
doors.contains(Door(loc, loc + dir)) || doors.contains(Door(loc + dir, loc))
}