May 23, 2015

Tetris in clojurescript and re-frame Part 5 - Tetriminios

Types

There are seven tetriminio types each one defined by a number from 1 to 7.

  • 1 I
  • 2 L
  • 3 J
  • 4 O
  • 5 S
  • 6 T
  • 7 S
So when the grid contains the number 1 it will draw the I type at that place.

Each Tetrimino has an orientation defined by numbers 0 to 4.

Tetriminio Drawing Definitions

(def tet-recipe
      {1 {0 [{:x #(- % 1)} {} {:x #(+ % 1)} {:x #(+ % 2)}]
          1 [{:x #(+ % 1) :y #(+ % 1)} {:x #(+ % 1)} {:x #(+ % 1) :y #(- % 1)} {:x #(+ % 1) :y #(- % 2)}]
          2 [{:x #(- % 1) :y #(- % 1)} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)} {:x #(+ % 2) :y #(- % 1)}]
          3 [{:y #(+ % 1)} {} {:y #(- % 1)} {:y #(- % 2)}]}
       2 {0 [{:x #(- % 1) :y #(+ % 1)} {:x #(- % 1)} {} {:x #(+ % 1)}]
          1 [{:x #(+ % 1) :y #(+ % 1)} {:y #(+ % 1)} {} {:y #(- % 1)}]
          2 [{:x #(- % 1)} {} {:x #(+ % 1)} {:x #(+ % 1) :y #(- % 1)}]
          3 [{:y #(+ % 1)} {} {:y #(- % 1)} {:x #(- % 1) :y #(- % 1)}]}
       3 {0 [{:x #(- % 1)} {} {:x #(+ % 1)} {:x #(+ % 1) :y #(+ % 1)}]
          1 [{:y #(+ % 1)} {} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]
          2 [{:x #(- % 1) :y #(- % 1)} {:x #(- % 1)} {} {:x #(+ % 1)}]
          3 [{:x #(- % 1) :y #(+ % 1)} {:y #(+ % 1)} {} {:y #(- % 1)}]}
       4 {0 [{} {:x #(+ % 1)} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]
          1 [{} {:x #(+ % 1)} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]
          2 [{} {:x #(+ % 1)} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]
          3 [{} {:x #(+ % 1)} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]}
       5 {0 [{:x #(- % 1)} {} {:y #(+ % 1)} {:x #(+ % 1) :y #(+ % 1)}]
          1 [{:y #(+ % 1)} {} {:x #(+ % 1)} {:x #(+ % 1) :y #(- % 1)}]
          2 [{:x #(- % 1) :y #(- % 1)} {:y #(- % 1)} {} {:x #(+ % 1)}]
          3 [{:x #(- % 1) :y #(+ % 1)} {:x #(- % 1)} {} {:y #(- % 1)}]}
       6 {0 [{:x #(- % 1)} {} {:x #(+ % 1)} {:y #(+ % 1)}]
          1 [{:y #(+ % 1)} {} {:y #(- % 1)} {:x #(+ % 1)}]
          2 [{:x #(- % 1)} {} {:x #(+ % 1)} {} {:y #(- % 1)}]
          3 [{:y #(+ % 1)} {} {:y #(- % 1)} {:x #(- % 1)}]}
       7 {0 [{:x #(- % 1) :y #(+ % 1)} {:y #(+ % 1)} {} {:x #(+ % 1)}]
          1 [{:x #(+ % 1) :y #(+ % 1)} {:x #(+ % 1)} {} {:y #(- % 1)}]
          2 [{:x #(- % 1)} {} {:y #(- % 1)} {:x #(+ % 1) :y #(- % 1)}]
          3 [{:y #(+ % 1)} {} {:x #(- % 1)} {:x #(- % 1) :y #(- % 1)}]}})
          
This is a map of a map of vecs containing anonymous functions for the type and orientation that will then be appliedin the function call drawing a specific tetriminio. The first key of the nested map is the tetriminio type and the second key the orientation.
So whenever we want to draw type S with orientation 0 we will take this for functions:
{:x #(- % 1) :y #(+ % 1)} {:y #(+ % 1)} {} {:x #(+ % 1)}
  • {:x #(- % 1) :y #(+ % 1)} means that for the first block we will subtract x by 1 and add 1 to y.
  • {:y #(+ % 1)} Here we will add 1 to y and leave x like it is
  • {} Leave x and y like they are
  • {:x #(+ % 1)} Add 1 to x and leave y like it is.

This all is in respect to the grid state. So we just move the tetriminio on the grid by applying these functions.

The beauty of this definition is that we could easily add more tetriminios in the map which will just work out of the box.

Active Tetriminio

The current active tetriminio (the one that can be moved) will be stored in the application state as a map like this: {:x 1 :y 1 :o 0 :t 1}. So whenever we pass it around it will be passed as a map.

Tags: tetris clojuresrcipt