Skip to content

Commit

Permalink
Replace at least some shuffle algorithms with Shuffle (#3801)
Browse files Browse the repository at this point in the history
Most of these are the poor-quality and slow "naive shuffle", but some might be better.
In any case, Shuffle is known good.
  • Loading branch information
tertu-m authored Dec 28, 2023
1 parent 4f61d44 commit c57b154
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 101 deletions.
37 changes: 8 additions & 29 deletions src/apprentice.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,7 @@ static void ShuffleApprenticeSpecies(void)
for (i = 0; i < ARRAY_COUNT(species); i++)
species[i] = i;

// Shuffle the possible species an arbitrary 50 times
for (i = 0; i < 50; i++)
{
u8 temp;
u8 rand1 = Random() % ARRAY_COUNT(species);
u8 rand2 = Random() % ARRAY_COUNT(species);
SWAP(species[rand1], species[rand2], temp);
}
Shuffle(species, APPRENTICE_SPECIES_COUNT, sizeof(species[0]));

for (i = 0; i < MULTI_PARTY_SIZE; i++)
PLAYER_APPRENTICE.speciesIds[i] = ((species[i * 2] & 0xF) << 4) | ((species[i * 2 + 1]) & 0xF);
Expand Down Expand Up @@ -254,33 +247,19 @@ static void SetRandomQuestionData(void)
u8 questionOrder[APPRENTICE_MAX_QUESTIONS + 1];
u8 partyOrder[MULTI_PARTY_SIZE];
u8 partySlot;
u8 rand;
u8 i, j;
u8 rand1, rand2;
u8 id;

for (i = 0; i < ARRAY_COUNT(partyOrder); i++)
partyOrder[i] = i;

// Shuffle the party an arbitrary 10 times
for (i = 0; i < 10; i++)
{
u8 temp;
rand1 = Random() % ARRAY_COUNT(partyOrder);
rand2 = Random() % ARRAY_COUNT(partyOrder);
SWAP(partyOrder[rand1], partyOrder[rand2], temp);
}
Shuffle(partyOrder, MULTI_PARTY_SIZE, sizeof(partyOrder[0]));

for (i = 0; i < ARRAY_COUNT(questionOrder); i++)
questionOrder[i] = sQuestionPossibilities[i];

// Shuffle the questions an arbitrary 50 times
for (i = 0; i < 50; i++)
{
u8 temp;
rand1 = Random() % ARRAY_COUNT(questionOrder);
rand2 = Random() % ARRAY_COUNT(questionOrder);
SWAP(questionOrder[rand1], questionOrder[rand2], temp);
}
Shuffle(questionOrder, APPRENTICE_MAX_QUESTIONS + 1, sizeof(questionOrder[0]));

gApprenticePartyMovesData = AllocZeroed(sizeof(*gApprenticePartyMovesData));
gApprenticePartyMovesData->moveCounter = 0;
Expand All @@ -302,16 +281,16 @@ static void SetRandomQuestionData(void)
{
do
{
rand1 = Random() % MAX_MON_MOVES;
rand = Random() % MAX_MON_MOVES;
for (j = 0; j < gApprenticePartyMovesData->moveCounter + 1; j++)
{
if (gApprenticePartyMovesData->moveSlots[id][j] == rand1)
if (gApprenticePartyMovesData->moveSlots[id][j] == rand)
break;
}
} while (j != gApprenticePartyMovesData->moveCounter + 1);

gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand1;
PLAYER_APPRENTICE.questions[i].moveSlot = rand1;
gApprenticePartyMovesData->moveSlots[id][gApprenticePartyMovesData->moveCounter] = rand;
PLAYER_APPRENTICE.questions[i].moveSlot = rand;
PLAYER_APPRENTICE.questions[i].data = GetRandomAlternateMove(PLAYER_APPRENTICE.questions[i].monId);
}
}
Expand Down
20 changes: 3 additions & 17 deletions src/battle_pike.c
Original file line number Diff line number Diff line change
Expand Up @@ -886,14 +886,8 @@ static bool8 TryInflictRandomStatus(void)

for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
indices[i] = i;
for (j = 0; j < 10; j++)
{
u8 temp, id;

i = Random() % FRONTIER_PARTY_SIZE;
id = Random() % FRONTIER_PARTY_SIZE;
SWAP(indices[i], indices[id], temp);
}
Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0]));

if (gSaveBlock2Ptr->frontier.curChallengeBattleNum <= 4)
count = 1;
Expand Down Expand Up @@ -1265,7 +1259,7 @@ static void Task_DoStatusInflictionScreenFlash(u8 taskId)

static void TryHealMons(u8 healCount)
{
u8 j, i, k;
u8 j, i;
u8 indices[FRONTIER_PARTY_SIZE];

if (healCount == 0)
Expand All @@ -1276,15 +1270,7 @@ static void TryHealMons(u8 healCount)

// Only 'healCount' number of pokemon will be healed.
// The order in which they're (attempted to be) healed is random,
// and determined by performing 10 random swaps to this index array.
for (k = 0; k < 10; k++)
{
u8 temp;

i = Random() % FRONTIER_PARTY_SIZE;
j = Random() % FRONTIER_PARTY_SIZE;
SWAP(indices[i], indices[j], temp);
}
Shuffle(indices, FRONTIER_PARTY_SIZE, sizeof(indices[0]));

for (i = 0; i < FRONTIER_PARTY_SIZE; i++)
{
Expand Down
24 changes: 2 additions & 22 deletions src/mauville_old_man.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,7 @@ static void InitGiddyTaleList(void)
// Shuffle question list
for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
giddy->questionList[i] = i;
for (i = 0; i < GIDDY_MAX_QUESTIONS; i++)
{
var = Random() % (i + 1);
SWAP(giddy->questionList[i], giddy->questionList[var], temp);
}
Shuffle(giddy->questionList, GIDDY_MAX_QUESTIONS, sizeof(giddy->questionList[0]));

// Count total number of words in above word groups
totalWords = 0;
Expand Down Expand Up @@ -1265,27 +1261,12 @@ static void StorytellerRecordNewStat(u32 player, u32 stat)
sStorytellerPtr->language[player] = gGameLanguage;
}

static void ScrambleStatList(u8 *arr, s32 count)
{
s32 i;

for (i = 0; i < count; i++)
arr[i] = i;
for (i = 0; i < count; i++)
{
u32 a = Random() % count;
u32 b = Random() % count;
u8 temp;
SWAP(arr[a], arr[b], temp);
}
}

static bool8 StorytellerInitializeRandomStat(void)
{
u8 storyIds[sNumStories];
s32 i, j;

ScrambleStatList(storyIds, sNumStories);
Shuffle(storyIds, sNumStories, sizeof(storyIds[0]));
for (i = 0; i < sNumStories; i++)
{
u8 stat = sStorytellerStories[storyIds[i]].stat;
Expand Down Expand Up @@ -1427,4 +1408,3 @@ bool8 Script_StorytellerInitializeRandomStat(void)
sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller;
return StorytellerInitializeRandomStat();
}

19 changes: 5 additions & 14 deletions src/mirage_tower.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,13 +598,9 @@ static void DoMirageTowerDisintegration(u8 taskId)
sFallingTower[index].disintegrateRand[i] = i;

// Randomize disintegration pattern
for (i = 0; i <= (INNER_BUFFER_LENGTH - 1); i++)
{
u16 rand1, rand2, temp;
rand1 = Random() % INNER_BUFFER_LENGTH;
rand2 = Random() % INNER_BUFFER_LENGTH;
SWAP(sFallingTower[index].disintegrateRand[rand2], sFallingTower[index].disintegrateRand[rand1], temp);
}
Shuffle(sFallingTower[index].disintegrateRand, INNER_BUFFER_LENGTH,
sizeof(sFallingTower[index].disintegrateRand[0]));

if (gTasks[taskId].data[3] <= (OUTER_BUFFER_LENGTH - 1))
gTasks[taskId].data[3]++;
gTasks[taskId].data[1] = 0;
Expand Down Expand Up @@ -702,13 +698,8 @@ static void Task_FossilFallAndSink(u8 taskId)
break;
case 6:
// Randomize disintegration pattern
for (i = 0; i < FOSSIL_DISINTEGRATE_LENGTH * sizeof(u16); i++)
{
u16 rand1, rand2, temp;
rand1 = Random() % FOSSIL_DISINTEGRATE_LENGTH;
rand2 = Random() % FOSSIL_DISINTEGRATE_LENGTH;
SWAP(sFallingFossil->disintegrateRand[rand2], sFallingFossil->disintegrateRand[rand1], temp);
}
Shuffle(sFallingFossil->disintegrateRand, FOSSIL_DISINTEGRATE_LENGTH,
sizeof(sFallingFossil->disintegrateRand[0]));
gSprites[sFallingFossil->spriteId].callback = SpriteCB_FallingFossil;
break;
case 7:
Expand Down
8 changes: 1 addition & 7 deletions src/tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1956,7 +1956,6 @@ void AlertTVThatPlayerPlayedRoulette(u16 nCoinsSpent)
static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
{
u8 i, j;
u16 k;
u8 n;
u8 decoration;

Expand Down Expand Up @@ -2002,12 +2001,7 @@ static void SecretBaseVisit_CalculateDecorationData(TVShow *show)
break;
default:
// More than 1 decoration, randomize the full list
for (k = 0; k < n * n; k++)
{
decoration = Random() % n;
j = Random() % n;
SWAP(sTV_DecorationsBuffer[decoration], sTV_DecorationsBuffer[j], i);
}
Shuffle(sTV_DecorationsBuffer, n, sizeof(sTV_DecorationsBuffer[0]));

// Pick the first decorations in the randomized list to talk about on the show
for (i = 0; i < show->secretBaseVisit.numDecorations; i++)
Expand Down
13 changes: 1 addition & 12 deletions src/wild_encounter.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ static u16 GetCurrentMapWildMonHeaderId(void)
u8 PickWildMonNature(void)
{
u8 i;
u8 j;
struct Pokeblock *safariPokeblock;
u8 natures[NUM_NATURES];

Expand All @@ -396,17 +395,7 @@ u8 PickWildMonNature(void)
{
for (i = 0; i < NUM_NATURES; i++)
natures[i] = i;
for (i = 0; i < NUM_NATURES - 1; i++)
{
for (j = i + 1; j < NUM_NATURES; j++)
{
if (Random() & 1)
{
u8 temp;
SWAP(natures[i], natures[j], temp);
}
}
}
Shuffle(natures, NUM_NATURES, sizeof(natures[0]));
for (i = 0; i < NUM_NATURES; i++)
{
if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
Expand Down

0 comments on commit c57b154

Please sign in to comment.