Maze generation: Difference between revisions

m
→‎{{header|Elm}}: Updated to work with Elm 0.17.1
mNo edit summary
m (→‎{{header|Elm}}: Updated to work with Elm 0.17.1)
Line 1,878:
import Random exposing (Seed)
import Matrix.Random
import Time exposing (Time, every, second)
import Set exposing (Set, fromList)
import List exposing (..)
import String exposing (join)
import Html exposing (Html, br, input, h1, h2, text, div, button, fromElement)
import Html.Events as HE
import Html.Attributes as HA
import Html.App exposing (program)
import Json.Decode as JD
import Svg
import Svg.Attributes exposing (version, viewBox, cx, cy, r, x, y, x1, y1, x2, y2, fill,points, style, width, height, preserveAspectRatio)
Line 1,922 ⟶ 1,924:
in downs ++ rights |> fromList
 
initinitModel : Int -> Int -> Bool -> State -> Int -> Model
initinitModel rows cols animate state starter =
let rowGenerator = Random.int 0 (rows-1)
colGenerator = Random.int 0 (cols-1)
locationGenerator = Random.pair rowGenerator colGenerator
(c, s)= Random.generatestep locationGenerator (Random.initialSeed starter)
in { rows = rows
, cols = cols
Line 1,939 ⟶ 1,941:
}
 
view address model =
let
greenLineStyleborderLineStyle = style "stroke:green;stroke-width:0.3"
redLineStylewallLineStyle = style "stroke:redgreen;stroke-width:0.1"
 
x1Min = x1 <| toString 0
Line 1,953 ⟶ 1,955:
y2Max = y2 <| toString model.rows
 
borders = [ Svg.line [ x1Min, y1Min, x2Max, y2Min, greenLineStyleborderLineStyle ] []
, Svg.line [ x1Max, y1Min, x2Max, y2Max, greenLineStyleborderLineStyle ] []
, Svg.line [ x1Max, y1Max, x2Min, y2Max, greenLineStyleborderLineStyle ] []
, Svg.line [ x1Min, y1Max, x2Min, y2Min, greenLineStyleborderLineStyle ] []
]
 
Line 1,966 ⟶ 1,968:
, x2 <| toString (column + 1)
, y2 <| toString (row + 1)
, redLineStylewallLineStyle ] []
 
doors = (List.map doorToLine <| Set.toList model.doors )
Line 2,000 ⟶ 2,002:
, div
[floatLeft]
( slider "rows" minSide maxSide model.rows address SetRows
++ [ br [] [] ]
 
++ slider "cols" minSide maxSide model.cols address SetCols
++ [ br [] [] ]
 
++ checkbox "Animate" model.animate address SetAnimate
++ [ br [] [] ]
 
++ [ button
[ HE.onClick address Generate ]
[ text "Generate"]
] )
Line 2,029 ⟶ 2,031:
]
 
checkbox label checked address actionmsg =
[ input
[ HA.type' "checkbox"
, HA.checked checked
, HE.on "change" HE.targetChecked (SignalJD.messagemap addressmsg << actionHE.targetChecked)
]
[]
Line 2,039 ⟶ 2,041:
]
 
slider name min max current address actionmsg =
[ input
[ HA.value (if current >= min then current |> toString else "")
, HE.on "input" HE.targetValue (SignalJD.messagemap addressmsg <<HE.targetValue action)
, HA.type' "range"
, HA.min <| toString min
Line 2,060 ⟶ 2,062:
|> List.filter (\l -> (Matrix.get l model.boxes) |> M.withDefault False |> not)
 
updateupdateModel' : Model -> Int -> Model
updateupdateModel' model t =
case head model.current of
Nothing -> {model | state = Generated, seedStarter = t }
Line 2,067 ⟶ 2,069:
let neighbors = unvisitedNeighbors model prev
in if (length neighbors) > 0 then
let (neighborIndex, seed) = Random.generatestep (Random.int 0 (length neighbors-1)) model.seed
next = head (drop neighborIndex neighbors) |> M.withDefault (0,0)
boxes = Matrix.set next True model.boxes
Line 2,077 ⟶ 2,079:
else
let tailCurrent = tail model.current |> M.withDefault []
in updateupdateModel' {model | current = tailCurrent} t
 
updateupdateModel : ActionMsg -> Model -> Model
updateupdateModel actionmsg model =
let stringToCellCount s =
let v' = String.toInt s |> R.withDefault minSide
in if v' < minSide then minSide else v'
in case actionmsg of
Tick ttf ->
iflet (model.statet == Generating)truncate then update' model ttf
else { model | seedStarter = t }in
if (model.state == Generating) then updateModel' model t
else { model | seedStarter = t }
 
Generate ->
initinitModel model.rows model.cols model.animate Generating model.seedStarter
 
SetRows countString ->
initinitModel (stringToCellCount countString) model.cols model.animate Initial model.seedStarter
 
SetCols countString ->
initinitModel model.rows (stringToCellCount countString) model.animate Initial model.seedStarter
 
SetAnimate b ->
Line 2,103 ⟶ 2,107:
NoOp -> model
 
type ActionMsg = NoOp | Tick IntTime | Generate | SetRows String | SetCols String | SetAnimate Bool
control = Signal.mailbox NoOp
 
subscriptions model = every (dt * second) Tick
type Action = NoOp | Tick Int | Generate | SetRows String | SetCols String | SetAnimate Bool
 
main =
tickSignal = (every (dt * second)) |> Signal.map (\t -> Tick (round t))
let
update msg model = (updateModel msg model, Cmd.none)
init = (initModel 21 36 False Initial 0, Cmd.none)
in program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}</lang>
 
Link to live demo: http://dc25.github.io/mazeGenerationElm/
actionSignal = Signal.mergeMany [tickSignal, control.signal]
 
modelSignal = Signal.foldp update (init 21 36 False Initial 0) actionSignal
 
main = Signal.map (view control.address) modelSignal</lang>
 
Link to live demo: http://dc25.github.io/mazeGenerationElm/
=={{header|Erlang}}==
Erlang is single assignment. To get mutability I use processes. The code is over-enginered for this task, but the extra is used for [[Maze_solving]]. Also, Erlang starts counting at 1, not 0, so the co-ordinate of the lower left corner is 1,1.