Main.elm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. module Cellular exposing (..)
  2. import Html exposing (..)
  3. import Html.Events exposing (..)
  4. import Html.Attributes exposing (id, class, classList, style)
  5. import Array
  6. import Time exposing (Time, second)
  7. type Cell
  8. = Alive
  9. | Dead
  10. type alias Board = Array.Array (Array.Array Cell)
  11. type alias Model =
  12. { width : Int
  13. , height : Int
  14. , board : Board
  15. }
  16. initModel : Int -> Int -> Model
  17. initModel w h =
  18. { width = w
  19. , height = h
  20. --, board = Array.repeat h <| Array.repeat w Dead
  21. , board = modify 3 2 Alive <| Array.repeat h <| Array.repeat w Dead
  22. }
  23. type Msg
  24. = NoOp
  25. | Step
  26. viewRow row =
  27. tr
  28. []
  29. <|
  30. Array.toList
  31. <|
  32. Array.map (\c ->
  33. let
  34. colour =
  35. case c of
  36. Alive ->
  37. "yellow"
  38. Dead ->
  39. "grey"
  40. in
  41. td
  42. [ style
  43. [ ("background-color", colour)
  44. ]
  45. ]
  46. [text (toString c)]
  47. ) row
  48. viewBoard : Board -> Html Msg
  49. viewBoard board =
  50. table
  51. []
  52. <|
  53. Array.toList
  54. <|
  55. Array.map (\r -> viewRow r) board
  56. view : Model -> Html Msg
  57. view model =
  58. div
  59. [ onClick Step
  60. ]
  61. [ text "cellular-elm"
  62. , viewBoard model.board
  63. ]
  64. modify : Int -> Int -> Cell -> Board -> Board
  65. modify x y newState board =
  66. case Array.get y board of
  67. Just oldRow ->
  68. let
  69. newRow = Array.set x newState oldRow
  70. newBoard = Array.set y newRow board
  71. in
  72. newBoard
  73. Nothing ->
  74. board
  75. surroundings : Array.Array Cell -> Array.Array Cell -> Int -> Array.Array Cell -> Int
  76. surroundings prevRow nextRow ind row =
  77. let
  78. ul =
  79. case Array.get (ind - 1) prevRow of
  80. Just Alive -> 1
  81. _ -> 0
  82. uc =
  83. case Array.get ind prevRow of
  84. Just Alive -> 1
  85. _ -> 0
  86. ur =
  87. case Array.get (ind + 1) prevRow of
  88. Just Alive -> 1
  89. _ -> 0
  90. ml =
  91. case Array.get (ind - 1) row of
  92. Just Alive -> 1
  93. _ -> 0
  94. mr =
  95. case Array.get (ind + 1) row of
  96. Just Alive -> 1
  97. _ -> 0
  98. ll =
  99. case Array.get (ind - 1) nextRow of
  100. Just Alive -> 1
  101. _ -> 0
  102. lc =
  103. case Array.get ind nextRow of
  104. Just Alive -> 1
  105. _ -> 0
  106. lr =
  107. case Array.get (ind + 1) nextRow of
  108. Just Alive -> 1
  109. _ -> 0
  110. in
  111. ul + uc + ur + ml + mr + ll + lc + lr
  112. replaceRow : Board -> Int -> Array.Array Cell -> Array.Array Cell
  113. replaceRow board rn row =
  114. let
  115. prevRow =
  116. Maybe.withDefault Array.empty <| Array.get (rn - 1) board
  117. nextRow =
  118. Maybe.withDefault Array.empty <| Array.get (rn + 1) board
  119. in
  120. Array.indexedMap
  121. (\cn cell ->
  122. --TODO: insert rules
  123. case cell of
  124. Dead ->
  125. if surroundings prevRow nextRow cn row > 0 then
  126. Alive
  127. else
  128. Dead
  129. Alive ->
  130. Dead
  131. ) row
  132. step : Board -> Board
  133. step board =
  134. Array.indexedMap (replaceRow board) board
  135. update : Msg -> Model -> (Model, Cmd Msg)
  136. update msg model =
  137. case msg of
  138. Step ->
  139. ( { model | board = step model.board }, Cmd.none )
  140. _ ->
  141. ( model, Cmd.none )
  142. subscriptions : Model -> Sub Msg
  143. subscriptions model =
  144. Sub.batch
  145. [ Time.every second (\_ -> Step)
  146. ]
  147. main =
  148. Html.program
  149. { init = ((initModel 20 10), Cmd.none)
  150. , view = view
  151. , update = update
  152. , subscriptions = subscriptions
  153. }