diff --git a/JGE/src/JFileSystem.cpp b/JGE/src/JFileSystem.cpp index 7d190c562..ab1d5adf9 100644 --- a/JGE/src/JFileSystem.cpp +++ b/JGE/src/JFileSystem.cpp @@ -248,7 +248,7 @@ void JFileSystem::clearZipCache() bool JFileSystem::AttachZipFile(const string &zipfile, char *password /* = NULL */) { - if (mZipAvailable && mZipFile != NULL) + if (mZipAvailable && mZipFile.is_open()) { if (mZipFileName != zipfile) DetachZipFile(); // close the previous zip file diff --git a/projects/mtg/include/AIPlayer.h b/projects/mtg/include/AIPlayer.h index 563620a01..9316577a3 100644 --- a/projects/mtg/include/AIPlayer.h +++ b/projects/mtg/include/AIPlayer.h @@ -43,7 +43,7 @@ public: }; friend ostream& operator<<(ostream&, const Action&); - friend istream& operator>>(istream&, Action&); + friend istream& operator>>(istream&, Action&); }; class AIAction @@ -84,6 +84,10 @@ public: { }; int Act(); + ostream& logSimpleAct(ostream& out, MTGCardInstance* click); + ostream& logMultiAct(ostream& out, vector& actionTargets); + + friend ostream& operator<<(ostream& out, AIAction& a); }; diff --git a/projects/mtg/include/GameObserver.h b/projects/mtg/include/GameObserver.h index a7c28b70f..2d0533944 100644 --- a/projects/mtg/include/GameObserver.h +++ b/projects/mtg/include/GameObserver.h @@ -52,7 +52,6 @@ class GameObserver{ string startupGameSerialized; bool parseLine(const string& s); virtual void logAction(const string& s); - bool processAction(const string& s); bool processActions(bool undo #ifdef TESTSUITE , TestSuiteGame* testgame @@ -69,6 +68,7 @@ class GameObserver{ ); public: + bool processAction(const string& s); int currentPlayerId; CombatStep combatStep; int turn; diff --git a/projects/mtg/include/Player.h b/projects/mtg/include/Player.h index eb52fd516..2bb4258f9 100644 --- a/projects/mtg/include/Player.h +++ b/projects/mtg/include/Player.h @@ -105,7 +105,7 @@ public: std::string GetCurrentDeckStatsFile(); virtual bool parseLine(const string& s); friend ostream& operator<<(ostream&, const Player&); - friend istream& operator>>(istream&, Player&); + friend istream& operator>>(istream&, Player&); bool operator<(Player& aPlayer); bool isDead(); }; diff --git a/projects/mtg/src/AIPlayer.cpp b/projects/mtg/src/AIPlayer.cpp index b2a64fae9..b83168ebc 100644 --- a/projects/mtg/src/AIPlayer.cpp +++ b/projects/mtg/src/AIPlayer.cpp @@ -67,6 +67,52 @@ AIAction::AIAction(AIPlayer * owner, MTGCardInstance * c, MTGCardInstance * t) } } +// should be "const AIAction& " instead, but compiler is annoying to enable that. +ostream& operator<<(ostream& out, AIAction& a) +{ + do { + if (a.player && !a.playerAbilityTarget) + { + out << "p" + (a.owner->getObserver()->getPlayerId(a.player) + 1) << endl; + break; + } + if (a.ability) + { + a.logSimpleAct(out, a.click); + // we're ignoring ability and we shouldn't + if (a.target && !a.mAbilityTargets.size()) + { + a.logSimpleAct(out, a.target); + // sounds broken if target is a player ... or not, it's the following case + break; + } + else if(a.playerAbilityTarget && !a.mAbilityTargets.size()) + { + out << "p" + (a.owner->getObserver()->getPlayerId((Player*)a.playerAbilityTarget) + 1) << endl; + // with this log we're losing what player clicked on who ... which is bad. + break; + } + if(a.mAbilityTargets.size()) + { + a.logMultiAct(out, a.mAbilityTargets); + break; + } + } + else if(a.mAbilityTargets.size()) + { + a.logMultiAct(out, a.mAbilityTargets); + break; + } + else if (a.click) + { //Shouldn't be used, really... + assert(0); + } + + } while(0); + + return out; +} + int AIAction::Act() { GameObserver * g = owner->getObserver(); @@ -107,6 +153,49 @@ int AIAction::Act() return 0; } +ostream& AIAction::logSimpleAct(ostream& out, MTGCardInstance* click) +{ + string currentPlayer = "p" + (owner->getObserver()->getPlayerId(owner) + 1); + out << currentPlayer << click->currentZone->getName() << "[" << click->currentZone->getIndex(click) << "]" << endl; + return out; +} + +ostream& AIAction::logMultiAct(ostream& out, vector& actionTargets) +{ + GameObserver * g = owner->getObserver(); + TargetChooser * tc = g->getCurrentTargetChooser(); + do { + if(!tc) break; + vector::iterator ite = actionTargets.begin(); + while(ite != actionTargets.end()) + { + MTGCardInstance * card = ((MTGCardInstance *) (*ite)); + if(card == (MTGCardInstance*)tc->source)//click source first. + { + g->cardClick(card); + ite = actionTargets.erase(ite); + continue; + } + ++ite; + } + + //shuffle to make it less predictable, otherwise ai will always seem to target from right to left. making it very obvious. + owner->getRandomGenerator()->random_shuffle(actionTargets.begin(), actionTargets.end()); + + for(int k = 0 ;k < int(actionTargets.size()) && k < tc->maxtargets; k++) + { + if (MTGCardInstance * card = dynamic_cast(actionTargets[k])) + { + if(k+1 == int(actionTargets.size())) + tc->done = true; + g->cardClick(card); + } + } + tc->attemptsToFill++; + } while (0); + return out; +} + int AIAction::clickMultiAct(vector& actionTargets) { GameObserver * g = owner->getObserver(); diff --git a/projects/mtg/src/AIPlayerMinMax.cpp b/projects/mtg/src/AIPlayerMinMax.cpp index d087e3dc7..f28e26d2d 100644 --- a/projects/mtg/src/AIPlayerMinMax.cpp +++ b/projects/mtg/src/AIPlayerMinMax.cpp @@ -66,9 +66,12 @@ void AIPlayerMinMax::LookAround() vector::iterator it; for(it = potentialActions.begin(); it != potentialActions.end(); it++) { + stringstream theCommand; + theCommand << (*it); + GameObserver g; g.load(stream.str()); -// g.processAction((*it)); + g.processAction(theCommand.str()); } }