Skip to content

Instantly share code, notes, and snippets.

@kamiyaowl
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kamiyaowl/9201362 to your computer and use it in GitHub Desktop.
Save kamiyaowl/9201362 to your computer and use it in GitHub Desktop.
リファクタリング:scalaで迷路(穴掘り法)
import scala.util.Random
import scala.language.implicitConversions
object Digging {
implicit class ExtendMap[T1,T2](val self:Map[T1,T2]) {
def intersect[T1,T2](m:Map[T1,T2]) = {
(self.toList intersect m.toList).toMap
}
implicit def mapToExtendMap[T1,T2](self: Map[T1,T2]) : ExtendMap[T1,T2] = new ExtendMap[T1,T2](self)
}
implicit class Maze(val self:Map[(Int,Int),String]) {
def draw(implicit size:(Int,Int)) = {
for(j <- 0 until size._2)
{
for(i <- 0 until size._1){
self.get((i,j)) match {
case Some(s) => print(s)
case None => print(" ")
}
}
println("")
}
}
implicit def mapToMaze(self:Map[(Int,Int),String]) : Maze = new Maze(self)
}
def canDig(src:Map[(Int,Int),String])(target:(Int,Int), from:(Int,Int))(implicit size:(Int,Int)) = {
if(!src.contains(target)) false
else {
val suggest = aroundPoint(target)(size) filter(s => {
src.get(s) match {
case Some(n) => true//まだ
case None => false//掘ってある
}
})
suggest.length == 3//新しい行き先の3方向がまだ壁なら掘れる
}
}
def aroundPoint(p:(Int,Int), d:Int = 1)(implicit size:(Int,Int)) = { (List((p._1, p._2 - d), (p._1, p._2 + d), (p._1 - d, p._2), (p._1 + d, p._2))) filter(p => { (p._1 > -1) && (p._2 > -1) && (p._1 < size._1) && (p._2 < size._2)}) }
def dig(pos:(Int,Int), bsrc:Map[(Int,Int),String], s:List[(Int,Int)] = List())(implicit size:(Int,Int)) : Map[(Int,Int),String] = {
val src = bsrc filter(_._1 != pos)
val t = if(s.length == 0)(new Random).shuffle(aroundPoint(pos)(size)) else s
if(canDig(src)(t.head,pos)(size)) {
val next = dig(t.head,src)(size)
if(t.tail.length > 0) next intersect dig(pos,next,t.tail)
else next
} else if(t.tail.length > 0) dig(pos,src,t.tail)
else src
}
def fill(implicit size:(Int,Int), wall:String) = (for(i <- 0 until size._1 ; j <- 0 until size._2) yield ((i,j) -> wall)).toMap
def main(args:Array[String]) = {
implicit val w = 40
implicit val h = 20
implicit val size = (w,h)
implicit val wall = "#"
val r = new Random
val dst = dig((1 + r.nextInt(w - 2),1 + r.nextInt(h - 2)),fill) ++ Map((1,1) -> "S", (w - 2,h - 2) -> "F")
dst.draw
}
}
########################################
#S # ## # # # #
# # ## ###### # # ### ## # # # # #
# # # ## # # # # # ## #### # # #
# # ## ## # ## # # # ##
# ## ### # # # # # ##### # ## #
# ## # ## # ## # #### # # # # #
## # # # # # # # # # # ##
# # ## ## # ## #### ### # ## # # #
# # # ## # # # # # # # # #
## ## # # # ## #### ##### # # #
# # # # # # ### # # # # #
# # # ### # ### # # # # # # ##
# # # # # # # # # # #
## # # # # #### # # ## # ## # #
# # # # # # # # # ## # # # # # # #
# # ### # # # # # # # # ## # ## #
## # ## # # ## # ## ## ##
# # # # # ## ## # # F#
########################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment