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.
This commit is contained in:
tertu 2023-12-28 03:58:35 -06:00 committed by GitHub
parent 4f61d44dfe
commit c57b1548a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 20 additions and 101 deletions

View File

@ -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);
}
}

View File

@ -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++)
{

View File

@ -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();
}

View File

@ -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:

View File

@ -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++)

View File

@ -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)