Sega Randomizer

From TetrisWiki
Jump to navigation Jump to search

Sega's original 1988 System 16 Tetris randomizer works as follows:

  1. Upon system startup, the seed is loaded from NVRAM. The first game started will use the loaded seed.
  2. A 1000 piece sequence is generated upon game start, with the seed changing for each piece. Once the sequence is generated, the seed remains the same during a game.
  3. The 1000 piece sequence restarts every 1000 pieces.
  4. Upon gameover, two choices can be made that affect the seed for the next game:
    1. Hit start and skip to the high score screen, before the monkey animation is shown. The seed after the 1000th piece was generated will be used next game.
    2. Wait for the monkey animation to be shown. The randomizer will be run to select a monkey animation, changing the seed for the next game; think of it as if a 1001st piece was generated.

Erasing NVRAM resets the seed to zero, and the randomizer replaces a zero seed with a built-in constant. Thus, the power-on pattern is observed, since the same default seed is always used in that case.

C code of the randomizer:

#include <stdint.h>
#include <stdio.h>

// The game simply calls rand() once at the gameover screen to select the monkey animation, if the player waits for the display of the animation.

#define DEFAULT_SEED 0x2A6D365A
#define HI(lw) ((lw) & 0xFFFF0000)
#define LO(lw) ((lw) & 0xFFFF)
#define LW(lw) ((lw) << 16)
#define RW(lw) ((lw) >> 16)
uint32_t rand(uint32_t *seedp) {
	uint32_t temp, oldseed;

	temp = (*seedp == 0u) ? DEFAULT_SEED : *seedp;
	oldseed = temp;
	temp *= 41u;
	*seedp = temp + LW(temp);
	return (LO(temp) + RW(temp)) | HI(oldseed);
}

void newsequence(uint8_t *seq, size_t len, uint32_t *seedp) {
	for (size_t i = 0u; i < len; i++) {
		seq[i] = (rand(seedp) & 0x3F) % 7;
	}
}

void printsequence(uint8_t *seq, size_t len) {
	for (size_t i = 0u; i < len; i++) {
		char c;

		switch (seq[i]) {
			case 0: c = 'I'; break;
			case 1: c = 'Z'; break;
			case 2: c = 'S'; break;
			case 3: c = 'O'; break;
			case 4: c = 'T'; break;
			case 5: c = 'L'; break;
			case 6: c = 'J'; break;
			default: c = '?'; break;
		}
		putchar(c);
	}
	putchar('\n');
}

Bloxeed uses the same basic randomizer. it's default seed is 0x2A6D365B, same as flashpoint. But to generate pieces it runs one loop of the rando, and stores the FULL result as the new seed for making the piece sequence with, while using the main seed for items. It also backs up this result so it can reuse it when you continue. Also, the piece randomizer in this game takes the low seven bits of the result, not the low six. This means the initial poweron pattern is created with seed of 0x2A6D8010, the result from one run at seed 0x2A6D365B. This makes many more possible sequences exist for Bloxeed, compared to Sega Tetris.

TODO: The randomizers of the other versions.