Skip to content

Commit 4699a91

Browse files
committed
Episode 8: Rotating pieces & spawning random pieces
1 parent 6edbd2d commit 4699a91

File tree

2 files changed

+118
-54
lines changed

2 files changed

+118
-54
lines changed

elm.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"elm/html": "1.0.0",
1212
"elm/http": "2.0.0",
1313
"elm/json": "1.1.3",
14+
"elm/random": "1.0.0",
1415
"elm/svg": "1.0.1",
1516
"elm/time": "1.0.0"
1617
},
@@ -25,8 +26,6 @@
2526
"direct": {
2627
"elm-explorations/test": "1.2.2"
2728
},
28-
"indirect": {
29-
"elm/random": "1.0.0"
30-
}
29+
"indirect": {}
3130
}
3231
}

src/Main.elm

Lines changed: 116 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import Browser.Events exposing (onKeyDown)
55
import Html exposing (Html, button, div, text)
66
import Html.Events exposing (onClick)
77
import Json.Decode as Decode
8-
import List exposing (map, range)
8+
import List exposing (drop, head, length, map, range)
9+
import Random
910
import String exposing (fromInt)
1011
import Svg
1112
import Svg.Attributes as SA
@@ -31,7 +32,7 @@ main =
3132

3233
type alias Model =
3334
{ board : Board
34-
, currentPiece : CurrentPiece
35+
, currentPiece : Maybe CurrentPiece
3536
}
3637

3738

@@ -95,6 +96,12 @@ jPiece =
9596
}
9697

9798

99+
pieceDefinitions =
100+
[ tPiece
101+
, jPiece
102+
]
103+
104+
98105
updateRow : FieldColor -> Position -> Int -> Row -> Row
99106
updateRow newColor ( x, y ) rowIndex ((Row fields) as oldRow) =
100107
let
@@ -148,17 +155,11 @@ init _ =
148155
let
149156
emptyBoard =
150157
mkEmptyBoard boardHeight boardWidth
151-
152-
currentPiece =
153-
{ position = ( 5, boardHeight - 2 )
154-
, tiles = tPiece.tiles
155-
, color = tPiece.color
156-
}
157158
in
158159
( { board = emptyBoard
159-
, currentPiece = currentPiece
160+
, currentPiece = Nothing
160161
}
161-
, Cmd.none
162+
, Random.generate NewCurrentPiece (Random.int 0 <| (length pieceDefinitions - 1))
162163
)
163164

164165

@@ -170,50 +171,101 @@ type Msg
170171
= GravityTick Time.Posix
171172
| KeyDown Key
172173
| Noop
174+
| NewCurrentPiece Int
173175

174176

175177
type Key
176178
= LeftArrow
177179
| RightArrow
180+
| DownArrow
178181

179182

180183
update : Msg -> Model -> ( Model, Cmd Msg )
181184
update msg model =
182185
case msg of
183186
GravityTick _ ->
184-
( dropCurrentPiece model
185-
, Cmd.none
186-
)
187+
dropCurrentPiece model
187188

188189
KeyDown key ->
189190
( movePiece key model
190191
, Cmd.none
191192
)
192193

194+
NewCurrentPiece pieceIndex ->
195+
( spawnPiece pieceIndex model
196+
, Cmd.none
197+
)
198+
193199
Noop ->
194200
( model
195201
, Cmd.none
196202
)
197203

198204

199-
movePiece : Key -> Model -> Model
200-
movePiece key ({ currentPiece } as model) =
205+
spawnPiece : Int -> Model -> Model
206+
spawnPiece pieceIndex model =
201207
let
202-
( x, y ) =
203-
currentPiece.position
208+
pieceDef =
209+
Maybe.withDefault tPiece <| head <| drop pieceIndex pieceDefinitions
204210

205-
newPosition =
206-
case key of
207-
LeftArrow ->
208-
( x - 1, y )
211+
newPiece =
212+
{ position = ( 5, boardHeight - 2 )
213+
, tiles = pieceDef.tiles
214+
, color = pieceDef.color
215+
}
216+
in
217+
{ model
218+
| currentPiece = Just newPiece
219+
}
209220

210-
RightArrow ->
211-
( x + 1, y )
212221

213-
movedPiece =
214-
{ currentPiece | position = newPosition }
215-
in
216-
{ model | currentPiece = movedPiece }
222+
movePiece : Key -> Model -> Model
223+
movePiece key model =
224+
case model.currentPiece of
225+
Nothing ->
226+
model
227+
228+
Just currentPiece ->
229+
let
230+
( x, y ) =
231+
currentPiece.position
232+
233+
tiles =
234+
currentPiece.tiles
235+
236+
newPosition =
237+
case key of
238+
LeftArrow ->
239+
( x - 1, y )
240+
241+
RightArrow ->
242+
( x + 1, y )
243+
244+
DownArrow ->
245+
( x, y )
246+
247+
newTiles =
248+
case key of
249+
LeftArrow ->
250+
tiles
251+
252+
RightArrow ->
253+
tiles
254+
255+
DownArrow ->
256+
let
257+
rotate ( tx, ty ) =
258+
( -ty, tx )
259+
in
260+
map rotate tiles
261+
262+
movedPiece =
263+
{ currentPiece
264+
| position = newPosition
265+
, tiles = newTiles
266+
}
267+
in
268+
{ model | currentPiece = Just movedPiece }
217269

218270

219271
canDrop : CurrentPiece -> Board -> Bool
@@ -253,30 +305,35 @@ canDrop { position, tiles } board =
253305
List.all canPlace translatedTiles
254306

255307

256-
dropCurrentPiece : Model -> Model
257-
dropCurrentPiece ({ currentPiece, board } as model) =
258-
let
259-
( x, y ) =
260-
currentPiece.position
308+
dropCurrentPiece : Model -> ( Model, Cmd Msg )
309+
dropCurrentPiece ({ board } as model) =
310+
case model.currentPiece of
311+
Nothing ->
312+
( model, Cmd.none )
261313

262-
nextRow =
263-
y - 1
314+
Just currentPiece ->
315+
let
316+
( x, y ) =
317+
currentPiece.position
264318

265-
droppedPiece =
266-
{ currentPiece | position = ( x, nextRow ) }
267-
in
268-
if canDrop currentPiece board then
269-
{ model | currentPiece = droppedPiece }
319+
nextRow =
320+
y - 1
270321

271-
else
272-
{ model
273-
| board = placePieceOnBoard currentPiece board
274-
, currentPiece =
275-
{ position = ( 5, boardHeight - 2 )
276-
, tiles = jPiece.tiles
277-
, color = jPiece.color
278-
}
279-
}
322+
droppedPiece =
323+
{ currentPiece | position = ( x, nextRow ) }
324+
in
325+
if canDrop currentPiece board then
326+
( { model | currentPiece = Just droppedPiece }
327+
, Cmd.none
328+
)
329+
330+
else
331+
( { model
332+
| board = placePieceOnBoard currentPiece board
333+
, currentPiece = Nothing
334+
}
335+
, Random.generate NewCurrentPiece (Random.int 0 <| (length pieceDefinitions - 1))
336+
)
280337

281338

282339

@@ -305,6 +362,9 @@ toKey string =
305362
"ArrowRight" ->
306363
KeyDown RightArrow
307364

365+
"ArrowDown" ->
366+
KeyDown DownArrow
367+
308368
_ ->
309369
Noop
310370

@@ -375,11 +435,16 @@ placePieceOnBoard currentPiece oldBoard =
375435
{ oldBoard | rows = newRows }
376436

377437

378-
boardView : Board -> CurrentPiece -> Html Msg
379-
boardView board currentPiece =
438+
boardView : Board -> Maybe CurrentPiece -> Html Msg
439+
boardView board mbCurrentPiece =
380440
let
381441
boardWithCurrentPiece =
382-
placePieceOnBoard currentPiece board
442+
case mbCurrentPiece of
443+
Nothing ->
444+
board
445+
446+
Just currentPiece ->
447+
placePieceOnBoard currentPiece board
383448

384449
rowViews =
385450
List.concat (List.indexedMap rowView boardWithCurrentPiece.rows)

0 commit comments

Comments
 (0)