|  | @@ -0,0 +1,176 @@
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +module Cellular exposing (..)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import Html exposing (..)
 | 
	
		
			
				|  |  | +import Html.Events exposing (..)
 | 
	
		
			
				|  |  | +import Html.Attributes exposing (id, class, classList, style)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import Array
 | 
	
		
			
				|  |  | +import Time exposing (Time, second)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type Cell
 | 
	
		
			
				|  |  | +    = Alive
 | 
	
		
			
				|  |  | +    | Dead
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type alias Board = Array.Array (Array.Array Cell)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type alias Model =
 | 
	
		
			
				|  |  | +    { width : Int
 | 
	
		
			
				|  |  | +    , height : Int
 | 
	
		
			
				|  |  | +    , board : Board
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +initModel : Int -> Int -> Model
 | 
	
		
			
				|  |  | +initModel w h =
 | 
	
		
			
				|  |  | +    { width = w
 | 
	
		
			
				|  |  | +    , height = h
 | 
	
		
			
				|  |  | +    --, board = Array.repeat h <| Array.repeat w Dead
 | 
	
		
			
				|  |  | +    , board = modify 3 2 Alive <| Array.repeat h <| Array.repeat w Dead
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type Msg
 | 
	
		
			
				|  |  | +    = NoOp
 | 
	
		
			
				|  |  | +    | Step
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +viewRow row =
 | 
	
		
			
				|  |  | +    tr
 | 
	
		
			
				|  |  | +        []
 | 
	
		
			
				|  |  | +        <|
 | 
	
		
			
				|  |  | +        Array.toList
 | 
	
		
			
				|  |  | +        <|
 | 
	
		
			
				|  |  | +        Array.map (\c ->
 | 
	
		
			
				|  |  | +            let
 | 
	
		
			
				|  |  | +                colour =
 | 
	
		
			
				|  |  | +                    case c of
 | 
	
		
			
				|  |  | +                        Alive ->
 | 
	
		
			
				|  |  | +                            "yellow"
 | 
	
		
			
				|  |  | +                        Dead ->
 | 
	
		
			
				|  |  | +                            "grey"
 | 
	
		
			
				|  |  | +            in
 | 
	
		
			
				|  |  | +                td
 | 
	
		
			
				|  |  | +                [ style
 | 
	
		
			
				|  |  | +                    [ ("background-color", colour)
 | 
	
		
			
				|  |  | +                    ]
 | 
	
		
			
				|  |  | +                ]
 | 
	
		
			
				|  |  | +                [text (toString c)]
 | 
	
		
			
				|  |  | +        ) row
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +viewBoard : Board -> Html Msg
 | 
	
		
			
				|  |  | +viewBoard board =
 | 
	
		
			
				|  |  | +    table
 | 
	
		
			
				|  |  | +        []
 | 
	
		
			
				|  |  | +        <|
 | 
	
		
			
				|  |  | +        Array.toList
 | 
	
		
			
				|  |  | +        <|
 | 
	
		
			
				|  |  | +        Array.map (\r -> viewRow r) board
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +view : Model -> Html Msg
 | 
	
		
			
				|  |  | +view model =
 | 
	
		
			
				|  |  | +    div
 | 
	
		
			
				|  |  | +        [ onClick Step
 | 
	
		
			
				|  |  | +        ]
 | 
	
		
			
				|  |  | +        [ text "cellular-elm"
 | 
	
		
			
				|  |  | +        , viewBoard model.board
 | 
	
		
			
				|  |  | +        ]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +modify : Int -> Int -> Cell -> Board -> Board
 | 
	
		
			
				|  |  | +modify x y newState board =
 | 
	
		
			
				|  |  | +    case Array.get y board of
 | 
	
		
			
				|  |  | +        Just oldRow ->
 | 
	
		
			
				|  |  | +            let
 | 
	
		
			
				|  |  | +                newRow = Array.set x newState oldRow
 | 
	
		
			
				|  |  | +                newBoard = Array.set y newRow board
 | 
	
		
			
				|  |  | +            in
 | 
	
		
			
				|  |  | +                newBoard
 | 
	
		
			
				|  |  | +        Nothing ->
 | 
	
		
			
				|  |  | +            board
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +surroundings : Array.Array Cell -> Array.Array Cell -> Int -> Array.Array Cell -> Int
 | 
	
		
			
				|  |  | +surroundings prevRow nextRow ind row =
 | 
	
		
			
				|  |  | +    let
 | 
	
		
			
				|  |  | +        ul =
 | 
	
		
			
				|  |  | +            case Array.get (ind - 1) prevRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        uc =
 | 
	
		
			
				|  |  | +            case Array.get ind prevRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        ur =
 | 
	
		
			
				|  |  | +            case Array.get (ind + 1) prevRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        ml =
 | 
	
		
			
				|  |  | +            case Array.get (ind - 1) row of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        mr =
 | 
	
		
			
				|  |  | +            case Array.get (ind + 1) row of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        ll =
 | 
	
		
			
				|  |  | +            case Array.get (ind - 1) nextRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        lc =
 | 
	
		
			
				|  |  | +            case Array.get ind nextRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +        lr =
 | 
	
		
			
				|  |  | +            case Array.get (ind + 1) nextRow of
 | 
	
		
			
				|  |  | +                Just Alive -> 1
 | 
	
		
			
				|  |  | +                _ -> 0
 | 
	
		
			
				|  |  | +    in
 | 
	
		
			
				|  |  | +        ul + uc + ur + ml + mr + ll + lc + lr
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +replaceRow : Board -> Int -> Array.Array Cell -> Array.Array Cell
 | 
	
		
			
				|  |  | +replaceRow board rn row =
 | 
	
		
			
				|  |  | +    let
 | 
	
		
			
				|  |  | +        prevRow =
 | 
	
		
			
				|  |  | +            Maybe.withDefault Array.empty <| Array.get (rn - 1) board
 | 
	
		
			
				|  |  | +        nextRow =
 | 
	
		
			
				|  |  | +            Maybe.withDefault Array.empty <| Array.get (rn + 1) board
 | 
	
		
			
				|  |  | +    in
 | 
	
		
			
				|  |  | +        Array.indexedMap
 | 
	
		
			
				|  |  | +        (\cn cell ->
 | 
	
		
			
				|  |  | +            --TODO: insert rules
 | 
	
		
			
				|  |  | +            case cell of
 | 
	
		
			
				|  |  | +                Dead ->
 | 
	
		
			
				|  |  | +                    if surroundings prevRow nextRow cn row > 0 then
 | 
	
		
			
				|  |  | +                        Alive
 | 
	
		
			
				|  |  | +                    else
 | 
	
		
			
				|  |  | +                        Dead
 | 
	
		
			
				|  |  | +                Alive ->
 | 
	
		
			
				|  |  | +                    Dead
 | 
	
		
			
				|  |  | +        ) row
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +step : Board -> Board
 | 
	
		
			
				|  |  | +step board =
 | 
	
		
			
				|  |  | +    Array.indexedMap (replaceRow board) board
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +update : Msg -> Model -> (Model, Cmd Msg)
 | 
	
		
			
				|  |  | +update msg model =
 | 
	
		
			
				|  |  | +    case msg of
 | 
	
		
			
				|  |  | +        Step ->
 | 
	
		
			
				|  |  | +            ( { model | board = step model.board }, Cmd.none )
 | 
	
		
			
				|  |  | +        _ ->
 | 
	
		
			
				|  |  | +            ( model, Cmd.none )
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +subscriptions : Model -> Sub Msg
 | 
	
		
			
				|  |  | +subscriptions model =
 | 
	
		
			
				|  |  | +    Sub.batch
 | 
	
		
			
				|  |  | +        [ Time.every second (\_ -> Step)
 | 
	
		
			
				|  |  | +        ]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +main =
 | 
	
		
			
				|  |  | +    Html.program
 | 
	
		
			
				|  |  | +        { init = ((initModel 20 10), Cmd.none)
 | 
	
		
			
				|  |  | +        , view = view
 | 
	
		
			
				|  |  | +        , update = update
 | 
	
		
			
				|  |  | +        , subscriptions = subscriptions
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 |