- Split AIPlayer and AIPlayerBaka in 2 files. Moved all "AI" specific code into AIPlayerBaka, as much as possible.

-- This is a copy/paste and shouldn't have any impact on the logic. I just moved some functions from AIPlayer to AIPlayerBaka
- Added back the possibility to select a different Resource folder with file Res.txt
- Fix a crash when a token id does not exist
This commit is contained in:
wagic.the.homebrew
2011-09-20 03:06:06 +00:00
parent 839d197835
commit fbfac78b09
22 changed files with 2536 additions and 2350 deletions

View File

@@ -6,7 +6,7 @@
using std::string;
using std::vector;
#include "AIPlayer.h"
#include "AIPlayerBaka.h"
class ManaCost;
class MTGAbility;
@@ -24,7 +24,7 @@ public:
class AIHints
{
protected:
AIPlayer * mPlayer;
AIPlayerBaka * mPlayer;
vector<AIHint *> hints;
AIHint * getByCondition (string condition);
AIAction * findAbilityRecursive(AIHint * hint, ManaCost * potentialMana);
@@ -34,7 +34,7 @@ protected:
bool findSource(int sourceId);
bool abilityMatches(MTGAbility * a, AIHint * hint);
public:
AIHints (AIPlayer * player);
AIHints (AIPlayerBaka * player);
AIAction * suggestAbility(ManaCost * potentialMana);
void add(string line);
~AIHints();

View File

@@ -1,13 +1,13 @@
#ifndef _AIMOMIRPLAYER_H_
#define _AIMOMIRPLAYER_H_
#include "AIPlayer.h"
#include "AIPlayerBaka.h"
class AIMomirPlayer: public AIPlayerBaka
{
public:
AIMomirPlayer(string file, string fileSmall, string avatarFile, MTGDeck * deck = NULL);
int getEfficiency(AIAction * action);
int getEfficiency(OrderedAIAction * action);
int momir();
int computeActions();
static MTGAbility * momirAbility;

View File

@@ -2,6 +2,14 @@
* Wagic, The Homebrew ?! is licensed under the BSD license
* See LICENSE in the Folder's root
* http://wololo.net/wagic/
AIPlayer is the interface to represent a CPU Player.
At its core, AIPlayer inherits from Player, and its children need to implement the function "Act" which
pretty much handles all the logic.
A sample implementation can be found in AIPlayerBaka.
Ideally, mid-term, AIPlayer will handle all the mechanical tasks (clicking on cards, etc...) while its children are just in charge of the logic
*/
#ifndef _IAPLAYER_H
@@ -12,20 +20,11 @@
#include <queue>
using std::queue;
#define INFO_NBCREATURES 0
#define INFO_CREATURESPOWER 1
#define INFO_CREATURESRANK 2
#define INFO_CREATURESTOUGHNESS 3
#define INFO_CREATURESATTACKINGPOWER 4
class AIStats;
class AIHints;
class AIAction
{
protected:
int efficiency;
static int currentId;
public:
MTGAbility * ability;
@@ -39,7 +38,7 @@ public:
//player targeting through abilities is handled completely seperate from spell targeting.
AIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL)
: efficiency(-1), ability(a), player(NULL), click(c), target(t),playerAbilityTarget(NULL)
: ability(a), player(NULL), click(c), target(t),playerAbilityTarget(NULL)
{
id = currentId++;
};
@@ -47,110 +46,57 @@ public:
AIAction(MTGCardInstance * c, MTGCardInstance * t = NULL);
AIAction(Player * p)//player targeting through spells
: efficiency(-1), ability(NULL), player(p), click(NULL), target(NULL),playerAbilityTarget(NULL)
: ability(NULL), player(p), click(NULL), target(NULL),playerAbilityTarget(NULL)
{
};
AIAction(MTGAbility * a, MTGCardInstance * c, vector<Targetable*>targetCards)
: efficiency(-1), ability(a), player(NULL), click(c), mAbilityTargets(targetCards),playerAbilityTarget(NULL)
: ability(a), player(NULL), click(c), mAbilityTargets(targetCards),playerAbilityTarget(NULL)
{
id = currentId++;
};
AIAction(MTGAbility * a, Player * p, MTGCardInstance * c)//player targeting through abilities.
: efficiency(-1), ability(a), click(c),target(NULL), playerAbilityTarget(p)
: ability(a), click(c),target(NULL), playerAbilityTarget(p)
{
id = currentId++;
};
int getEfficiency();
int Act();
int clickMultiAct(vector<Targetable*>&actionTargets);
};
// compares Abilities efficiency
class CmpAbilities
{
public:
bool operator()(const AIAction& a1, const AIAction& a2) const
{
AIAction* a1Ptr = const_cast<AIAction*>(&a1);
AIAction* a2Ptr = const_cast<AIAction*>(&a2);
int e1 = a1Ptr->getEfficiency();
int e2 = a2Ptr->getEfficiency();
if (e1 == e2) return a1Ptr->id < a2Ptr->id;
return (e1 > e2);
}
};
typedef std::map<AIAction, int, CmpAbilities> RankingContainer;
class AIPlayer: public Player{
protected:
//Variables used by Test suite
MTGCardInstance * nextCardToPlay;
AIHints * hints;
queue<AIAction *> clickstream;
bool payTheManaCost(ManaCost * cost, MTGCardInstance * card = NULL,vector<MTGAbility*> gotPayment = vector<MTGAbility*>());
int orderBlockers();
int combatDamages();
int interruptIfICan();
int chooseAttackers();
int chooseBlockers();
int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
AIStats * getStats();
// returns 1 if the AI algorithm supports a given cost (ex:simple mana cost), 0 otherwise (ex: cost involves Sacrificing a target)
int CanHandleCost(ManaCost * cost);
//Tries to play an ability recommended by the deck creator
int selectHintAbility();
int clickMultiTarget(TargetChooser * tc,vector<Targetable*>&potentialTargets);
int clickSingleTarget(TargetChooser * tc,vector<Targetable*>&potentialTargets, MTGCardInstance * Choosencard = NULL);
public:
AIStats * stats;
//These variables are used by TestSuite and Rules.cpp... TODO change that?
int agressivity;
bool forceBestAbilityUse;
void End(){};
virtual int displayStack() {return 0;};
int receiveEvent(WEvent * event);
void Render();
ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
vector<MTGAbility*> canPayMana(MTGCardInstance * card = NULL,ManaCost * mCost = NULL);
vector<MTGAbility*> canPaySunBurst(ManaCost * mCost = NULL);
virtual int receiveEvent(WEvent * event);
virtual void Render();
AIPlayer(string deckFile, string deckFileSmall, MTGDeck * deck = NULL);
virtual ~AIPlayer();
virtual MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0);
virtual int selectMenuOption();
virtual int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget =NULL,MTGCardInstance * Choosencard = NULL,bool checkonly = false);
virtual int clickMultiTarget(TargetChooser * tc,vector<Targetable*>&potentialTargets);
virtual int clickSingleTarget(TargetChooser * tc,vector<Targetable*>&potentialTargets,int nbtargets = 0,MTGCardInstance * Choosencard = NULL);
virtual int Act(float dt);
virtual int affectCombatDamages(CombatStep);
virtual int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget = NULL, MTGCardInstance * Chosencard = NULL, bool checkonly = false) = 0;
virtual int affectCombatDamages(CombatStep) = 0;
virtual int Act(float dt) = 0;
int isAI(){return 1;};
int canHandleCost(MTGAbility * ability);
int selectAbility();
int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, RankingContainer& ranking);
int useAbility();
virtual int getEfficiency(AIAction * action);
};
class AIPlayerBaka: public AIPlayer{
protected:
int oldGamePhase;
float timer;
MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type);
public:
vector<MTGAbility*>gotPayments;
int deckId;
AIPlayerBaka(string deckFile, string deckfileSmall, string avatarFile, MTGDeck * deck = NULL);
virtual int Act(float dt);
void initTimer();
virtual int computeActions();
};
class AIPlayerFactory{
public:
AIPlayer * createAIPlayer(MTGAllCards * collection, Player * opponent, int deckid = 0);

View File

@@ -0,0 +1,131 @@
#ifndef _AI_PLAYER_BAKA_H_
#define _AI_PLAYER_BAKA_H_
#include "AIPlayer.h"
class AIStats;
class AIHints;
//Would love to define those classes as private nested classes inside of AIPlayerBaka, but they are used by AIHints (which itself should be known only by AIPlayerBaka anyways)
// Any way to clean this up and make all the AIPlayerBaka universe (AIHints, AIPlayerBaka, OrderedAIAction) "closed" ?
class OrderedAIAction: public AIAction
{
protected:
int efficiency;
public:
OrderedAIAction(MTGAbility * a, MTGCardInstance * c, MTGCardInstance * t = NULL)
: AIAction(a, c, t), efficiency(-1)
{
};
OrderedAIAction(MTGCardInstance * c, MTGCardInstance * t = NULL);
OrderedAIAction(Player * p)//player targeting through spells
: AIAction(p), efficiency(-1)
{
};
OrderedAIAction(MTGAbility * a, MTGCardInstance * c, vector<Targetable*>targetCards)
: AIAction(a, c, targetCards), efficiency(-1)
{
};
OrderedAIAction(MTGAbility * a, Player * p, MTGCardInstance * c)//player targeting through abilities.
: AIAction(a, p, c), efficiency(-1)
{
};
int getEfficiency();
};
// compares Abilities efficiency
class CmpAbilities
{
public:
bool operator()(const OrderedAIAction& a1, const OrderedAIAction& a2) const
{
OrderedAIAction* a1Ptr = const_cast<OrderedAIAction*>(&a1);
OrderedAIAction* a2Ptr = const_cast<OrderedAIAction*>(&a2);
int e1 = a1Ptr->getEfficiency();
int e2 = a2Ptr->getEfficiency();
if (e1 == e2) return a1Ptr->id < a2Ptr->id;
return (e1 > e2);
}
};
typedef std::map<OrderedAIAction, int, CmpAbilities> RankingContainer;
class AIPlayerBaka: public AIPlayer{
private:
MTGCardInstance * nextCardToPlay;
AIHints * hints;
AIStats * stats;
int orderBlockers();
int combatDamages();
int interruptIfICan();
int chooseAttackers();
int chooseBlockers();
int canFirstStrikeKill(MTGCardInstance * card, MTGCardInstance *ennemy);
int effectBadOrGood(MTGCardInstance * card, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL);
// returns 1 if the AI algorithm supports a given cost (ex:simple mana cost), 0 otherwise (ex: cost involves Sacrificing a target)
int CanHandleCost(ManaCost * cost);
//Tries to play an ability recommended by the deck creator
int selectHintAbility();
vector<MTGAbility*> canPayMana(MTGCardInstance * card = NULL,ManaCost * mCost = NULL);
vector<MTGAbility*> canPaySunBurst(ManaCost * mCost = NULL);
MTGCardInstance * chooseCard(TargetChooser * tc, MTGCardInstance * source, int random = 0);
int selectMenuOption();
int useAbility();
AIStats * getStats();
protected:
int oldGamePhase;
float timer;
MTGCardInstance * FindCardToPlay(ManaCost * potentialMana, const char * type);
//used by MomirPlayer, hence protected instead of private
virtual int getEfficiency(OrderedAIAction * action);
bool payTheManaCost(ManaCost * cost, MTGCardInstance * card = NULL,vector<MTGAbility*> gotPayment = vector<MTGAbility*>());
int getCreaturesInfo(Player * player, int neededInfo = INFO_NBCREATURES , int untapMode = 0, int canAttack = 0);
ManaCost * getPotentialMana(MTGCardInstance * card = NULL);
int selectAbility();
public:
enum {
INFO_NBCREATURES,
INFO_CREATURESPOWER,
INFO_CREATURESRANK,
INFO_CREATURESTOUGHNESS,
INFO_CREATURESATTACKINGPOWER
};
vector<MTGAbility*>gotPayments;
int deckId;
AIPlayerBaka(string deckFile, string deckfileSmall, string avatarFile, MTGDeck * deck = NULL);
virtual int Act(float dt);
void initTimer();
virtual int computeActions();
virtual void Render();
virtual int receiveEvent(WEvent * event);
virtual ~AIPlayerBaka();
int affectCombatDamages(CombatStep step);
int canHandleCost(MTGAbility * ability);
int chooseTarget(TargetChooser * tc = NULL, Player * forceTarget =NULL,MTGCardInstance * Choosencard = NULL,bool checkonly = false);
//used by AIHInts, therefore public instead of private :/
int createAbilityTargets(MTGAbility * a, MTGCardInstance * c, RankingContainer& ranking);
};
#endif

View File

@@ -6,7 +6,7 @@
#define MAX_TESTSUITE_ACTIONS 100
#define MAX_TESTUITE_CARDS 100
#include "AIPlayer.h"
#include "AIPlayerBaka.h"
class TestSuiteActions
{
@@ -95,6 +95,7 @@ public:
};
// TODO This should inherit from AIPlayer instead!
class TestSuiteAI:public AIPlayerBaka
{
private: