All Downloads are FREE. Search and download functionalities are using the official Maven repository.

spire.example.maze.scala Maven / Gradle / Ivy

The newest version!
package spire.example

import Predef.{any2stringadd => _, intWrapper => _, _}

import spire.algebra._
import spire.implicits._
import spire.math._
import spire.random._
//import spire.syntax._

import scala.reflect.ClassTag
import scala.annotation.tailrec
import scala.collection.mutable

object Maze {
  def empty[B: ClassTag](w: Int, h: Int)(fill: B) =
    Maze(w, h, Array.fill(w * h)(fill))
}

case class Maze[A](w: Int, h: Int, grid: Array[A]) extends Traversable[A] {
  def apply(x: Int, y: Int): A = grid(y * w + x)
  def update(x: Int, y: Int, a: A): Unit = grid(y * w + x) = a
  def foreach[U](f: A => U): Unit = grid.foreach(f)
  def map[B: ClassTag](f: A => B): Maze[B] = Maze(w, h, grid.map(f).toArray)

  def display(): String = {
    val sb = new StringBuilder()
    cfor(0)(_ < h, _ + 1) { y =>
      cfor(0)(_ < w, _ + 1) { x =>
        sb.append(apply(x, y).toString)
      }
      sb.append("\n")
    }
    sb.toString
  }
}

object Coord {
  def wall: Coord = Wall
  def floor: Coord = Floor
}

sealed abstract class Coord(s: String) {
  override def toString(): String = s
}

case object Floor extends Coord("\033[0m  ")
case object Wall extends Coord("\033[7m  ")

object MazeDemo {
  def main(args: Array[String]) {
    val w = 31
    val h = 31
    val grid = Maze.empty(w, h)(Coord.wall)

    val (lw, lh) = (w - 1, h - 1)

    type Color = Int
    type Point = (Int, Int)

    var ncolors: Int = 0
    val colors = mutable.Map.empty[Point, Color]
    cfor(1)(_ < lh, _ + 2) { y =>
      cfor(1)(_ < lw, _ + 2) { x =>
        grid(x, y) = Coord.floor
        colors((x, y)) = ncolors
        ncolors += 1
      }
    }

    val walls = mutable.ArrayBuffer.empty[Point]
    cfor(1)(_ < lh, _ + 1) { y =>
      cfor((y & 1) + 1)(_ < lw, _ + 2) { x =>
        walls.append((x, y))
      }
    }

    val queue = walls.toArray
    val len = queue.length
    queue.qshuffle()

    cfor(0)(_ < len && ncolors > 1, _ + 1) { i =>
      val j = i //fixme
      val (x, y) = queue(j) //fixme
      val (s1, s2) = if ((x & 1) == 0)
        ((x - 1, y), (x + 1, y))
      else
        ((x, y - 1), (x, y + 1))

      val (color1, color2) = (colors(s1), colors(s2))
      if (color1 != color2) {
        grid(x, y) = Coord.floor
        colors.foreach { case (k, v) => if (v == color2) colors(k) = color1 }
        ncolors -= 1
      }
    }

    println(grid.display)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy