defmodule Tetris do alias Tetris.{Bottom, Brick, Points} def prepare(brick) do brick |> Brick.prepare |> Points.move_to_location(brick.location) end def drop(brick, bottom, colour) do new_brick = Brick.down(brick) maybe_do_drop( Bottom.collides?(bottom, prepare(new_brick)), bottom, brick, new_brick, colour ) end def maybe_do_drop(true=_collided,bottom, old_brick, _new_block, colour) do new_brick = Brick.new_random points = old_brick |> prepare |> Points.with_colour(colour) {count, new_bottom} = bottom |> Bottom.merge(points) |> Bottom.full_collapse %{ brick: new_brick, bottom: new_bottom, score: score(count), game_over: Bottom.collides?(new_bottom, prepare(new_brick)) } end def maybe_do_drop(false=_collided,bottom, _old_brick, new_block, _colour) do %{ brick: new_block, bottom: bottom, score: 1, game_over: false } end def score(0), do: 0 def score(count) do 100 * round(:math.pow(2, count)) end def try_left(brick, bottom), do: try_move(brick,bottom, &Brick.left/1) def try_right(brick, bottom), do: try_move(brick,bottom, &Brick.right/1) def try_spin(brick, bottom), do: try_move(brick,bottom, &Brick.spin_90/1) defp try_move(brick, bottom, f) do new_brick = f.(brick) if Bottom.collides?(bottom, prepare(new_brick)) do brick else new_brick end end end