From 80698277cf1207be8ad1e59add1cd58cbd7752da Mon Sep 17 00:00:00 2001 From: Steve Checkoway Date: Mon, 26 Jun 2006 12:14:30 +0000 Subject: [PATCH] Don't use rand()%n. The function specified by the ANSI committee is a terrible linear congruential generator. In fact, it's so bad that the low order bit alternates. The algorithm implemented as RandomFloat() seems to be Park and Miller's "minimum standard" generator which is better (but not great). [See Knuth for more information.] Any place where you would use rand()%n, use RandomInt(0, n) instead. --- stepmania/src/BGAnimationLayer.cpp | 4 ++-- stepmania/src/Character.cpp | 2 +- stepmania/src/CharacterManager.cpp | 2 +- stepmania/src/DancingCharacters.cpp | 4 ++-- stepmania/src/GameSoundManager.cpp | 2 +- stepmania/src/MusicWheel.cpp | 4 ++-- stepmania/src/NoteDataUtil.cpp | 4 ++-- stepmania/src/PlayerOptions.cpp | 4 ++-- stepmania/src/RageUtil.h | 6 ++++++ stepmania/src/RandomSample.cpp | 2 +- stepmania/src/ScoreKeeperRave.cpp | 4 ++-- stepmania/src/ScreenDebugOverlay.cpp | 10 +++++----- stepmania/src/ScreenDemonstration.cpp | 2 +- stepmania/src/ScreenEdit.cpp | 2 +- stepmania/src/ScreenEnding.cpp | 16 ++++++++-------- stepmania/src/ScreenEvaluation.cpp | 14 +++++++------- stepmania/src/ScreenJukebox.cpp | 6 +++--- .../InputHandler/InputHandler_MonkeyKeyboard.cpp | 2 +- .../MemoryCardDriverThreaded_Windows.cpp | 2 +- 19 files changed, 49 insertions(+), 43 deletions(-) diff --git a/stepmania/src/BGAnimationLayer.cpp b/stepmania/src/BGAnimationLayer.cpp index 101c4fe9df..8c4a676064 100644 --- a/stepmania/src/BGAnimationLayer.cpp +++ b/stepmania/src/BGAnimationLayer.cpp @@ -326,7 +326,7 @@ void BGAnimationLayer::LoadFromAniLayerFile( const RString& sPath ) if( sHint.find("startonrandomframe") != RString::npos ) for( unsigned i=0; iSetState( rand()%m_SubActors[i]->GetNumStates() ); + m_SubActors[i]->SetState( RandomInt(m_SubActors[i]->GetNumStates()) ); if( sHint.find("dontanimate") != RString::npos ) for( unsigned i=0; iSetState( rand()%m_SubActors[i]->GetNumStates() ); + m_SubActors[i]->SetState( RandomInt(m_SubActors[i]->GetNumStates()) ); } } diff --git a/stepmania/src/Character.cpp b/stepmania/src/Character.cpp index e63bb51565..7138bb5560 100644 --- a/stepmania/src/Character.cpp +++ b/stepmania/src/Character.cpp @@ -72,7 +72,7 @@ RString GetRandomFileInDir( RString sDir ) if( asFiles.empty() ) return RString(); else - return asFiles[rand()%asFiles.size()]; + return asFiles[RandomInt(asFiles.size())]; } diff --git a/stepmania/src/CharacterManager.cpp b/stepmania/src/CharacterManager.cpp index a1c461966b..31ff9655a6 100644 --- a/stepmania/src/CharacterManager.cpp +++ b/stepmania/src/CharacterManager.cpp @@ -61,7 +61,7 @@ Character* CharacterManager::GetRandomCharacter() vector apCharacters; GetCharacters( apCharacters ); if( apCharacters.size() ) - return apCharacters[rand()%apCharacters.size()]; + return apCharacters[RandomInt(apCharacters.size())]; else return GetDefaultCharacter(); } diff --git a/stepmania/src/DancingCharacters.cpp b/stepmania/src/DancingCharacters.cpp index 73cacf7ad2..e51b6e35f5 100644 --- a/stepmania/src/DancingCharacters.cpp +++ b/stepmania/src/DancingCharacters.cpp @@ -160,7 +160,7 @@ void DancingCharacters::LoadNextSong() m_pCharacter[p]->PlayAnimation( "rest" ); } -int Neg1OrPos1() { return rand()%2 ? -1 : +1; } +int Neg1OrPos1() { return RandomInt( 2 ) ? -1 : +1; } void DancingCharacters::Update( float fDelta ) { @@ -213,7 +213,7 @@ void DancingCharacters::Update( float fDelta ) // time for a new sweep? if( GAMESTATE->m_fSongBeat > m_fThisCameraEndBeat ) { - if( (rand()%5) >= 2 ) + if( RandomInt(5) >= 2 ) { // sweeping camera m_CameraDistance = CAMERA_SWEEP_DISTANCE + RandomInt(-1,1) * CAMERA_SWEEP_DISTANCE_VARIANCE; diff --git a/stepmania/src/GameSoundManager.cpp b/stepmania/src/GameSoundManager.cpp index 2440fa9ba4..137811cff5 100644 --- a/stepmania/src/GameSoundManager.cpp +++ b/stepmania/src/GameSoundManager.cpp @@ -270,7 +270,7 @@ static void DoPlayOnceFromDir( RString sPath ) if( arraySoundFiles.empty() ) return; - int index = rand() % arraySoundFiles.size(); + int index = RandomInt( arraySoundFiles.size( )); SOUNDMAN->PlayOnce( sPath + arraySoundFiles[index] ); } diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index e7df0c253c..f25aec74ee 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -1065,7 +1065,7 @@ bool MusicWheel::Select() // return true if this selection ends the screen if( m_WheelState == STATE_ROULETTE_SPINNING ) { m_WheelState = STATE_ROULETTE_SLOWING_DOWN; - m_iSwitchesLeftInSpinDown = ROULETTE_SLOW_DOWN_SWITCHES/2+1 + rand()%(ROULETTE_SLOW_DOWN_SWITCHES/2); + m_iSwitchesLeftInSpinDown = ROULETTE_SLOW_DOWN_SWITCHES/2+1 + RandomInt( ROULETTE_SLOW_DOWN_SWITCHES/2 ); m_fTimeLeftInState = 0.1f; return false; } @@ -1331,7 +1331,7 @@ Song *MusicWheel::GetPreferredSelectionForRandomOrPortal() if( i == NUM_PROBES/2 ) vDifficultiesToRequire.clear(); - int iSelection = rand() % wid.size(); + int iSelection = RandomInt( wid.size() ); if( wid[iSelection].m_Type != TYPE_SONG ) continue; diff --git a/stepmania/src/NoteDataUtil.cpp b/stepmania/src/NoteDataUtil.cpp index 04d2984fa2..94520e1070 100644 --- a/stepmania/src/NoteDataUtil.cpp +++ b/stepmania/src/NoteDataUtil.cpp @@ -1068,7 +1068,7 @@ static void SuperShuffleTaps( NoteData &inout, int iStartIndex, int iEndIndex ) set vTriedTracks; for( int i=0; i<4; i++ ) // probe max 4 times { - int t2 = rand() % inout.GetNumTracks(); + int t2 = RandomInt( inout.GetNumTracks() ); if( vTriedTracks.find(t2) != vTriedTracks.end() ) // already tried this track continue; // skip vTriedTracks.insert( t2 ); @@ -1941,7 +1941,7 @@ void NoteDataUtil::AddTapAttacks( NoteData &nd, Song* pSong ) TapNote::attack, TapNote::SubType_invalid, TapNote::original, - szAttacks[rand()%ARRAYSIZE(szAttacks)], + szAttacks[RandomInt(ARRAYSIZE(szAttacks))], 15.0f, false, 0 ); diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index 4c687c9ebd..71610b6c38 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -460,9 +460,9 @@ void PlayerOptions::ChooseRandomModifiers() float f; f = RandomFloat(0,1); if( f>0.66f ) - m_fAccels[rand()%NUM_ACCELS] = 1; + m_fAccels[RandomInt(NUM_ACCELS)] = 1; else if( f>0.33f ) - m_fEffects[rand()%NUM_EFFECTS] = 1; + m_fEffects[RandomInt(NUM_EFFECTS)] = 1; f = RandomFloat(0,1); if( f>0.95f ) m_fAppearances[APPEARANCE_HIDDEN] = 1; diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index 1e10f9a51f..5dbebf6b37 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -176,6 +176,12 @@ inline int RandomInt( int nLow, int nHigh ) return int( RandomFloat() * (nHigh - nLow + 1) + nLow ); } +// Returns an integer between 0 and n-1 inclusive (replacement for rand() % n). +inline int RandomInt( int n ) +{ + return RandomInt( 0, n-1 ); +} + /* Alternative: */ class RandomGen { diff --git a/stepmania/src/RandomSample.cpp b/stepmania/src/RandomSample.cpp index 110e6e7766..34d2421206 100644 --- a/stepmania/src/RandomSample.cpp +++ b/stepmania/src/RandomSample.cpp @@ -92,7 +92,7 @@ int RandomSample::GetNextToPlay() int iIndexToPlay = 0; for( int i=0; i<5; i++ ) { - iIndexToPlay = rand() % m_pSamples.size(); + iIndexToPlay = RandomInt( m_pSamples.size() ); if( iIndexToPlay != m_iIndexLastPlayed ) break; } diff --git a/stepmania/src/ScoreKeeperRave.cpp b/stepmania/src/ScoreKeeperRave.cpp index b1de1d66c3..494790ba6f 100644 --- a/stepmania/src/ScoreKeeperRave.cpp +++ b/stepmania/src/ScoreKeeperRave.cpp @@ -131,12 +131,12 @@ void ScoreKeeperRave::LaunchAttack( AttackLevel al ) RString sAttackToGive; if (GAMESTATE->m_pCurCharacters[pn] != NULL) - sAttackToGive = asAttacks[ rand()%NUM_ATTACKS_PER_LEVEL ]; + sAttackToGive = asAttacks[ RandomInt(NUM_ATTACKS_PER_LEVEL) ]; else { /* If you add any note skins here, you need to make sure they're cached, too. */ RString DefaultAttacks[8] = { "1.5x", "2.0x", "0.5x", "reverse", "sudden", "boost", "brake", "wave" }; - sAttackToGive = DefaultAttacks[ rand()%8 ]; + sAttackToGive = DefaultAttacks[ RandomInt(8) ]; } PlayerNumber pnToAttack = OPPOSITE_PLAYER[pn]; diff --git a/stepmania/src/ScreenDebugOverlay.cpp b/stepmania/src/ScreenDebugOverlay.cpp index 7c675d4ce5..70a5463adc 100644 --- a/stepmania/src/ScreenDebugOverlay.cpp +++ b/stepmania/src/ScreenDebugOverlay.cpp @@ -650,8 +650,8 @@ static HighScore MakeRandomHighScore( float fPercentDP ) { HighScore hs; hs.SetName( "FAKE" ); - hs.SetGrade( (Grade)SCALE( rand()%5, 0, 4, Grade_Tier01, Grade_Tier05 ) ); - hs.SetScore( rand()%100*1000 ); + hs.SetGrade( (Grade)SCALE( RandomInt(5), 0, 4, Grade_Tier01, Grade_Tier05 ) ); + hs.SetScore( RandomInt(100*1000) ); hs.SetPercentDP( fPercentDP ); hs.SetSurviveSeconds( randomf(30.0f, 100.0f) ); PlayerOptions po; @@ -660,11 +660,11 @@ static HighScore MakeRandomHighScore( float fPercentDP ) hs.SetDateTime( DateTime::GetNowDateTime() ); hs.SetPlayerGuid( Profile::MakeGuid() ); hs.SetMachineGuid( Profile::MakeGuid() ); - hs.SetProductID( rand()%10 ); + hs.SetProductID( RandomInt(10) ); FOREACH_TapNoteScore( tns ) - hs.SetTapNoteScore( tns, rand() % 100 ); + hs.SetTapNoteScore( tns, RandomInt(100) ); FOREACH_HoldNoteScore( hns ) - hs.SetHoldNoteScore( hns, rand() % 100 ); + hs.SetHoldNoteScore( hns, RandomInt(100) ); RadarValues rv; FOREACH_RadarCategory( rc ) rv.m_Values.f[rc] = randomf( 0, 1 ); diff --git a/stepmania/src/ScreenDemonstration.cpp b/stepmania/src/ScreenDemonstration.cpp index 9ed8a87910..0afad3f7e9 100644 --- a/stepmania/src/ScreenDemonstration.cpp +++ b/stepmania/src/ScreenDemonstration.cpp @@ -48,7 +48,7 @@ void ScreenDemonstration::Init() } ASSERT( vStylePossible.size() > 0 ); - const Style* pStyle = vStylePossible[ rand() % vStylePossible.size() ]; + const Style* pStyle = vStylePossible[ RandomInt(vStylePossible.size()) ]; GAMESTATE->m_pCurStyle.Set( pStyle ); } diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 5174bc5afe..17c121e96b 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -604,7 +604,7 @@ static RString GetOneBakedRandomFile( Song *pSong, bool bTryGenre = true ) vsNamesOut, bTryGenre ); if( !vsNamesOut.empty() ) - return vsNamesOut[rand()%vsNamesOut.size()]; + return vsNamesOut[RandomInt(vsNamesOut.size())]; else return RString(); } diff --git a/stepmania/src/ScreenEnding.cpp b/stepmania/src/ScreenEnding.cpp index 853da24ef0..4751cda877 100644 --- a/stepmania/src/ScreenEnding.cpp +++ b/stepmania/src/ScreenEnding.cpp @@ -53,9 +53,9 @@ ScreenEnding::ScreenEnding() : ScreenAttract( false/*dont reset GAMESTATE*/ ) STATSMAN->m_CurStageStats.m_player[PLAYER_2].SetLifeRecordAt( 1-fP1, f ); } - STATSMAN->m_CurStageStats.m_player[PLAYER_1].iActualDancePoints = rand()%3; + STATSMAN->m_CurStageStats.m_player[PLAYER_1].iActualDancePoints = RandomInt( 3 ); STATSMAN->m_CurStageStats.m_player[PLAYER_1].iPossibleDancePoints = 2; - STATSMAN->m_CurStageStats.m_player[PLAYER_2].iActualDancePoints = rand()%2; + STATSMAN->m_CurStageStats.m_player[PLAYER_2].iActualDancePoints = RandomInt( 2 ); STATSMAN->m_CurStageStats.m_player[PLAYER_2].iPossibleDancePoints = 1; STATSMAN->m_CurStageStats.m_player[PLAYER_1].iCurCombo = 0; STATSMAN->m_CurStageStats.m_player[PLAYER_1].UpdateComboList( 0, false ); @@ -66,12 +66,12 @@ ScreenEnding::ScreenEnding() : ScreenAttract( false/*dont reset GAMESTATE*/ ) STATSMAN->m_CurStageStats.m_player[PLAYER_1].iCurCombo = 250; STATSMAN->m_CurStageStats.m_player[PLAYER_1].UpdateComboList( 100, false ); - STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W1] = rand()%2; - STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W2] = rand()%2; - STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W3] = rand()%2; - STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W1] = rand()%2; - STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W2] = rand()%2; - STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W3] = rand()%2; + STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W1] = RandomInt( 2 ); + STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W2] = RandomInt( 2 ); + STATSMAN->m_CurStageStats.m_player[PLAYER_1].iTapNoteScores[TNS_W3] = RandomInt( 2 ); + STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W1] = RandomInt( 2 ); + STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W2] = RandomInt( 2 ); + STATSMAN->m_CurStageStats.m_player[PLAYER_2].iTapNoteScores[TNS_W3] = RandomInt( 2 ); STATSMAN->m_vPlayedStageStats.clear(); } diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 14ee8b99eb..0f142c5033 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -106,7 +106,7 @@ ScreenEvaluation::ScreenEvaluation() FOREACH_PlayerNumber( p ) { - if( rand() % 2 ) + if( RandomInt(2) ) GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.m_bTransforms[PlayerOptions::TRANSFORM_ECHO] = true; // show "disqualified" GAMESTATE->m_bSideIsJoined[p] = true; @@ -131,9 +131,9 @@ ScreenEvaluation::ScreenEvaluation() FOREACH_PlayerNumber( p ) { float fSeconds = GAMESTATE->m_pCurSong->GetStepsSeconds(); - STATSMAN->m_CurStageStats.m_player[p].iActualDancePoints = rand()%3; + STATSMAN->m_CurStageStats.m_player[p].iActualDancePoints = RandomInt( 3 ); STATSMAN->m_CurStageStats.m_player[p].iPossibleDancePoints = 2; - if( rand()%2 ) + if( RandomInt(2) ) STATSMAN->m_CurStageStats.m_player[p].iCurCombo = 11000; else STATSMAN->m_CurStageStats.m_player[p].iCurCombo = 0; @@ -154,13 +154,13 @@ ScreenEvaluation::ScreenEvaluation() STATSMAN->m_CurStageStats.m_player[p].UpdateComboList( 0.50f * fSeconds, false ); STATSMAN->m_CurStageStats.m_player[p].iCurCombo = 100; STATSMAN->m_CurStageStats.m_player[p].UpdateComboList( 1.00f * fSeconds, false ); - if( rand()%5 == 0 ) + if( RandomInt(5) == 0 ) { STATSMAN->m_CurStageStats.m_player[p].bFailedEarlier = true; } - STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W1] = rand()%3; - STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W2] = rand()%3; - STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W3] = rand()%3; + STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W1] = RandomInt( 3 ); + STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W2] = RandomInt( 3 ); + STATSMAN->m_CurStageStats.m_player[p].iTapNoteScores[TNS_W3] = RandomInt( 3 ); STATSMAN->m_CurStageStats.m_player[p].iPossibleGradePoints = 4*ScoreKeeperNormal::TapNoteScoreToGradePoints(TNS_W1, false); STATSMAN->m_CurStageStats.m_player[p].fLifeRemainingSeconds = randomf( 90, 580 ); } diff --git a/stepmania/src/ScreenJukebox.cpp b/stepmania/src/ScreenJukebox.cpp index d97d9d12fb..23bf343cf8 100644 --- a/stepmania/src/ScreenJukebox.cpp +++ b/stepmania/src/ScreenJukebox.cpp @@ -76,7 +76,7 @@ void ScreenJukebox::SetSong() if( vSongs.size() == 0 ) return; - Song* pSong = vSongs[rand()%vSongs.size()]; + Song* pSong = vSongs[RandomInt(vSongs.size())]; if( !pSong->HasMusic() ) continue; // skip @@ -85,7 +85,7 @@ void ScreenJukebox::SetSong() if( !pSong->ShowInDemonstrationAndRanking() ) continue; // skip - Difficulty dc = vDifficultiesToShow[ rand()%vDifficultiesToShow.size() ]; + Difficulty dc = vDifficultiesToShow[ RandomInt(vDifficultiesToShow.size()) ]; Steps* pSteps = SongUtil::GetStepsByDifficulty( pSong, GAMESTATE->GetCurrentStyle()->m_StepsType, dc ); if( pSteps == NULL ) @@ -148,7 +148,7 @@ void ScreenJukebox::SetSong() if( !apOptions.empty() ) { - int iIndex = rand()%apOptions.size(); + int iIndex = RandomInt( apOptions.size() ); m_pCourseEntry = apOptions[iIndex]; Course *pCourse = apPossibleCourses[iIndex]; diff --git a/stepmania/src/arch/InputHandler/InputHandler_MonkeyKeyboard.cpp b/stepmania/src/arch/InputHandler/InputHandler_MonkeyKeyboard.cpp index 9acf988399..f3712ce35a 100644 --- a/stepmania/src/arch/InputHandler/InputHandler_MonkeyKeyboard.cpp +++ b/stepmania/src/arch/InputHandler/InputHandler_MonkeyKeyboard.cpp @@ -50,7 +50,7 @@ static const DeviceButton g_keys[] = static DeviceButton GetRandomKeyboardKey() { - int index = rand()%ARRAYSIZE(g_keys); + int index = RandomInt( ARRAYSIZE(g_keys) ); return g_keys[index]; } diff --git a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp index 16574d897e..3bc394d80c 100644 --- a/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp +++ b/stepmania/src/arch/MemoryCard/MemoryCardDriverThreaded_Windows.cpp @@ -42,7 +42,7 @@ bool MemoryCardDriverThreaded_Windows::TestWrite( UsbStorageDevice* pDevice ) * the chance of corruption if the user removes the device immediately, without doing anything. */ for( int i = 0; i < 10; ++i ) { - HANDLE hFile = CreateFile( ssprintf( "%stmp%i", pDevice->sOsMountDir.c_str(), rand() % 100000), + HANDLE hFile = CreateFile( ssprintf( "%stmp%i", pDevice->sOsMountDir.c_str(), RandomInt(100000)), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL );