Load AI difficulty data at runtime from AI.ini

This commit is contained in:
Chris Danford
2003-04-21 02:41:10 +00:00
parent cc9bf8677a
commit e15dcc2ab5
29 changed files with 412 additions and 228 deletions
+42 -61
View File
@@ -12,83 +12,64 @@
#include "PlayerAI.h"
#include "RageUtil.h"
#include "IniFile.h"
#include "RageException.h"
#include "GameState.h"
#include <math.h>
struct TapScoreDistribution
{
float fCumulativeProbability[NUM_TAP_NOTE_SCORES];
TapNoteScore GetTapNoteScore( int iDifficultyExponent )
TapNoteScore GetTapNoteScore()
{
float fRand = randomf(0,1);
ASSERT( iDifficultyExponent >= 1 );
fRand = powf( fRand, (float)iDifficultyExponent );
for( int i=TNS_MISS; i<=TNS_MARVELOUS; i++ )
if( fRand <= fCumulativeProbability[i] )
return (TapNoteScore)i;
ASSERT(0); // the last probability must be 1.0, so we should never get here!
return TNS_MARVELOUS;
}
};
TapScoreDistribution TAP_SCORE_DISTRIBUTIONS[NUM_PLAYER_CONTROLLERS] =
{
// HUMAN
{
0.00f, // TNS_NONE
1.00f, // TNS_MISS // don't ever hit automatically when human
0.00f, // TNS_BOO
0.00f, // TNS_GOOD
0.00f, // TNS_GREAT
0.00f, // TNS_PERFECT
0.00f, // TNS_MARVELOUS
},
// CPU_EASY
{
0.00f, // TNS_NONE
0.02f, // TNS_MISS
0.06f, // TNS_BOO
0.10f, // TNS_GOOD
0.55f, // TNS_GREAT
0.80f, // TNS_PERFECT
1.00f, // TNS_MARVELOUS
},
// CPU_MEDIUM
{
0.00f, // TNS_NONE
0.01f, // TNS_MISS
0.02f, // TNS_BOO
0.05f, // TNS_GOOD
0.45f, // TNS_GREAT
0.70f, // TNS_PERFECT
1.00f, // TNS_MARVELOUS
},
// CPU_HARD
{
0.00f, // TNS_NONE
0.005f, // TNS_MISS
0.007f, // TNS_BOO
0.01f, // TNS_GOOD
0.10f, // TNS_GREAT
0.60f, // TNS_PERFECT
1.00f, // TNS_MARVELOUS
},
// CPU_AUTOPLAY
{
0.00f, // TNS_NONE
0.00f, // TNS_MISS
0.00f, // TNS_BOO
0.00f, // TNS_GOOD
0.00f, // TNS_GREAT
0.00f, // TNS_PERFECT
1.00f, // TNS_MARVELOUS
},
};
TapScoreDistribution g_Distributions[NUM_SKILL_LEVELS];
TapNoteScore PlayerAI::GetTapNoteScore( PlayerController pc, int iSumOfAttackLevels )
void PlayerAI::InitFromDisk()
{
TapNoteScore tns = TAP_SCORE_DISTRIBUTIONS[pc].GetTapNoteScore( iSumOfAttackLevels+1 );
ASSERT( tns != TNS_NONE ); // sanity check on PlayerAI's result
return tns;
}
IniFile ini;
ini.SetPath( "AI.ini" );
ini.ReadFile();
for( int i=0; i<NUM_SKILL_LEVELS; i++ )
{
CString sKey = ssprintf("Skill%d", i);
if( ini.GetKey(sKey)==NULL )
RageException::Throw( "AI.ini: '%s' doesn't exist.", sKey.GetString() );
TapScoreDistribution& dist = g_Distributions[i];
dist.fCumulativeProbability[TNS_NONE] = 0;
ini.GetValueF( sKey, "MissCum", dist.fCumulativeProbability[TNS_MISS] );
ini.GetValueF( sKey, "BooCum", dist.fCumulativeProbability[TNS_BOO] );
ini.GetValueF( sKey, "GoodCum", dist.fCumulativeProbability[TNS_GOOD] );
ini.GetValueF( sKey, "GreatCum", dist.fCumulativeProbability[TNS_GREAT] );
ini.GetValueF( sKey, "PerfectCum", dist.fCumulativeProbability[TNS_PERFECT] );
dist.fCumulativeProbability[TNS_MARVELOUS] = 1;
}
}
TapNoteScore PlayerAI::GetTapNoteScore( int iCpuSkill, int iSumOfAttackLevels )
{
// shouldn't call this unless we're CPU controlled
ASSERT( iCpuSkill>=0 && iCpuSkill<NUM_SKILL_LEVELS );
iCpuSkill -= iSumOfAttackLevels;
CLAMP( iCpuSkill, 0, NUM_SKILL_LEVELS-1 );
TapScoreDistribution& distribution = g_Distributions[iCpuSkill];
return distribution.GetTapNoteScore();
}