Difference between revisions of "059D"

From GTAMods Wiki
Jump to navigation Jump to search
(algorithm)
Line 5: Line 5:
 
| syntax1    = 059D: shuffle_card_decks [''int'']
 
| syntax1    = 059D: shuffle_card_decks [''int'']
 
| p1t        = [''int'']
 
| p1t        = [''int'']
| p1d        = Integer value (between ''0'' and ''6'')
+
| p1d        = 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 [[wikipedia:Standard 52-card deck|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 [[Referring to GTA Versions|PC v1.0 and v1.1]], and was never called in the original script.
 
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 [[wikipedia:Standard 52-card deck|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 [[Referring to GTA Versions|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.
 +
<syntaxhighlight lang="cpp">
 +
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
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
  
 
== Keywords ==
 
== Keywords ==

Revision as of 17:27, 12 October 2016

Vice City San Andreas SHUFFLE_CARD_DECKS


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

Reference