defmodule Tetris.Brick do alias Tetris.Points @x_centre 40 defstruct [ name: :i, location: {40,0}, rotation: 0, reflection: false ] def new(attributes \\ []), do: __struct__(attributes) def new_random() do %__MODULE__{ name: random_name(), location: {3,-3}, rotation: random_rotation(), reflection: random_reflection() } end def random_name() do ~w(i l z o t)a |> Enum.random() end def random_rotation() do [0, 90, 180, 270] |> Enum.random() end def random_reflection() do [true, false] |> Enum.random end def left(brick) do %{brick| location: point_left(brick.location)} end def right(brick) do %{brick| location: point_right(brick.location)} end def down(brick) do %{brick| location: point_down(brick.location)} end def point_down({x,y}) do {x,y+1} end def point_left({x,y}) do {x-1,y} end def point_right({x,y}) do {x+1,y} end def spin_90(brick) do %{brick| rotation: rotate(brick.rotation)} end def rotate(270), do: 0 def rotate(degrees), do: degrees + 90 def shape(%{name: :l}) do [ {2,1}, {2,2}, {2,3}, {3,3} ] end def shape(%{name: :i}) do [ {2,1}, {2,2}, {2,3}, {2,4} ] end def shape(%{name: :o}) do [ {2,2}, {3,2}, {2,3}, {3,3} ] end def shape(%{name: :z}) do [ {2,2}, {2,3}, {3,3}, {3,4} ] end def shape(%{name: :t}) do [ {2,1}, {2,2}, {3,2} , {2,3} ] end def prepare(brick) do brick |> shape |> Points.rotate(brick.rotation) |> Points.mirror(brick.reflection) end def to_string(brick) do brick |> prepare |> Points.to_string end def print(brick) do brick |> prepare |> Points.print brick end def colour(%{name: :i}), do: :blue def colour(%{name: :l}), do: :green def colour(%{name: :z}), do: :orange def colour(%{name: :o}), do: :red def colour(%{name: :t}), do: :yellow def x_centre(), do: @x_centre defimpl Inspect do import Inspect.Algebra def inspect(brick, _opts) do concat([ "\n", Tetris.Brick.to_string(brick), "\n", "location : #{inspect(brick.location)}", "\n", "reflection: #{inspect(brick.reflection)}", "\n", "rotation : #{inspect(brick.rotation)}" ]) end end end