-
Notifications
You must be signed in to change notification settings - Fork 0
/
Main.elm
130 lines (101 loc) · 3.02 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
port module Main exposing (main)
import CodinGame
import Json.Decode as Decode exposing (Decoder, Value)
{-| Port bringing the updated game data every turn.
-}
port stdin : (Value -> msg) -> Sub msg
{-| Port to give the new commands for this turn.
-}
port stdout : String -> Cmd msg
{-| Port to help debugging, will print using console.error().
-}
port stderr : String -> Cmd msg
main : Program Value GameState Value
main =
CodinGame.worker
{ stdin = stdin identity
, stdout = stdout
, stderr = stderr
}
{ init = init
, turn = turn
}
type alias GameState =
{ turnCount : Int
, nodeCount : Int
, linkCount : Int
, exitCount : Int
, links : List ( Int, Int )
, exits : List Int
}
defaultGameState : GameState
defaultGameState =
{ turnCount = 0
, nodeCount = 0
, linkCount = 0
, exitCount = 0
, links = []
, exits = []
}
type alias InitData =
{ nodeCount : Int
, linkCount : Int
, exitCount : Int
, links : List ( Int, Int )
, exits : List Int
}
type alias TurnData =
{ skynetNode : Int
}
initDataDecoder : Decoder InitData
initDataDecoder =
Decode.map5 InitData
(Decode.field "nodeCount" Decode.int)
(Decode.field "linkCount" Decode.int)
(Decode.field "exitCount" Decode.int)
(Decode.field "links" (Decode.list (pairDecoder Decode.int Decode.int)))
(Decode.field "exits" (Decode.list Decode.int))
pairDecoder : Decoder a -> Decoder b -> Decoder ( a, b )
pairDecoder decA decB =
Decode.map2 Tuple.pair
(Decode.index 0 decA)
(Decode.index 1 decB)
turnDataDecoder : Decoder TurnData
turnDataDecoder =
Decode.map TurnData
(Decode.field "skynetNode" Decode.int)
{-| Function called at the game initialization.
The string contains initial game data.
-}
init : Value -> ( GameState, Maybe String )
init value =
case Decode.decodeValue initDataDecoder value of
Err err ->
-- Should not happen once we've written the decoder correctly
( defaultGameState, Just (Decode.errorToString err) )
Ok initData ->
( { turnCount = 0
, nodeCount = initData.nodeCount
, linkCount = initData.linkCount
, exitCount = initData.exitCount
, links = initData.links
, exits = initData.exits
}
, Just "Initialization done!"
)
{-| Function called during the game loop with the data of the current turn.
-}
turn : Value -> GameState -> ( GameState, String, Maybe String )
turn value state =
case Decode.decodeValue turnDataDecoder value of
Err err ->
-- Should not happen once we've written the decoder correctly
( { state | turnCount = state.turnCount + 1 }
, ""
, Just (Decode.errorToString err)
)
Ok turnData ->
( { state | turnCount = state.turnCount + 1 }
, "1 2"
, Nothing
)