> q = q : quit : The 'q' command instructs learntris to quit. : : Learntris should not produce any output unless : explicitly instructed to do so.
Matrix is the official term for the 10 × 22 grid of cells.
The playing area is only 10 × 20 but there are 2 extra lines above where new tetriminos form.
> p # 1 2 3 4 5 6 7 8 9 ( first column, hidden by the #, is 0 . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 > q = p : print : The 'p' command instructs learntris to print the state : of the matrix, the rectangular array of cells in which : blocks can appear. : : The matrix is 10 cells wide and 22 cells deep, although : the top two rows are used only for spawning new Tetraminos. : : At the start of the game, the matrix should be empty. : The 'p' command should indicate empty cells with the : '.' character. : : Cells should be separated by spaces. : : Lines should be separated by the standard end of line : sequence on your operating system (python's "\n").
> g > . . . . . . . . . . # 0 > . . . . . . . . . . # 1 > . . . . . . . . . . # 2 > . . . . . . . . . . # 3 > m m m m m m m m m m # 4 > b b b b b b b b b b # 5 > c c c c c c c c c c # 6 > g g g g g g g g g g # 7 > y y y y y y y y y y # 8 > o o o o o o o o o o # 9 > r r r r r r r r r r # 10 > . . . . . . . . . . # 11 > . . . . . . . . . . # 12 > . . . . . . . . . . # 13 > . . . . . . . . . . # 14 > c . . . . . . . . . # 15 > c . . . . . . . . . # 16 > c . . . . g . . . . # 17 > c . . o . g g . . . # 18 > . . . o . b g . . . # 19 > . m r r o o b y y . # 20 > m m m r r b b y y . # 21 > p . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 m m m m m m m m m m # 4 b b b b b b b b b b # 5 c c c c c c c c c c # 6 g g g g g g g g g g # 7 y y y y y y y y y y # 8 o o o o o o o o o o # 9 r r r r r r r r r r # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 c . . . . . . . . . # 15 c . . . . . . . . . # 16 c . . . . g . . . . # 17 c . . o . g g . . . # 18 . . . o . b g . . . # 19 . m r r o o b y y . # 20 m m m r r b b y y . # 21 > q = g : given : The 'g' command instructs learntris to read 22 lines : of text from the standard input stream, and use the : characters on these lines to populate some internal : representation of the matrix. : : The letter 'g' is a mnemonic for the word 'given', as : in: "given the following matrix...." : : The input format should be identical to the output : produced by the 'p' command. : : The letters used in the representation correspond to : the set of colors used for blocks in the game: : : . = empty (black) b = blue c = cyan : g = green m = magenta o = orange : r = red y = yellow
> g > . . . . . . . . . . # 0 > . . . . . . . . . . # 1 > . . . . . . . . . . # 2 > . . . . . . . . . . # 3 > m m m m m m m m m m # 4 > b b b b b b b b b b # 5 > c c c c c c c c c c # 6 > g g g g g g g g g g # 7 > y y y y y y y y y y # 8 > o o o o o o o o o o # 9 > r r r r r r r r r r # 10 > . . . . . . . . . . # 11 > . . . . . . . . . . # 12 > . . . . . . . . . . # 13 > . . . . . . . . . . # 14 > c . . . . . . . . . # 15 > c . . . . . . . . . # 16 > c . . . . g . . . . # 17 > c . . o . g g . . . # 18 > . . . o . b g . . . # 19 > . m r r o o b y y . # 20 > m m m r r b b y y . # 21 > c > p . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 > q = c : clear : The 'c' command instructs learntris to clear the matrix.
> ?s 0 >q = ?s : query 's' register (score) : The '?s' command instructs learntris to display the : current score as a decimal number. : : Initially, the score should be zero.
> ?n 0 >q = ?n : query 'n' register (number of cleared lines) : The '?n' command instructs learntris to display the : number of lines that have been cleared. : : Initially, this number should be zero.
> ?s 0 > g > . . . . . . . . . . # 0 > . . . . . . . . . . # 1 > . . . . . . . . . . # 2 > . . . . . . . . . . # 3 > . . . . . . . . . . # 4 > . . . . . . . . . . # 5 > . . . . . . . . . . # 6 > . . . . . . . . . . # 7 > . . . . . . . . . . # 8 > . . . . . . . . . . # 9 > m c r g b y m c o b # 10 > . . . . . . . . . . # 11 > . . . . . . . . . . # 12 > m y o . c r g c m y # 13 > . . . . . . . . . . # 14 > . . . . . . . . . . # 15 > . . . . . . . . . . # 16 > . . . . . . . . . . # 17 > . . . . . . . . . . # 18 > . . . . . . . . . . # 19 > . . . . . . . . . . # 20 > . . . . . . . . . . # 21 > s > p . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 m y o . c r g c m y # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 > ?n 1 > ?s 100 > q = s : step : The 's' command instructs learntris to execute one step : of the simulation. : : If the matrix contains an unbroken row of blocks, (or : in other words, a row that contains no empty cells), then : the 's' command should: : : 1. Clear the row (replacing each block with an empty cell) : 2. Increment the 'n' register by 1. : 3. Increment the 's' register by 100. : : This is only an initial approximation of the scoring : system, but it will do for now.
> I > t . . . . c c c c . . . . . . . . > q = t,I : drawing and selecting the active tetramino : At any point in time while the game is running, there : should be a single 'active' tetramino that the player : is able to control. Normally these are chosen somewhat : randomly at runtime, but for automated testing, there : needs to be some way to set the active tetramino. : : There are exactly seven tetraminos and they each have : specific names used by mathematicians and players of : video games. This one is called the I tetramino, and : in the game, it is generally colored cyan. : : After issuing the 'I' command, the active tetramino : should be the 'I' tetramino, and it should be oriented : horizontally. : : In order to verify that the active tetramino is correct, : the tests need some way to ask what it looks like. This : is the role of the 't' command: it displays the active : tetramino.
The O spawns in a 4 × 3 matrix:
> O > t y y y y > q = O : The O Tetramino : The 2x2 square is called the O tetramino, and in the game : it should be colored yellow. : : Note that while the I tetramino appeared inside a 4x4 : matrix, the O tetramino's matrix is 2x2. This has to do : with rotation, which we will deal with later.
The Z and others fit in 3x3 matrices.
> Z t q r r . . r r . . . = Z : The Z Tetramino : The Z Tetramino is colored red and inhabits a 3x3 matrix. : : Notice that in this test, the commands are all issued on : a single line. This helps keep the test descriptions : readable, and also makes it more convienient to type the : commands interactively by hand. : : You do realize you can do that, right? :) : : Anyway, from now on, commands may be separated by either : newlines or spaces. You may need to adjust your : implementation accordingly.
> S t q . g g g g . . . . = S : The S Tetramino. : The green S tetramino inhabits a 3x3 matrix. It is a mirror image of the Z.
> J t q b . . b b b . . . = J : The J Tetramino : The J tetramino is blue and inhabits a 3x3 matrix. Its default : orientation is rotated 90 degrees counter clockwise.
> L t q . . o o o o . . . = L : The L Tetramino : The L tetramino is a mirror image of the J. It is colored orange.
> T t q . m . m m m . . . = T : The T Tetramino : The T is is colored magenta and spawns upside down in a 3x3 matrix.
Clockwise only. No wall-kicks. For each test, four rotations should bring it back to the staring position.
> I ) t . . c . . . c . . . c . . . c . > ) t . . . . . . . . c c c c . . . . > ) t . c . . . c . . . c . . . c . . > ) t q . . . . c c c c . . . . . . . . = ) : clockwise rotation : The ')' command rotates the active tetramino 90 degrees clockwise. : Here we see the I tetramino rotating clockwise within its bounding box.
> O ) t y y y y > ) t y y y y > ) t y y y y > ) t q y y y y = O rotation : The O looks the same in all orientations.
> Z t r r . . r r . . . > ) t . . r . r r . r . > ) t . . . r r . . r r > ) t q . r . r r . r . . = Z Rotation : The Z rotates within its 3x3 matrix.
> S t ; ) t ; ) t ; ) t q . g g g g . . . . . g . . g g . . g . . . . g g g g . g . . g g . . g . = ; : newlines and S rotation : You should be getting the hang of rotation now. : Here we see the new ';' command, which emits a newline : simply to make the output a little more readable.
> J t ; ) t ; ) t ; ) t q b . . b b b . . . . b b . b . . b . . . . b b b . . b . b . . b . b b . = J Rotation : No surprises here. : Maybe this is a good time to look over your code : and see if there's something you ought to clean up?
> L t ; ) t ; ) t ; ) t q . . o o o o . . . . o . . o . . o o . . . o o o o . . o o . . o . . o . = L Rotation : Yep. Another rotating tetramino.
> T t ; ) t ; ) t ; ) t ; q . m . m m m . . . . m . . m m . m . . . . m m m . m . . m . m m . . m . = T Rotation : Last one!
> c O P q . . . . Y Y . . . . # 0 . . . . Y Y . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = P : Print Matrix with active Tetramino : Now it's time to place the active tetramino in the matrix. : The 'P' command should print the matrix just like 'p' does, : but in addition, it should show the active tetramino. : : Note that the active tetramino is drawn with upper case : letters, so we can distinguish it from the settled blocks. : : Here we see the O tetramino in its initial spawn location.
> c L P q . . . . . O . . . . # 0 . . . O O O . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn location for L : This is how the L Tetramino spawns.
> cJPq . . . B . . . . . . # 0 . . . B B B . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn location for J : Here's the spawn location for J. : : Notice that there are no spaces between the commands : this time. We said earlier that commands may be separated : by spaces or newlines, but we never said they *had* to be.
> cZPq . . . R R . . . . . # 0 . . . . R R . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn Location for Z : This is where the Z spawns.
> cSPq . . . . G G . . . . # 0 . . . G G . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn Location for S : This is where the S spawns.
> cIPq . . . . . . . . . . # 0 . . . C C C C . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn Location for I : This is where the I spawns.
> cTPq . . . . M . . . . . # 0 . . . M M M . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Spawn Location for T : And finally, this is where the T spawns.
> cT<Pq . . . M . . . . . . # 0 . . M M M . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = It's just a step to the left... : The '<' command nudges the active tetramino one cell to the left.
> cT>Pq . . . . . M . . . . # 0 . . . . M M M . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = ... And then a jump to the right. : The '>' command nudges the tetramino one cell to the right.
> cTvPq . . . . . . . . . . # 0 . . . . M . . . . . # 1 . . . M M M . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Onward, young Tetramino : The 'v' command nudges the active tetramino downward by one cell.
# nudging <<< should put T on the left wall > cT<<<P . M . . . . . . . . # 0 M M M . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 # nudging again should do nothing: > <Pq . M . . . . . . . . # 0 M M M . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Hitting The Wall : Three '<' commands should place a freshly spawned T tetramino : against the left side of the matrix. But it should go no further, : no matter how many more '<' commands get sent.
# nudging >>>> should put T on the right wall > cT>>>>P . . . . . . . . M . # 0 . . . . . . . M M M # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 # nudging again should do nothing: > >Pq . . . . . . . . M . # 0 . . . . . . . M M M # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Hitting the Other Wall : Look out! It seems that crafty T tetramino is trying to escape : on the right side of the matrix! Let's teach it a lesson, shall we?
> T ( >>>> > Pq . . . . . . . . . M # 0 . . . . . . . . M M # 1 . . . . . . . . . M # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = Smashing its Head Against the Wall : This T appears to have rotated counter-clockwise : with the '(' command, and then attempted once again : to plow its way through the right side of the matrix. : : It gets an extra '>' in with this strategy, but : there can be no compromise.
> cT vvvv vvvv vvvv vvvv vvvv vvvv Pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . M . . . . . # 20 . . . M M M . . . . # 21 = Oh, how the Mighty have Fallen... : Once upon a time, a T tetramino spawned at the : top of the well, and used the 'v' command to : move down by one cell 24 times. Sadly, it was : unable to burrow into the earth and spent the : remainder of its life standing on its head at : the bottom of a well.
> TVpq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . m . . . . . # 20 . . . m m m . . . . # 21 = Taking the plunge. : This one dove head first into the floor, : using the 'V' command to trigger a hard drop. : : Note that we're printing with 'p' this time. : There's no walking away from a hard drop.
> T)V pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . m . . . . . # 19 . . . . m m . . . . # 20 . . . . m . . . . . # 21 = Rotate and Hard drop. : Aside from demonstrating the astonishing grace : and agility of your average tetramino as it plunges : sideways to its doom, this test double checks that : your collision detection holds up under rotation.
> TV ZV pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . r r . . . . . # 18 . . . . r r . . . . # 19 . . . . m . . . . . # 20 . . . m m m . . . . # 21 = Block Collisions : Here we have our first test of collision detection : between a falling piece and a block already in the well. : : When the second hard drop is issued, the Z tetramino : should collide with the remains of the T and come to : a complete halt.
> TV Z)<V pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . r . . . . . # 18 . . . r r . . . . . # 19 . . . r m . . . . . # 20 . . . m m m . . . . # 21 = Rotated Collision : Same situation, but the Z rotates clockwise first, : and then takes one step to the left. Now when it falls, : it should fit together nicely with the remains of the T.
> J ) << V Z ) vvvvvvvvvvvvvvvvv < Pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . R . . . . # 17 . . . . R R . . . . # 18 . . b b R . . . . . # 19 . . b . . . . . . . # 20 . . b . . . . . . . # 21 = Sideways Block Collisions 1 : Here we've hard-drapped a J off to the left side a bit, then : spawned a Z and manually moved it down next to the fallen blocks. : The '<' commands should have no effect.
> I)>V I)>V I)>V I)>V T)>vvvv> Pq . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . M . . . . # 4 . . . . . M M . . . # 5 . . . . . M c . . . # 6 . . . . . . c . . . # 7 . . . . . . c . . . # 8 . . . . . . c . . . # 9 . . . . . . c . . . # 10 . . . . . . c . . . # 11 . . . . . . c . . . # 12 . . . . . . c . . . # 13 . . . . . . c . . . # 14 . . . . . . c . . . # 15 . . . . . . c . . . # 16 . . . . . . c . . . # 17 . . . . . . c . . . # 18 . . . . . . c . . . # 19 . . . . . . c . . . # 20 . . . . . . c . . . # 21 = Sideways Block Collisions 2 : Here's another scenario. That rascally T tetramino : is attempting to pass through a tower of cyan blocks. : Alas, his big head gets in the way... Or at least it : would, if this test were passing...
> @ p Learntris (c) 1992 Tetraminex, Inc. Press start button to begin. > ! p q . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = The Title Screen : Legal says we need a title screen with a copyright notice. : It should show up when you first turn on the game, but for : the tests, they're fine as long as there's some way to get : to it. : : Here's what we came up with: the '@' command takes you to : the title screen, where the 'p' command prints out the main : menu. Then '!' to simulate the start button should take you : to the game.
> p . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 > ! p Paused Press start button to continue. > ! p q . . . . . . . . . . # 0 . . . . . . . . . . # 1 . . . . . . . . . . # 2 . . . . . . . . . . # 3 . . . . . . . . . . # 4 . . . . . . . . . . # 5 . . . . . . . . . . # 6 . . . . . . . . . . # 7 . . . . . . . . . . # 8 . . . . . . . . . . # 9 . . . . . . . . . . # 10 . . . . . . . . . . # 11 . . . . . . . . . . # 12 . . . . . . . . . . # 13 . . . . . . . . . . # 14 . . . . . . . . . . # 15 . . . . . . . . . . # 16 . . . . . . . . . . # 17 . . . . . . . . . . # 18 . . . . . . . . . . # 19 . . . . . . . . . . # 20 . . . . . . . . . . # 21 = The Pause Menu : Wow, that title screen you whipped up was a huge hit upstairs. : They loved pressing that start button, and they want to show : it off in the brochures. So now they're asking for a pause : screen that pops up when the '!' command gets issued in-game. : Sending '!' again should unpause.
> I)>V I)>V I)>V I)>V I)>V T)>>V Pq . . . . . m . . . . # 0 . . . . . m m . . . # 1 . . . . . m c . . . # 2 . . . . . . c . . . # 3 . . . . . . c . . . # 4 . . . . . . c . . . # 5 . . . . . . c . . . # 6 . . . . . . c . . . # 7 . . . . . . c . . . # 8 . . . . . . c . . . # 9 . . . . . . c . . . # 10 . . . . . . c . . . # 11 . . . . . . c . . . # 12 . . . . . . c . . . # 13 . . . . . . c . . . # 14 . . . . . . c . . . # 15 . . . . . . c . . . # 16 . . . . . . c . . . # 17 . . . . . . c . . . # 18 . . . . . . c . . . # 19 . . . . . . c . . . # 20 . . . . . . c . . . # 21 Game Over = The Game Over Screen : The T tetramino couldn't escape the top 2 tetramino : spawning rows. Your game is over!
> q (Something Awesome) = The Next Test : Congratualations! Your learntris implementation passes all : existing tests, and you've even created and passed a few of : your own. : : Take a moment to pat yourself on the back for making it this far. :) : : Now it's time for the real test... : : Take a look at what you've built so far. Is this everything : you'd want to see in a video game? Or is it missing a thing : or two? : : This test case contradicts the very first one, so the only way : to make it pass is to delete it, or replace it with something : better. The choice is yours. : : Either way, you will need to open up testplan.org and search : for the test named 'learntris.end'.
- Think of a situation that needs to be tested.
- Think of the commands you would need to issue to make that situation happen.
- Write a new test that shows the expected behavior.
Here is the test format (remove the leading ‘: ’ from each line, and also the comments on the right).
#+name: test.name <- must be unique! #+begin_src <- marks start of test # other lines with # are comments <- comment > o <- '>' indicates an input line output <- anything besides (#, >, :, or =) more output | is expected output. > q <- always send the quit command! = my very own test <- this is the title for the test : This is where I describe the test. <- ':' indicates a line of description : Here's another descriptive line. | these lines show up when a test fails. #+end_src <- marks end of test
- [x] Game over conditions.
- [ ] Better scoring.
- [ ] Some or all of the Super Rotation System
- [ ] Wall Kicks
- [ ] Floor Kicks
- [ ] T-Spins
- [ ] The Ghost Piece (preview of where the tetramino will land)
- [ ] The Hold Piece (swap out the active tetramino)
- [ ] Test how and when the game speeds up as you progress.
- [ ] A high score system.
- [ ] Rules for when a tetramino becomes part of the matrix.
… Or come up with your own rules and make the game your own. :)