Tetris DX

Not to be confused with Tetris DS, a game released for the Nintendo DS.

Tetris DX is a Game Boy Color game that is an enhancement of Nintendo's original Game Boy Tetris, with two added gameplay modes (Ultra, lasting 3 minutes; and Vs. CPU, a match against the computer), a profile/save feature, and color graphics on Game Boy Color and above. In addition, the game's rotation system had a feature which lets a player move any tetromino except O upward by holding the direction against a wall while rotating in the opposite direction.

Modes

 * Marathon (score maxes at 9,999,999)
 * True 40 lines mode (not 40 "points" like in Tetris Worlds)
 * Vs. CPU opponent

Rotation system
The rotation system is an early version of what would become SRS. Very interestingly, L, J, T spawn pointing down, while I, S, Z spawn pointing up. TDX first tries rotation about the center of the box (the blue circle). If this fails, it tries rotation about an alternate center displaced by one cell (the gray circle). For I, S, and Z, this center starts out one cell above the ordinary center; for L, J, or T, it starts out one cell below.

Wall climbing
This rotation system is exploitable, especially on low levels: This particular exploit was fixed in SRS, because it uses a different rotation system.

Infinity
Ordinarily, Tetris DX lock delay follows step reset behavior: only downward motion under gravity resets the lock delay timer. But rotation about the alternate center does reset the timer used for gravity. This can be exploited by placing a piece in a corner and rotating it back and forth about the alternate center:

Randomizer
Like in the original GameBoy version, some piece shapes show up more frequently than others - for different reasons though. A test involving around 10,000 pieces resulted in the following piece distributions:

Almost every fourth dealt piece is T-shaped. According to people trying to read the assembly code, the algorithm works roughly like this:

currentPiece = nextPiece pieceCount = (pieceCount + 1) % 7

// generate the piece a = randInt(0..7) if a == 7 { a = pieceCount } if a != lastPiece { // stick to choice lastPiece = a   rerollCount = 0 } else { // change choice rerollCount += 1 a = rerollCount if rerollCount >= 5 { rerollCount = 0 go back to the "generate the piece" comment } } nextPiece = a

The final choice is noted by the variable a in this pseudo code. Each shape is represented by an integer number between 0 and 6, as listed in the table above (piece ID). At first, the algorithm rolls a random integer number between 0 and 7, and a becomes that number - except if the random number was 7, then it will chose 0 to 6 according to the total number of dealt pieces. The algorithm will stick to this choice, if a differs from the last dealt piece.

However, there's also some code with the purpose to reduce the likelihood of receiving the same shape twice in a row, and this part is flawed. There's a variable called rerollCount and it basically counts how often the algorithm will change its choice in a row. The chance to change the choice is slightly below 1/7 = 14.3 %, and rerollCount is almost geometrically distributed according to this chance. rerollCount is most likely 1 in this branch of the code; 2 is the second most common; and 5 is already so unlikely that this if statement can be ignored.

Anyway, if the algorithm changes its choice, then it will reroll the piece exactly once. And in case of the reroll it doesn't set a to a random integer number - it sets a to rerollCount instead. And as explained above, rerollCount is most likely 1 which corresponds to the T shape. And if it's not 1, then it's most likely 2 which corresponds to the Z shape. This explains why the T piece shows up almost twice as often as the other shapes, and why the Z piece is the second most common. It seems the S piece doesn't show up as often as it should according to this code - maybe the random number generation has a slight bias, too.