059D
- Description
- Shuffle card decks
- Syntax
- 059D: shuffle_card_decks [int]
- Parameter
- [int]
- Number of decks (between 0 and 6)
This opcode generates arrays of randomly ordered numbers between 1 and 52, the number of arrays determined by the value of this opcode. The arrays simulate the random order when shuffling a deck of 52 cards. Opcode 059E is used to read the elements of the arrays. A value of 0 clears the deck by filling the arrays with the number 0. The arrays do not reset when loading different game sessions so they carry over. For Vice City, this opcode only exists on the PC v1.0 and v1.1, and was never called in the original script.
Algorithm
The following is the algorithm reverse-engineered from Vice City for generating the arrays.
memset(CardStack, 0, sizeof(CardStack[0]) * 312); // init card stack to 0
short seqarr[312]; // set up sequential array with numbers from 0 to 311 inclusive
for (short i = 0; i < 312; i++) {
seqarr[i] = i;
}
if (ScriptParams[0].int32) { // check if opcode's argument is non-zero
int index = ScriptParams[0].int32 * 52; // start index at end of card stack
for (short card = 1; card < 53; card++) { // iterate through all cards
for (int deck = 0; deck < ScriptParams[0].int32; deck++) { // iterate through all decks
int rand = rand() % 0x7FFF; // get random value between 0 and 0x7FFF
int seqindex = static_cast<int>(index * static_cast<float>(rand & 0xFFFF) / 0x8000); // calculate randomized index
int seqval = seqarr[seqindex]; // get value from sequential array at randomized index
CardStack[seqval] = card; // set card stack at value to card number
while (seqindex < index) { // omit used value by shifting elements of sequential array
if (seqindex + 1 < 312) {
seqarr[seqindex] = seqarr[seqindex + 1]; // start shifting at randomized index
} else {
seqarr[seqindex] = 0; // set to 0 if reach end of array
}
seqindex++;
}
index--; // go down the card stack by one
}
}
}
Keywords
shuffle, card, deck, decks