working on player AI

This commit is contained in:
Chris Danford
2003-04-07 22:07:44 +00:00
parent 02d72dea3d
commit 14cbdd2ce7
9 changed files with 171 additions and 77 deletions
+12
View File
@@ -414,3 +414,15 @@ void GameState::RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn )
}
GAMESTATE->m_PlayerOptions[pn] = po;
}
int GameState::GetSumOfActiveAttackLevels( PlayerNumber pn )
{
int iSum = 0;
for( unsigned s=0; s<NUM_INVENTORY_SLOTS; s++ )
if( m_ActiveAttacks[pn][s].fSecsRemaining > 0 )
iSum += m_ActiveAttacks[pn][s].level;
return iSum;
}
+2 -1
View File
@@ -164,6 +164,7 @@ public:
// used in PLAY_MODE_RAVE and PLAY_MODE_BATTLE
struct ActiveAttack
{
AttackLevel level;
float fSecsRemaining;
CString sModifier;
};
@@ -172,7 +173,7 @@ public:
void LaunchAttack( PlayerNumber target, ActiveAttack aa );
void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
void RemoveAllActiveAttacks(); // called on end of song
int GetSumOfActiveAttackLevels( PlayerNumber pn );
bool HasEarnedExtraStage();
+19 -6
View File
@@ -17,16 +17,18 @@
#include "RageTimer.h"
#define NUM_ITEM_TYPES THEME->GetMetricF("Inventory","NumItemTypes")
#define ITEM_DURATION_SECONDS THEME->GetMetricF("Inventory","ItemDurationSeconds")
#define ITEM_COMBO( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dCombo",i+1))
#define ITEM_EFFECT( i ) THEME->GetMetric ("Inventory",ssprintf("Item%dEffect",i+1))
#define NUM_ITEM_TYPES THEME->GetMetricF("Inventory","NumItemTypes")
#define ITEM_DURATION_SECONDS THEME->GetMetricF("Inventory","ItemDurationSeconds")
#define ITEM_COMBO( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dCombo",i+1))
#define ITEM_EFFECT( i ) THEME->GetMetric ("Inventory",ssprintf("Item%dEffect",i+1))
#define ITEM_LEVEL( i ) THEME->GetMetricI("Inventory",ssprintf("Item%dLevel",i+1))
const PlayerNumber OPPOSITE_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 };
struct Item
{
AttackLevel level;
int iCombo;
CString sModifier;
};
@@ -38,6 +40,7 @@ void ReloadItems()
for( int i=0; i<NUM_ITEM_TYPES; i++ )
{
Item item;
item.level = (AttackLevel)(ITEM_LEVEL(i)-1);
item.iCombo = ITEM_COMBO(i);
item.sModifier = ITEM_EFFECT(i);
g_Items.push_back( item );
@@ -151,10 +154,20 @@ void Inventory::UseItem( int iSlot )
return;
PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber];
GameState::ActiveAttack aa;
aa.fSecsRemaining = ITEM_DURATION_SECONDS;
aa.sModifier = asInventory[iSlot];
aa.fSecsRemaining = ITEM_DURATION_SECONDS;
aa.level = ATTACK_LEVEL_1;
// UGLY: Search through g_Items and find out what the attack level for this item is.
for( unsigned i=0; i<g_Items.size(); i++ )
{
if( aa.sModifier == g_Items[i].sModifier )
{
aa.level = g_Items[i].level;
break;
}
}
GAMESTATE->LaunchAttack( pnToAttack, aa );
GAMESTATE->RebuildPlayerOptionsFromActiveAttacks( pnToAttack );
+4 -68
View File
@@ -29,6 +29,7 @@
#include "Combo.h"
#include "ScoreDisplay.h"
#include "LifeMeter.h"
#include "PlayerAI.h"
#define GRAY_ARROWS_Y THEME->GetMetricF("Player","GrayArrowsY")
#define JUDGMENT_Y THEME->GetMetricF("Player","JudgmentY")
@@ -39,75 +40,10 @@ CachedThemeMetricI BRIGHT_GHOST_COMBO_THRESHOLD("Player","BrightGhostComboTh
#define STOP_DRAWING_AT_PIXELS THEME->GetMetricI("Player","StopDrawingAtPixels")
/* Distance to search for a note in Step(). */
/* Units? */
static const float StepSearchDistanceBackwards = 1.0f;
static const float StepSearchDistanceForwards = 1.0f;
struct TapScoreDistribution
{
float fCumulativeProbability[NUM_TAP_NOTE_SCORES];
TapNoteScore GetTapNoteScore()
{
float fRand = randomf(0,1);
for( int i=0; i<NUM_TAP_NOTE_SCORES; 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.010f, // TNS_BOO
0.02f, // TNS_GOOD
0.10f, // TNS_GREAT
0.50f, // 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
},
};
Player::Player()
@@ -439,7 +375,7 @@ void Player::Step( int col )
}
else
{
score = TAP_SCORE_DISTRIBUTIONS[GAMESTATE->m_PlayerController[m_PlayerNumber]].GetTapNoteScore();
score = PlayerAI::GetTapNoteScore( GAMESTATE->m_PlayerController[m_PlayerNumber], GAMESTATE->GetSumOfActiveAttackLevels(m_PlayerNumber) );
}
if( score==TNS_MARVELOUS && !PREFSMAN->m_bMarvelousTiming )
@@ -582,7 +518,7 @@ void Player::CrossedRow( int iNoteRow )
{
if( GetTapNote(t, iNoteRow) != TAP_EMPTY )
{
TapNoteScore tns = TAP_SCORE_DISTRIBUTIONS[ GAMESTATE->m_PlayerController[m_PlayerNumber] ].GetTapNoteScore();
TapNoteScore tns = PlayerAI::GetTapNoteScore( GAMESTATE->m_PlayerController[m_PlayerNumber], GAMESTATE->GetSumOfActiveAttackLevels(m_PlayerNumber) );
if( tns!=TNS_MISS )
this->Step( t );
}
+92
View File
@@ -0,0 +1,92 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: PlayerAI
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "PlayerAI.h"
#include "RageUtil.h"
#include <math.h>
struct TapScoreDistribution
{
float fCumulativeProbability[NUM_TAP_NOTE_SCORES];
TapNoteScore GetTapNoteScore( int iDifficultyExponent )
{
float fRand = randomf(0,1);
ASSERT( iDifficultyExponent >= 1 );
fRand = powf(fRand, iDifficultyExponent);
for( int i=0; i<NUM_TAP_NOTE_SCORES; 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.010f, // TNS_BOO
0.03f, // TNS_GOOD
0.10f, // TNS_GREAT
0.50f, // 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
},
};
TapNoteScore PlayerAI::GetTapNoteScore( PlayerController pc, int iSumOfAttackLevels )
{
return TAP_SCORE_DISTRIBUTIONS[pc].GetTapNoteScore( iSumOfAttackLevels+1 );
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef PlayerAI_H
#define PlayerAI_H
/*
-----------------------------------------------------------------------------
Class: PlayerAI
Desc: .
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameConstantsAndTypes.h"
class PlayerAI
{
public:
static TapNoteScore PlayerAI::GetTapNoteScore( PlayerController pc, int iSumOfAttackLevels );
};
#endif
+1
View File
@@ -81,6 +81,7 @@ void RaveHelper::LaunchAttack( AttackLevel al )
PlayerNumber pnToAttack = OPPOSITE_PLAYER[m_PlayerNumber];
GameState::ActiveAttack aa;
aa.level = al;
aa.fSecsRemaining = ATTACK_DURATION_SECONDS;
aa.sModifier = sAttackToGive;
+10 -2
View File
@@ -60,7 +60,7 @@ IntDir=.\../Release6
TargetDir=\stepmania\stepmania
TargetName=StepMania
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -95,7 +95,7 @@ IntDir=.\../Debug6
TargetDir=\stepmania\stepmania
TargetName=StepMania-debug
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -495,6 +495,14 @@ SOURCE=.\NoteTypes.h
# End Source File
# Begin Source File
SOURCE=.\PlayerAI.cpp
# End Source File
# Begin Source File
SOURCE=.\PlayerAI.h
# End Source File
# Begin Source File
SOURCE=.\PlayerNumber.cpp
# End Source File
# Begin Source File
+6
View File
@@ -671,6 +671,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
<File
RelativePath="NotesWriterSM.h">
</File>
<File
RelativePath="PlayerAI.cpp">
</File>
<File
RelativePath="PlayerAI.h">
</File>
<File
RelativePath="PlayerNumber.cpp">
</File>