-
Notifications
You must be signed in to change notification settings - Fork 1
/
Main.elm
113 lines (84 loc) · 2.82 KB
/
Main.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import Core exposing (Model, moveRows,
replaseZeroNTimes, replaceRandomZero, Direction(..), countScore,
Update(..))
import Graphics.Element as GE exposing(Element, show, flow, left, down)
import Random
import Keyboard
import Signal as S
import Html exposing (Html, div)
import Debug
import UI exposing(mainView)
import List as List exposing(isEmpty, append, map, reverse, map4, filter,
length, sum, foldr, concat, take, all, maximum)
import Core exposing (GameState(..))
uiMailBox: Signal.Mailbox Update
uiMailBox = Signal.mailbox NoAction
getDirection: {x: Int, y: Int} -> Direction
getDirection {x, y} =
case (x, y) of
(-1, 0) -> L {-- left --}
(1, 0) -> R {-- right --}
(0, 1) -> U {-- up --}
(0, -1) -> D {-- down --}
_ -> N
updateBeforeStart : Bool -> Model -> GameState Model
updateBeforeStart isEnter model =
if isEnter then OnAir model else BeforeStart model
updateOnAir : {x: Int, y: Int} -> Model -> GameState Model
updateOnAir arrows model =
let
direction = getDirection arrows
modelWasChanged = model /= movedModel
isLoose = all (\d -> (moveRows d model) == model) [L, R, U, D]
movedModel = moveRows direction model
modelWithScore = countScore movedModel
in
if | modelWithScore.score == 2048 -> EndWin modelWithScore
| isLoose -> EndLoose model
| modelWasChanged -> OnAir (replaceRandomZero modelWithScore)
| otherwise -> OnAir model
updateOnLoose: Bool -> Model -> GameState Model
updateOnLoose isEnter model =
if isEnter then OnAir initState else EndLoose model
updateOnWin: Bool -> Model -> GameState Model
updateOnWin isEnter model =
if isEnter then OnAir initState else EndWin model
update: Update -> GameState Model -> GameState Model
update upd model =
case (model, upd) of
((BeforeStart state), IsEnterDown isEnter) ->
updateBeforeStart isEnter state
((BeforeStart state), Start) -> OnAir initState
((OnAir state), Arrows arrows) ->
updateOnAir arrows state
((EndLoose state), IsEnterDown isEnter) ->
updateOnLoose isEnter state
((EndWin state), IsEnterDown isEnter) ->
updateOnWin isEnter state
(OnAir state, Restart) -> OnAir initState
(EndLoose state, Restart) -> OnAir initState
(EndWin state, Restart) -> OnAir initState
_ -> model
stage = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
initState =
{cells = stage, seed = Random.initialSeed 100, score = 0}
|> (replaseZeroNTimes 4)
|> countScore
main : Signal Html
main = S.map
(mainView uiMailBox.address)
(S.foldp
update
(BeforeStart initState)
(S.mergeMany
[
(S.map Arrows Keyboard.arrows)
,(S.map IsEnterDown Keyboard.enter)
,uiMailBox.signal
]
))