ai simple combo system is finally fully working.

added ai hint dontblockwith(targetchooser)
This commit is contained in:
omegablast2002@yahoo.com
2013-03-16 21:35:10 +00:00
parent c2132ab97f
commit b436550150
4 changed files with 218 additions and 4 deletions

View File

@@ -18,6 +18,7 @@ public:
string mCondition;
string mAction;
string mCombatAttackTip;
string mCombatBlockTip;
vector<string>castOrder;
vector<string>combos;
//for preformance we disect the combo on first run.
@@ -25,6 +26,7 @@ public:
vector<string>hold;
vector<string>until;
vector<string>restrict;
vector<string>casting;
map<string,string>cardTargets;
string manaNeeded;
int mSourceId;
@@ -48,6 +50,7 @@ public:
AIHints (AIPlayerBaka * player);
AIAction * suggestAbility(ManaCost * potentialMana);
bool HintSaysDontAttack(GameObserver* observer,MTGCardInstance * card = NULL);
bool HintSaysDontBlock(GameObserver* observer,MTGCardInstance * card = NULL);
bool HintSaysItsForCombo(GameObserver* observer,MTGCardInstance * card = NULL);
bool canWeCombo(GameObserver* observer,MTGCardInstance * card = NULL,AIPlayerBaka * Ai = NULL);
vector<string> mCastOrder();

View File

@@ -13,6 +13,7 @@
#define CHOOSE_OPPONENT 7
#define NMB_PLAYERS 2 // Number of players in the game. Currently that's always 2.
#ifdef TESTSUITE
class TestSuite;
@@ -22,6 +23,156 @@ class Credits;
class JNetwork;
#endif
/////// Tournament Mod ///////////
#define PLAYER_TOURNAMENT "tournament.dat"
#define AI_TOURNAMENT "/ai/baka/tournament.dat"
#define AI_RESULTS_FILE "/ai/baka/ai_test.csv"
class TDeck{
public:
TDeck(int deck,PlayerType deckType,int victories = 0,int lastWin = 0, int wonMatches=0, int playedMatches=0, int wonGames=0, int playedGames=0);
TDeck();
~TDeck();
int getDeckNumber(){return mDeckNumber;}
void setDeckNumber(int deck){mDeckNumber=deck;}
void setDeckType(PlayerType ptype){mDeckType=ptype;}
PlayerType getDeckType(){return mDeckType;}
bool isAI(){return mDeckType==PLAYER_TYPE_CPU;}
void reset();
void increaseDeckNumber();
void winGame(){mVictories++;mLastWin++;mGamesPlayed++;mWonGames++;}
void winMatch(){mWonMatches++;mMatchesPlayed++;}
void setMatchesWon(int w){mWonMatches=w;}
int getMatchesWon(){return mWonMatches;}
void looseGame(){mLastWin = 0;mGamesPlayed++;}
void looseMatch(){mMatchesPlayed++;}
void drawMatch(){mMatchesPlayed++;}
int getLastWin(){return mLastWin;}
int getVictories(){return mVictories;}
void newMatch(){mVictories=0;mLastWin=0;}
void deleteStats(){mVictories=0;mLastWin=0;mWonMatches=0;mMatchesPlayed=0;mWonGames=0;mGamesPlayed=0;mRanking=0;}
void resetTournament(){mWonMatches=0;}
void setVictories(int v){mVictories=v;}
void setLastWin(int lastWin){mLastWin=lastWin;}
int getGamesPlayed(){return mGamesPlayed;}
void setGamesPlayed(int games){mGamesPlayed=games;}
int getGamesWon(){return mWonGames;}
void setGamesWon(int games){mWonGames=games;}
int getMatchesPlayed(){return mMatchesPlayed;}
void setMatchesPlayed(int matches){mMatchesPlayed=matches;}
void setRanking(int ranking){mRanking=ranking;}
int getRanking(){return mRanking;}
std::string getDeckName();
private:
int mDeckNumber;
PlayerType mDeckType;
int mVictories;
int mLastWin;
int mWonMatches;
int mMatchesPlayed;
int mWonGames;
int mGamesPlayed;
int mRanking;
int mDifficulty;
};
class Tournament{
public:
Tournament();
~Tournament();
void addDeck(int player,int deck,PlayerType deckType);
void addDeck(int player,TDeck newDeck);
int getDeckNumber(int player){return Deck[player].getDeckNumber();}
PlayerType getDeckType(int player){return Deck[player].getDeckType();}
unsigned int getAvailableDecks(){return nmbDecks;}
void setAvailableDecks(unsigned int a){nmbDecks=a;}
void setGamesToPlay(int games){mNbGames=games;}
int getGamesToPlay(){return mNbGames;}
void setMatchType(int gamestoplay,int matchMode,bool swapPlayer=false){mNbGames=gamestoplay;mMatchMode=matchMode;mCompetition=swapPlayer;}
void setMatchMode(int m){mMatchMode=m;}
int getMatchMode(){return mMatchMode;}
int getTournamentMode(){return mTournamentMode;}
bool isGauntlet();
bool isEndlessDemo();
bool isTournament(){return mTournamentMode>0;}
void setTournamentMode(int b){mTournamentMode=b;}
bool getFastTimerMode(){return mFastTimerMode;}
void setFastTimerMode(bool timerMode){mFastTimerMode=timerMode;}
void updateScoreTable(Player * _p0, Player * _p1, int gt = GAME_TYPE_CLASSIC, bool gameEnd=false);
void renderScoreTable();
bool gameFinished(bool,bool);
bool isMatchFinished(){return endOfMatch;}
bool isNextDeckFound(){return nextDeckFound;}
void swapPlayer();
void revertSwapPlayer();
void Start(); //may change the gamephase
void End();
void saveMatchResults();
bool updateTournament();
void save(bool isAI);
bool load(bool isAI, bool loadComplete);
void setOpLevel(int o){mOpLevel=o;}
int getOpLevel(){return mOpLevel;}
void initTournament();
void resetTournamentSelection(); //resets the choosen oppent decks
std::string exportTournamentDescription();
unsigned int getNumberofTournamentDecks(){return TournamentsDecks.size();}
void enableTournamantMode(int tournamentMode, int player = 0);
bool wasScoreDisplayed(){return scoreDisplayed;}
void setScoreDisplayed(bool s){scoreDisplayed=s;}
bool didHumanWin();
int gamesPlayedbyHuman();
int gamesWonbyHuman();
int matchesPlayedbyHuman();
int matchesWonbyHuman();
void calculateRanking();
void initTournamentResults();
void setRankedDeck(int rank,TDeck deck){if (rank<11&&rank>0)sortedTournamentDecks[rank-1]=deck;}
bool checkTournamentFile(bool isAI);
void leaveOutAIvsAIMatches();
void updateScoreforTournament();
int getHardRandomDeck();
int getRandomDeck(bool noEasyDecks);
int remainingDecksToNextStage();
private:
bool mCompetition;
bool mPlayerSwaped;
int mSpeed;
int mNbGames;
int mMatchMode;
int mGamesPlayed;
unsigned int TournamentsDecksID[NMB_PLAYERS];
int gauntletLastDeckNumber[NMB_PLAYERS];
TDeck Deck[NMB_PLAYERS];
std::vector<TDeck> TournamentsDecks;
int mOpLevel;
unsigned int nmbDecks; // number of decks in the last constructed deckmenu
bool mFastTimerMode;
int mTournamentMode;
bool endOfMatch;
bool nextDeckFound;
bool looserDecks; //double KO
// variables for scoretable
bool scoreDisplayed;
JQuadPtr p0Quad;
JQuadPtr p1Quad;
int mgameType;
TDeck sortedTournamentDecks[10];
int mVictories0;
int mVictories1;
bool p0IsAI;
bool p1IsAI;
bool scoreFinal;
bool tournamentFinal;
int scoreMatchesToPlay;
int scoreMatchesPlayed;
};
/////// End Tournament Mod ///////////
class GameStateDuel: public GameState, public JGuiListener
{
private:
@@ -38,6 +189,13 @@ private:
SimplePopup * popupScreen; // used for informational screens, modal
static int selectedPlayerDeckId;
static int selectedAIDeckId;
/////// Tournament Mod ///////////
//std::ofstream ai_file;
SimpleMenu * cnogmenu; // to choose the number of games to play in the match
void setAISpeed();
Tournament* tournament;
bool tournamentSelection;
/////// End Tournament Mod ///////////
bool premadeDeck;
int OpponentsDeckid;
@@ -48,6 +206,7 @@ private:
void initScroller();
void setGamePhase(int newGamePhase);
public:
GameStateDuel(GameApp* parent);
virtual ~GameStateDuel();
@@ -105,6 +264,20 @@ public:
MENUITEM_REMOTE_CLIENT = -18,
MENUITEM_REMOTE_SERVER = -19,
#endif
/////// Tournament Mod ///////////
MENUITEM_SHOW_SCORE = -20,
MENUITEM_SPEED_FAST = -21,
MENUITEM_SPEED_NORMAL = -22,
MENUITEM_GAUNTLET = -23,
MENUITEM_KO_TOURNAMENT = -24,
MENUITEM_RR_TOURNAMENT = -25,
MENUITEM_START_TOURNAMENT = -26,
MENUITEM_ENDLESSDEMO = -27,
MENUITEM_RANDOM_AI_HARD = -28,
MENUITEM_DOUBLEKO_TOURNAMENT = -29,
MENUITEM_FILL_NEXT_STAGE_HARD = -30,
MENUITEM_FILL_NEXT_STAGE = -31,
/////// End Tournament Mod ///////////
MENUITEM_MORE_INFO = kInfoMenuID
};

View File

@@ -36,6 +36,12 @@ AIHint::AIHint(string _line)
mCombatAttackTip = splitDontAttack[1];
}
vector<string> splitDontBlock = parseBetween(action, "dontblockwith(", ")");
if(splitDontBlock.size())
{
mCombatBlockTip = splitDontBlock[1];
}
vector<string> splitCastOrder = parseBetween(action, "castpriority(", ")");
if(splitCastOrder.size())
{
@@ -100,6 +106,26 @@ bool AIHints::HintSaysDontAttack(GameObserver* observer,MTGCardInstance * card)
return false;
}
bool AIHints::HintSaysDontBlock(GameObserver* observer,MTGCardInstance * card)
{
TargetChooserFactory tfc(observer);
TargetChooser * hintTc = NULL;
for(unsigned int i = 0; i < hints.size();i++)
{
if (hints[i]->mCombatBlockTip.size())
{
hintTc = tfc.createTargetChooser(hints[i]->mCombatBlockTip,card);
if(hintTc && hintTc->canTarget(card,true))
{
SAFE_DELETE(hintTc);
return true;
}
SAFE_DELETE(hintTc);
}
}
return false;
}
bool AIHints::HintSaysItsForCombo(GameObserver* observer,MTGCardInstance * card)
{
TargetChooserFactory tfc(observer);
@@ -142,6 +168,7 @@ bool AIHints::HintSaysItsForCombo(GameObserver* observer,MTGCardInstance * card)
asTc = parseBetween(hints[i]->partOfCombo[dPart],"cast(",")");
if(asTc.size())
{
hints[i]->casting.push_back(asTc[1]);
vector<string>cht = parseBetween(hints[i]->partOfCombo[dPart],"targeting(",")");
if(cht.size())
hints[i]->cardTargets[asTc[1]] = cht[1];
@@ -353,6 +380,11 @@ string AIHints::constraintsNotFulfilled(AIAction * action, AIHint * hint, ManaCo
out << "to see if this can attack[" << hint->mCombatAttackTip << "]";
return out.str();
}
if (hint->mCombatBlockTip.size())
{
out << "to see if this can block[" << hint->mCombatBlockTip << "]";
return out.str();
}
if (hint->mSourceId && !findSource(hint->mSourceId))
{
out << "needcardinplay[" << hint->mSourceId << "]";
@@ -414,7 +446,7 @@ AIAction * AIHints::findAbilityRecursive(AIHint * hint, ManaCost * potentialMana
}
string s = constraintsNotFulfilled(a, hint, potentialMana);
if (hint->mCombatAttackTip.size() || hint->castOrder.size())
if (hint->mCombatAttackTip.size() || hint->mCombatBlockTip.size() || hint->castOrder.size())
return NULL;
if (s.size())
{

View File

@@ -1851,7 +1851,7 @@ MTGCardInstance * AIPlayerBaka::FindCardToPlay(ManaCost * pMana, const char * ty
if(hints && hints->HintSaysItsForCombo(observer,nextCardToPlay))
{
DebugTrace(" AI wants to play a card that belongs to a combo.")
DebugTrace(" AI wants to play a card that belongs to a combo.");
nextCardToPlay = NULL;
}
@@ -1866,9 +1866,9 @@ MTGCardInstance * AIPlayerBaka::activateCombo()
TargetChooser * hintTc = NULL;
TargetChooserFactory tfc(observer);
ManaCost * totalCost = ManaCost::parseManaCost(comboHint->manaNeeded);
for(unsigned int k = 0;k < comboHint->hold.size(); k++)
for(unsigned int k = 0;k < comboHint->casting.size(); k++)
{
hintTc = tfc.createTargetChooser(comboHint->hold[k],nextCardToPlay);
hintTc = tfc.createTargetChooser(comboHint->casting[k],nextCardToPlay);
int combohand = game->hand->cards.size();
for(int j = 0; j < combohand;j++)
{
@@ -2252,6 +2252,8 @@ int AIPlayerBaka::chooseBlockers()
// We first try to block the major threats, those that are marked in the Top 3 of our stats
while ((card = cd.nextmatch(game->inPlay, card)))
{
if(hints && hints->HintSaysDontBlock(observer,card))
continue;
observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE);
int set = 0;
while (!set)
@@ -2287,6 +2289,8 @@ int AIPlayerBaka::chooseBlockers()
card = NULL;
while ((card = cd.nextmatch(game->inPlay, card)))
{
if(hints && hints->HintSaysDontBlock(observer,card))
continue;
if (card->defenser && opponentsToughness[card->defenser] > 0)
{
while (card->defenser)
@@ -2300,6 +2304,8 @@ int AIPlayerBaka::chooseBlockers()
card = NULL;
while ((card = cd.nextmatch(game->inPlay, card)))
{
if(hints && hints->HintSaysDontBlock(observer,card))
continue;
if (!card->defenser)
{
observer->cardClick(card, MTGAbility::MTG_BLOCK_RULE);