From c57b1548a07d9d1ad9e855bdad1c8444b6f19a12 Mon Sep 17 00:00:00 2001 From: tertu Date: Thu, 28 Dec 2023 03:58:35 -0600 Subject: [PATCH] Replace at least some shuffle algorithms with Shuffle (#3801) Most of these are the poor-quality and slow "naive shuffle", but some might be better. In any case, Shuffle is known good. --- src/apprentice.c | 37 ++++++++----------------------------- src/battle_pike.c | 20 +++----------------- src/mauville_old_man.c | 24 ++---------------------- src/mirage_tower.c | 19 +++++-------------- src/tv.c | 8 +------- src/wild_encounter.c | 13 +------------ 6 files changed, 20 insertions(+), 101 deletions(-) diff --git a/src/apprentice.c b/src/apprentice.c index dc7ac92a86d0..8c9128b71864 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -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); @@ -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; @@ -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); } } diff --git a/src/battle_pike.c b/src/battle_pike.c index 0692b680630d..4a2065be4487 100644 --- a/src/battle_pike.c +++ b/src/battle_pike.c @@ -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; @@ -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) @@ -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++) { diff --git a/src/mauville_old_man.c b/src/mauville_old_man.c index 0b4a950ad5f0..0c0714354a4f 100644 --- a/src/mauville_old_man.c +++ b/src/mauville_old_man.c @@ -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; @@ -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; @@ -1427,4 +1408,3 @@ bool8 Script_StorytellerInitializeRandomStat(void) sStorytellerPtr = &gSaveBlock1Ptr->oldMan.storyteller; return StorytellerInitializeRandomStat(); } - diff --git a/src/mirage_tower.c b/src/mirage_tower.c index b1e2e5003b0f..78dec7a15b75 100644 --- a/src/mirage_tower.c +++ b/src/mirage_tower.c @@ -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; @@ -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: diff --git a/src/tv.c b/src/tv.c index 306d0fc9e3f3..0211ef71e2cb 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1956,7 +1956,6 @@ void AlertTVThatPlayerPlayedRoulette(u16 nCoinsSpent) static void SecretBaseVisit_CalculateDecorationData(TVShow *show) { u8 i, j; - u16 k; u8 n; u8 decoration; @@ -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++) diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 13b92136f869..f4412c479aca 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -385,7 +385,6 @@ static u16 GetCurrentMapWildMonHeaderId(void) u8 PickWildMonNature(void) { u8 i; - u8 j; struct Pokeblock *safariPokeblock; u8 natures[NUM_NATURES]; @@ -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)