- 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:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
131
projects/mtg/include/AIPlayerBaka.h
Normal file
131
projects/mtg/include/AIPlayerBaka.h
Normal 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
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user