Open JobLeonard opened 5 years ago
Here's what I did for my terrible Commodore version: I created a "bag" and put each piece in twice, then I made sure you didn't get the same piece twice. It ended up being a good chunk of the program, though.
It's probably not the best way to do it but it sure kept the program from generating a deluge of S and Z pieces.
Why two though? Wouldn't the simplest way be to have a sequence of seven and shuffle that sequence every seven steps?
Currently, the logic for a new piece is:
// create a new piece, don't remove old one (it has landed and should stick)
void new_piece() {
y = py = 0;
p = rand() % 7;
r = pr = rand() % 4;
x = px = rand() % (10 - NUM(r, 16));
}
The key line being p = rand() % 7;
If I'm correct, something like this should work: (just wrote this of the top of my head, haven't really written C++ in a while so probably contains a mistake somewhere)
// index into bag sequence and bag of seven tetronimos
int n = 0, bag[7] = {0, 1, 2, 3, 4, 5, 6}
void new_piece() {
y = py = 0;
// Fisher-Yates shuffle the bag every time
// one random sequence is finished
if (n == 0) {
for(int i = 1; i < 7; i++) {
int j = rand() % i;
p = bag[j];
bag[j] = bag[i];
bag[i] = p;
}
}
p = bag[n];
n = (n + 1) % 7;
r = pr = rand() % 4;
x = px = rand() % (10 - NUM(r, 16));
}
Currently any piece can follow any piece. In modern Tetris implementations we instead get pieces in shuffled sequences, where each sequence contains every tetronimo piece exactly once. See also:
https://tetris.fandom.com/wiki/Random_Generator
Would make the game a lot more "fair" to play :)