Files
wagic/projects/mtg/src/AIStats.cpp
jean.chalard 3e9ff2b580 J :
* Change the name of debug.h into config.h and use the new RESPATH define.
2008-12-25 16:28:03 +00:00

129 lines
3.6 KiB
C++

#include "../include/config.h"
#include "../include/AIStats.h"
#include "../include/GameObserver.h"
#include "../include/Player.h"
#include "../include/MTGCardInstance.h"
bool compare_aistats(AIStat * first, AIStat * second){
float damage1 = first->value / first->occurences;
float damage2 = second->value/ second->occurences;
return (damage1 > damage2);
}
AIStats::AIStats(Player * _player, char * _filename){
filename = _filename;
load(_filename);
player = _player;
}
AIStats::~AIStats(){
list<AIStat *>::iterator it;
for ( it=stats.begin() ; it != stats.end(); it++ ){
AIStat * stat = *it;
delete stat;
}
}
void AIStats::updateStatsCard(MTGCardInstance * cardInstance, Damage * damage, float multiplier){
MTGCard * card = cardInstance->model;
AIStat * stat = find(card);
if (!stat){
stat = NEW AIStat(card->getMTGId(),0,1,0);
stats.push_back(stat);
}
if (damage->target == player){
stat->value+= multiplier * STATS_PLAYER_MULTIPLIER * damage->damage;
}else if (damage->target->type_as_damageable == DAMAGEABLE_MTGCARDINSTANCE){
MTGCardInstance * target = (MTGCardInstance *)damage->target;
if (target->controller() == player && !target->isInPlay()){
//One of my creatures got lethal damage...
stat->value+= multiplier * STATS_CREATURE_MULTIPLIER * damage->damage;
}
}
}
void AIStats::updateStats(){
GameObserver * game = GameObserver::GetInstance();
ActionStack * as = game->mLayers->stackLayer();
Damage * damage = ((Damage * )as->getNext(NULL,ACTION_DAMAGE, RESOLVED_OK));
MTGGameZone * opponentZone = player->opponent()->game->inPlay;
while(damage){
MTGCardInstance * card = damage->source;
updateStatsCard(card,damage);
//Auras on damage source can be the cause
for (int i=0; i < opponentZone->nb_cards; i++){
MTGCardInstance * aura = opponentZone->cards[i];
if (aura->target == card){
updateStatsCard(aura,damage, STATS_AURA_MULTIPLIER);
}
}
damage = ((Damage * )as->getNext(damage,ACTION_DAMAGE, RESOLVED_OK));
}
stats.sort(compare_aistats);
}
bool AIStats::isInTop(MTGCardInstance * card, unsigned int max, bool tooSmallCountsForTrue ){
if (stats.size()<max) return tooSmallCountsForTrue;
unsigned int n = 0;
MTGCard * source = card->model;
int id = source->getMTGId();
list<AIStat *>::iterator it;
for ( it=stats.begin() ; it != stats.end(); it++ ){
if (n >= max) return false;
AIStat * stat = *it;
if (stat->source == id){
if (stat->value>=0) return true;
return false;
}
n++;
}
return false;
}
AIStat * AIStats::find(MTGCard * source){
int id = source->getMTGId();
list<AIStat *>::iterator it;
for ( it=stats.begin() ; it != stats.end(); it++ ){
AIStat * stat = *it;
if (stat->source == id) return stat;
}
return NULL;
}
void AIStats::load(char * filename){
std::ifstream file(filename);
std::string s;
if(file){
while(std::getline(file,s)){
int cardid = atoi(s.c_str());
std::getline(file,s);
int value = atoi(s.c_str());
std::getline(file,s);
int direct = atoi(s.c_str());
AIStat * stat = NEW AIStat(cardid,value,1,direct);
stats.push_back(stat);
}
file.close();
}else{
//TODO Error management
}
}
void AIStats::save(){
std::ofstream file(filename.c_str());
char writer[128];
if (file){
list<AIStat *>::iterator it;
for ( it=stats.begin() ; it != stats.end(); it++ ){
AIStat * stat = *it;
if (stat->value > 0){
sprintf(writer,"%i\n%i\n%i\n", stat->source,stat->value/2,stat->direct);
file<<writer;
}
}
file.close();
}
}