@@ -5,7 +5,8 @@ import Browser.Events exposing (onKeyDown)
55import Html exposing (Html , button , div , text )
66import Html.Events exposing (onClick )
77import Json.Decode as Decode
8- import List exposing (map , range )
8+ import List exposing (drop , head , length , map , range )
9+ import Random
910import String exposing (fromInt )
1011import Svg
1112import Svg.Attributes as SA
3132
3233type 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+
98105updateRow : FieldColor -> Position -> Int -> Row -> Row
99106updateRow 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
175177type Key
176178 = LeftArrow
177179 | RightArrow
180+ | DownArrow
178181
179182
180183update : Msg -> Model -> ( Model , Cmd Msg )
181184update 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
219271canDrop : 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