ai simple combo system is finally fully working.
added ai hint dontblockwith(targetchooser)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user