Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
86
Task/Maze-generation/Scala/maze-generation.scala
Normal file
86
Task/Maze-generation/Scala/maze-generation.scala
Normal 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))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue