summaryrefslogtreecommitdiff
path: root/Uniquely-Shuffle-Array.md
blob: e6f0e1a1270ab117c64386c5bec3eabc2254fd65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
## Uniquely Shuffle Array

credits to ghoulslash

This function is useful for internal randomizers or other challenges. It allows us to uniquely shuffle a predefined array of values (e.g. species) using the [Fisher-Yates algorithm](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle)

### The Function
```c
/*
Inputs:
  list: array of u16 values
  count: size of the array (or number of elements to shuffle)
*/
void ShuffleList(u16 *list, u16 count)
{
    u16 i;

    for (i = (count - 1); i > 0; i--)
    {
        u16 j = Random() % (i + 1);
        u16 arr = list[j];
        list[j] = list[i];
        list[i] = arr;
    }
}
```

### Example
In this example, we will shuffle all possible starters through gen 3

static const u16 sSpeciesToRandomize[9] = {
    SPECIES_BULBASAUR,
    SPECIES_CHARMANDER,
    SPECIES_SQUIRTLE,
    SPECIES_CHIKORITA,
    SPECIES_CYNDAQUIL,
    SPECIES_TOTODILE,
    SPECIES_TREECKO,
    SPECIES_TORCHIC,
    SPECIES_MUDKIP
};

// obviously, this is a terrible way to choose a random starter, but is a good example of how to use the shuffling algorithm.
// we cannot write to `const` data, so we must copy it to EWRAM first.
```c
EWRAM_DATA static u16 sStarters[9] = {0};
static u16 ChooseStarter(void)
{
    memcpy(sStarters, sSpeciesToRandomize, sizeof(sSpeciesToRandomize));
    ShuffleList(sStarters, NELEMS(sSpeciesToRandomize));

    StringCopy(gStringVar1, gSpeciesNames[sStarters[0]]); // buffer the chosen species' name
    return sStarters[0]; // return the first element of the now randomized list, sSpeciesToRandomize
}
```

<a href="https://imgur.com/qk4VFbF"><img src="https://imgur.com/qk4VFbF.gif" title="source: imgur.com" /></a>