-
Notifications
You must be signed in to change notification settings - Fork 0
/
View.elm
461 lines (366 loc) · 18.6 KB
/
View.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
module View exposing (view)
import Model exposing (Model, Size(..), Stack(..), Board(..), BoardId(..), EdgeId(..), Stash, Outcome(..))
import Html exposing (Html, text)
import Html.Attributes
import Msg exposing (Msg(..))
import Material.Button as Button
import Material.Grid as Grid exposing (Device(..))
import Svg exposing (Svg, svg, polygon, Attribute, g)
import Svg.Attributes exposing (..)
import Svg.Events exposing (onClick)
import PyramidView exposing (renderStash, renderStack, getScale)
view : Model -> Html Msg
view model =
Html.div []
[ Html.div [ Html.Attributes.style [ ( "display", "flex" ), ( "justify-content", "center" ) ] ]
[ Button.render Mdl
[ 0 ]
model.mdl
[ Button.raised
, Button.ripple
, Button.onClick NewGame
]
[ text "New Game" ]
]
, Grid.grid []
[ Grid.cell [ Grid.size All 5 ]
[ renderStash model.selected model.stash
]
, Grid.cell [ Grid.size All 6 ]
[ Html.div [ Html.Attributes.style [ ( "width", boardWidthString ++ "px" ), ( "display", "flex" ), ( "justify-content", "center" ), ( "font-size", (boardWidth / 16 |> toString) ++ "px" ) ] ]
[ model.outcome
|> outcomeToString
|> Html.text
]
, svg
[ width boardWidthString
, height boardHeightString
, viewBox ("0 0 " ++ boardWidthString ++ " " ++ boardHeightString)
]
[ renderBoard model.selected model.board
]
]
]
]
outcomeToString : Outcome -> String
outcomeToString outcome =
case outcome of
TBD ->
""
UserWin ->
"You win!"
UserWinByExhaustion ->
"The CPU has no legal moves, so you win!"
CPUWin ->
"You lost!"
CPUWinByExhaustion ->
"You have no legal moves, so you lost!"
Tie ->
"No pieces are left so it's a tie"
boardWidth =
720
boardWidthString =
toString boardWidth
boardHeight =
720
boardHeightString =
toString boardHeight
centerX =
boardWidth / 2
centerY =
boardHeight / 2
renderBoard : Maybe Size -> Board -> Svg Msg
renderBoard selected board =
let
determinedSpace =
case board of
EmptyBoard ->
spaceAndStack ZeroZero selected EmptyStack (fromBoardOffset 0 spaceOffset)
OneByOne stack ->
spaceAndStack ZeroZero selected stack (fromBoardOffset 0 spaceOffset)
OneByTwo stack0 stack1 ->
spaceAndStack ZeroZero selected stack0 (fromBoardOffset halfSpaceOffset halfSpaceOffset)
++ spaceAndStack ZeroOne selected stack1 (fromBoardOffset -halfSpaceOffset threeHalfsSpaceOffset)
TwoByOne stack0 stack1 ->
spaceAndStack ZeroZero selected stack0 (fromBoardOffset -halfSpaceOffset halfSpaceOffset)
++ spaceAndStack OneZero selected stack1 (fromBoardOffset halfSpaceOffset threeHalfsSpaceOffset)
OneByThree stack0 stack1 stack2 ->
spaceAndStack ZeroZero selected stack0 (fromBoardOffset halfSpaceOffset 0)
++ spaceAndStack OneZero selected stack1 (fromBoardOffset -halfSpaceOffset spaceOffset)
++ spaceAndStack TwoZero selected stack2 (fromBoardOffset -threeHalfsSpaceOffset doubleSpaceOffset)
ThreeByOne stack0 stack1 stack2 ->
spaceAndStack ZeroZero selected stack0 (fromBoardOffset -halfSpaceOffset halfSpaceOffset)
++ spaceAndStack ZeroOne selected stack1 (fromBoardOffset halfSpaceOffset threeHalfsSpaceOffset)
++ spaceAndStack ZeroTwo selected stack2 (fromBoardOffset threeHalfsSpaceOffset fiveHalfsSpaceOffset)
TwoByTwo spaces ->
spaceAndStack ZeroZero selected spaces.zeroZero atBoardOffset
++ spaceAndStack OneZero selected spaces.oneZero (fromBoardOffset spaceOffset spaceOffset)
++ spaceAndStack ZeroOne selected spaces.zeroOne (fromBoardOffset -spaceOffset spaceOffset)
++ spaceAndStack OneOne selected spaces.oneOne (fromBoardOffset 0 doubleSpaceOffset)
TwoByThree spaces ->
spaceAndStack ZeroZero selected spaces.zeroZero (fromBoardOffset 0 -halfSpaceOffset)
++ spaceAndStack OneZero selected spaces.oneZero (fromBoardOffset spaceOffset halfSpaceOffset)
++ spaceAndStack ZeroOne selected spaces.zeroOne (fromBoardOffset -spaceOffset halfSpaceOffset)
++ spaceAndStack OneOne selected spaces.oneOne (fromBoardOffset 0 threeHalfsSpaceOffset)
++ spaceAndStack ZeroTwo selected spaces.zeroTwo (fromBoardOffset -doubleSpaceOffset threeHalfsSpaceOffset)
++ spaceAndStack OneTwo selected spaces.oneTwo (fromBoardOffset -spaceOffset fiveHalfsSpaceOffset)
ThreeByTwo spaces ->
spaceAndStack ZeroZero selected spaces.zeroZero (fromBoardOffset -halfSpaceOffset -halfSpaceOffset)
++ spaceAndStack OneZero selected spaces.oneZero (fromBoardOffset halfSpaceOffset halfSpaceOffset)
++ spaceAndStack TwoZero selected spaces.twoZero (fromBoardOffset threeHalfsSpaceOffset threeHalfsSpaceOffset)
++ spaceAndStack ZeroOne selected spaces.zeroOne (fromBoardOffset -threeHalfsSpaceOffset halfSpaceOffset)
++ spaceAndStack OneOne selected spaces.oneOne (fromBoardOffset -halfSpaceOffset threeHalfsSpaceOffset)
++ spaceAndStack TwoOne selected spaces.twoOne (fromBoardOffset halfSpaceOffset fiveHalfsSpaceOffset)
ThreeByThree spaces ->
spaceAndStack ZeroZero selected spaces.zeroZero (fromBoardOffset 0 -spaceOffset)
++ spaceAndStack OneZero selected spaces.oneZero (fromBoardOffset spaceOffset 0)
++ spaceAndStack TwoZero selected spaces.twoZero (fromBoardOffset doubleSpaceOffset spaceOffset)
++ spaceAndStack ZeroOne selected spaces.zeroOne (fromBoardOffset -spaceOffset 0)
++ spaceAndStack OneOne selected spaces.oneOne (fromBoardOffset 0 spaceOffset)
++ spaceAndStack TwoOne selected spaces.twoOne (fromBoardOffset spaceOffset doubleSpaceOffset)
++ spaceAndStack ZeroTwo selected spaces.zeroTwo (fromBoardOffset -doubleSpaceOffset spaceOffset)
++ spaceAndStack OneTwo selected spaces.oneTwo (fromBoardOffset -spaceOffset doubleSpaceOffset)
++ spaceAndStack TwoTwo selected spaces.twoTwo (fromBoardOffset 0 (3 * spaceOffset))
in
edgeSpaces selected board
++ determinedSpace
|> g []
edgeSpaces : Maybe Size -> Board -> List (Svg Msg)
edgeSpaces selected board =
case board of
EmptyBoard ->
[]
OneByOne _ ->
[ edgeSpace (fromBoardOffset 0 -spaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset spaceOffset 0) EdgeOneZero selected
, edgeSpace (fromBoardOffset doubleSpaceOffset spaceOffset) EdgeTwoZero selected
, edgeSpace (fromBoardOffset -spaceOffset 0) EdgeZeroOne selected
, edgeSpace (fromBoardOffset spaceOffset doubleSpaceOffset) EdgeTwoOne selected
, edgeSpace (fromBoardOffset -doubleSpaceOffset spaceOffset) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset -spaceOffset doubleSpaceOffset) EdgeOneTwo selected
, edgeSpace (fromBoardOffset 0 (3 * spaceOffset)) EdgeTwoTwo selected
]
OneByTwo _ _ ->
[ edgeSpace (fromBoardOffset halfSpaceOffset -threeHalfsSpaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset -halfSpaceOffset) EdgeOneZero selected
, edgeSpace (fromBoardOffset fiveHalfsSpaceOffset halfSpaceOffset) EdgeTwoZero selected
, edgeSpace (fromBoardOffset -halfSpaceOffset -halfSpaceOffset) EdgeZeroOne selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset threeHalfsSpaceOffset) EdgeTwoOne selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset halfSpaceOffset) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset halfSpaceOffset fiveHalfsSpaceOffset) EdgeTwoTwo selected
, edgeSpace (fromBoardOffset -fiveHalfsSpaceOffset threeHalfsSpaceOffset) EdgeZeroThree selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset fiveHalfsSpaceOffset) EdgeOneThree selected
, edgeSpace (fromBoardOffset -halfSpaceOffset (3.5 * spaceOffset)) EdgeTwoThree selected
]
TwoByOne _ _ ->
[ edgeSpace (fromBoardOffset -halfSpaceOffset -threeHalfsSpaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset halfSpaceOffset -halfSpaceOffset) EdgeOneZero selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset halfSpaceOffset) EdgeTwoZero selected
, edgeSpace (fromBoardOffset fiveHalfsSpaceOffset threeHalfsSpaceOffset) EdgeThreeZero selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset -halfSpaceOffset) EdgeZeroOne selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset fiveHalfsSpaceOffset) EdgeThreeOne selected
, edgeSpace (fromBoardOffset -fiveHalfsSpaceOffset halfSpaceOffset) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset threeHalfsSpaceOffset) EdgeOneTwo selected
, edgeSpace (fromBoardOffset -halfSpaceOffset fiveHalfsSpaceOffset) EdgeTwoTwo selected
, edgeSpace (fromBoardOffset halfSpaceOffset (3.5 * spaceOffset)) EdgeThreeTwo selected
]
OneByThree _ _ _ ->
[ edgeSpace (fromBoardOffset -halfSpaceOffset -spaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset spaceOffset) EdgeTwoZero selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset 0) EdgeZeroOne selected
, edgeSpace (fromBoardOffset halfSpaceOffset doubleSpaceOffset) EdgeTwoOne selected
, edgeSpace (fromBoardOffset -fiveHalfsSpaceOffset spaceOffset) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset -halfSpaceOffset (3 * spaceOffset)) EdgeTwoTwo selected
]
ThreeByOne _ _ _ ->
[ edgeSpace (fromBoardOffset halfSpaceOffset -halfSpaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset halfSpaceOffset) EdgeOneZero selected
, edgeSpace (fromBoardOffset fiveHalfsSpaceOffset threeHalfsSpaceOffset) EdgeTwoZero selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset threeHalfsSpaceOffset) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset -halfSpaceOffset fiveHalfsSpaceOffset) EdgeOneTwo selected
, edgeSpace (fromBoardOffset halfSpaceOffset (3.5 * spaceOffset)) EdgeTwoTwo selected
]
TwoByTwo r ->
[ if r.zeroZero == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset 0 -doubleSpaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset spaceOffset -spaceOffset) EdgeOneZero selected
, edgeSpace (fromBoardOffset doubleSpaceOffset 0) EdgeTwoZero selected
, if r.oneZero == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset (3 * spaceOffset) spaceOffset) EdgeThreeZero selected
, edgeSpace (fromBoardOffset -spaceOffset -spaceOffset) EdgeZeroOne selected
, edgeSpace (fromBoardOffset doubleSpaceOffset doubleSpaceOffset) EdgeThreeOne selected
, edgeSpace (fromBoardOffset -doubleSpaceOffset 0) EdgeZeroTwo selected
, edgeSpace (fromBoardOffset spaceOffset (3 * spaceOffset)) EdgeThreeTwo selected
, if r.zeroOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset -(3 * spaceOffset) spaceOffset) EdgeZeroThree selected
, edgeSpace (fromBoardOffset -doubleSpaceOffset doubleSpaceOffset) EdgeOneThree selected
, edgeSpace (fromBoardOffset -spaceOffset (3 * spaceOffset)) EdgeTwoThree selected
, if r.oneOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset 0 (4 * spaceOffset)) EdgeThreeThree selected
]
TwoByThree r ->
let
_ =
Debug.log "oneOne" r.oneOne
_ =
Debug.log "oneTwo" r.oneTwo
in
[ if r.zeroZero == EmptyStack && r.zeroOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset -spaceOffset -threeHalfsSpaceOffset) EdgeZeroZero selected
, if r.oneZero == EmptyStack && r.oneOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset doubleSpaceOffset threeHalfsSpaceOffset) EdgeThreeZero selected
, edgeSpace (fromBoardOffset -doubleSpaceOffset -halfSpaceOffset) EdgeZeroOne selected
, edgeSpace (fromBoardOffset spaceOffset fiveHalfsSpaceOffset) EdgeThreeOne selected
, if r.zeroOne == EmptyStack && r.zeroTwo == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset -(3 * spaceOffset) halfSpaceOffset) EdgeZeroTwo selected
, if r.oneOne == EmptyStack && r.oneTwo == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset 0 (3.5 * spaceOffset)) EdgeThreeTwo selected
]
ThreeByTwo r ->
let
_ =
Debug.log "oneOne" r.oneOne
_ =
Debug.log "twoOne" r.twoOne
in
[ if r.zeroZero == EmptyStack && r.oneZero == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset halfSpaceOffset -threeHalfsSpaceOffset) EdgeZeroZero selected
, edgeSpace (fromBoardOffset threeHalfsSpaceOffset -halfSpaceOffset) EdgeOneZero selected
, if r.oneZero == EmptyStack && r.twoZero == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset fiveHalfsSpaceOffset halfSpaceOffset) EdgeTwoZero selected
, if r.zeroOne == EmptyStack && r.oneOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset -fiveHalfsSpaceOffset threeHalfsSpaceOffset) EdgeZeroThree selected
, edgeSpace (fromBoardOffset -threeHalfsSpaceOffset fiveHalfsSpaceOffset) EdgeOneThree selected
, if r.oneOne == EmptyStack && r.twoOne == EmptyStack then
PyramidView.nullSvg
else
edgeSpace (fromBoardOffset -halfSpaceOffset (3.5 * spaceOffset)) EdgeTwoThree selected
]
_ ->
[]
boardOffsetX =
centerX
boardOffsetY =
centerY - halfSpaceOffset
atBoardOffset =
( boardOffsetX, boardOffsetY )
fromBoardOffset x y =
( boardOffsetX + x, boardOffsetY + y )
tupleAdd ( x, y ) ( xOffset, yOffset ) =
( x + xOffset, y + yOffset )
spaceAndStack : BoardId -> Maybe Size -> Stack -> ( Float, Float ) -> List (Svg Msg)
spaceAndStack boardId selected stack coords =
[ spaceMsg boardId selected stack
|> space coords
, renderStack stack coords
]
spaceMsg : BoardId -> Maybe Size -> Stack -> Maybe Msg
spaceMsg boardId selected stack =
case selected of
Just size ->
if Model.sizeFits size stack then
Just (Place boardId)
else
Nothing
Nothing ->
Nothing
space : ( Float, Float ) -> Maybe Msg -> Svg Msg
space ( x, y ) maybeMsg =
let
dString =
("M " ++ toString x ++ " " ++ toString y)
++ spaceSuffix
msgAttributes =
case maybeMsg of
Just msg ->
[ stroke "white", onClick msg ]
Nothing ->
[ stroke "black" ]
in
g []
[ Svg.path
(msgAttributes
++ [ d dString
, fill "#444444"
, strokeWidth "4"
]
)
[]
]
edgeSpace : ( Float, Float ) -> EdgeId -> Maybe Size -> Svg Msg
edgeSpace ( x, y ) edgeId selected =
let
dString =
("M " ++ toString x ++ " " ++ toString y)
++ spaceSuffix
msgAttributes =
case selected of
Just _ ->
[ stroke "white", onClick (PlaceOnEdge edgeId) ]
Nothing ->
[ stroke "black" ]
in
g []
[ Svg.path
(msgAttributes
++ [ d dString
, fill "#444444"
, fillOpacity "0.4"
, strokeWidth "4"
]
)
[]
]
square x =
x ^ 2
queenScale =
getScale Queen
queenScaleString =
toString queenScale
spaceSideLength =
sqrt (2.5 * square queenScale) * 7 / 5
spaceOffset =
sqrt (square spaceSideLength / 2)
halfSpaceOffset =
spaceOffset / 2
suffixSpaceOffset =
--make room for the ourlines
spaceOffset - 2.5
suffixSpaceOffsetString =
toString suffixSpaceOffset
threeHalfsSpaceOffset =
halfSpaceOffset * 3
fiveHalfsSpaceOffset =
halfSpaceOffset * 5
doubleSpaceOffset =
spaceOffset * 2
minusSuffixSpaceOffsetString =
toString -suffixSpaceOffset
spaceSuffix =
(" m 0 " ++ toString (queenScale / 2))
++ (" l " ++ suffixSpaceOffsetString ++ " " ++ minusSuffixSpaceOffsetString)
++ (" l " ++ minusSuffixSpaceOffsetString ++ " " ++ minusSuffixSpaceOffsetString)
++ (" l " ++ minusSuffixSpaceOffsetString ++ " " ++ suffixSpaceOffsetString)
++ "Z"