Erwan
-fix issue 209 (Clone loops AI)
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
#Bug:AI clone
|
||||||
|
[INIT]
|
||||||
|
FIRSTMAIN
|
||||||
|
[PLAYER1]
|
||||||
|
manapool:{3}{U}
|
||||||
|
hand:clone
|
||||||
|
[PLAYER2]
|
||||||
|
[DO]
|
||||||
|
ai
|
||||||
|
ai
|
||||||
|
[ASSERT]
|
||||||
|
COMBATEND
|
||||||
|
[PLAYER1]
|
||||||
|
graveyard:clone
|
||||||
|
[PLAYER2]
|
||||||
|
[END]
|
||||||
@@ -22,7 +22,6 @@ class AIAction{
|
|||||||
protected:
|
protected:
|
||||||
int efficiency;
|
int efficiency;
|
||||||
static int currentId;
|
static int currentId;
|
||||||
static MTGAbility * getCoreAbility(MTGAbility * a);
|
|
||||||
public:
|
public:
|
||||||
MTGAbility * ability;
|
MTGAbility * ability;
|
||||||
Player * player;
|
Player * player;
|
||||||
|
|||||||
@@ -438,6 +438,35 @@ class GenericActivatedAbility:public ActivatedAbility{
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Copier. ActivatedAbility
|
||||||
|
class AACopier:public ActivatedAbility{
|
||||||
|
public:
|
||||||
|
AACopier(int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost=NULL):ActivatedAbility(_id,_source,_cost,0,0){
|
||||||
|
target = _target;
|
||||||
|
}
|
||||||
|
|
||||||
|
int resolve(){
|
||||||
|
MTGCardInstance * _target = (MTGCardInstance *) target;
|
||||||
|
if(_target){
|
||||||
|
source->copy(_target);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * getMenuText(){
|
||||||
|
return "Copy";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AACopier * clone() const{
|
||||||
|
AACopier * a = NEW AACopier(*this);
|
||||||
|
a->isClone = 1;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Generic TargetAbility */
|
/* Generic TargetAbility */
|
||||||
class GenericTargetAbility:public TargetAbility{
|
class GenericTargetAbility:public TargetAbility{
|
||||||
|
|
||||||
@@ -447,6 +476,8 @@ public:
|
|||||||
MTGGameZone * activeZone;
|
MTGGameZone * activeZone;
|
||||||
GenericTargetAbility(int _id, MTGCardInstance * _source, TargetChooser * _tc,MTGAbility * a, ManaCost * _cost = NULL, int _tap=0, int limit = 0, int restrictions = 0, MTGGameZone * dest = NULL):TargetAbility(_id,_source, _tc,_cost,restrictions,_tap),limitPerTurn(limit), activeZone(dest){
|
GenericTargetAbility(int _id, MTGCardInstance * _source, TargetChooser * _tc,MTGAbility * a, ManaCost * _cost = NULL, int _tap=0, int limit = 0, int restrictions = 0, MTGGameZone * dest = NULL):TargetAbility(_id,_source, _tc,_cost,restrictions,_tap),limitPerTurn(limit), activeZone(dest){
|
||||||
ability = a;
|
ability = a;
|
||||||
|
MTGAbility * core = AbilityFactory::getCoreAbility(a);
|
||||||
|
if (dynamic_cast<AACopier *>(core)) tc->other = true; //http://code.google.com/p/wagic/issues/detail?id=209 (avoid inifinite loop)
|
||||||
counters = 0;
|
counters = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -750,36 +781,6 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//Copier. ActivatedAbility
|
|
||||||
class AACopier:public ActivatedAbility{
|
|
||||||
public:
|
|
||||||
AACopier(int _id, MTGCardInstance * _source, MTGCardInstance * _target = NULL, ManaCost * _cost=NULL):ActivatedAbility(_id,_source,_cost,0,0){
|
|
||||||
target = _target;
|
|
||||||
}
|
|
||||||
|
|
||||||
int resolve(){
|
|
||||||
MTGCardInstance * _target = (MTGCardInstance *) target;
|
|
||||||
if(_target){
|
|
||||||
source->copy(_target);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * getMenuText(){
|
|
||||||
return "Copy";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AACopier * clone() const{
|
|
||||||
AACopier * a = NEW AACopier(*this);
|
|
||||||
a->isClone = 1;
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class AADestroyer:public ActivatedAbility{
|
class AADestroyer:public ActivatedAbility{
|
||||||
public:
|
public:
|
||||||
int bury;
|
int bury;
|
||||||
|
|||||||
@@ -229,6 +229,7 @@ class AbilityFactory{
|
|||||||
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL);
|
int abilityEfficiency(MTGAbility * a, Player * p, int mode = MODE_ABILITY, TargetChooser * tc = NULL);
|
||||||
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL, MTGGameZone * dest = NULL);
|
int magicText(int id, Spell * spell, MTGCardInstance * card = NULL, int mode = MODE_PUTINTOPLAY, TargetChooser * tc = NULL, MTGGameZone * dest = NULL);
|
||||||
static int computeX(Spell * spell, MTGCardInstance * card);
|
static int computeX(Spell * spell, MTGCardInstance * card);
|
||||||
|
static MTGAbility * getCoreAbility(MTGAbility * a);
|
||||||
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
|
int destroyAllInPlay(TargetChooser * tc, int bury = 0);
|
||||||
int moveAll(TargetChooser * tc, string destinationZone);
|
int moveAll(TargetChooser * tc, string destinationZone);
|
||||||
int damageAll(TargetChooser * tc, int damage);
|
int damageAll(TargetChooser * tc, int damage);
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class CardDescriptor;
|
|||||||
class TargetChooser: public TargetsList {
|
class TargetChooser: public TargetsList {
|
||||||
protected:
|
protected:
|
||||||
int forceTargetListReady;
|
int forceTargetListReady;
|
||||||
bool other;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum{
|
enum{
|
||||||
@@ -34,7 +33,7 @@ class TargetChooser: public TargetsList {
|
|||||||
CONTROLLER = 1,
|
CONTROLLER = 1,
|
||||||
TARGET_CONTROLLER = 2
|
TARGET_CONTROLLER = 2
|
||||||
};
|
};
|
||||||
|
bool other;
|
||||||
|
|
||||||
TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1, bool other = false);
|
TargetChooser(MTGCardInstance * card = NULL, int _maxtargets = -1, bool other = false);
|
||||||
|
|
||||||
|
|||||||
@@ -142,17 +142,7 @@ int AIPlayer::canHandleCost(MTGAbility * ability){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTGAbility * AIAction::getCoreAbility(MTGAbility * a){
|
|
||||||
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*>(a);
|
|
||||||
if (gta) return getCoreAbility(gta->ability);
|
|
||||||
|
|
||||||
GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(a);
|
|
||||||
if (gaa) return getCoreAbility(gaa->ability);
|
|
||||||
|
|
||||||
if (MultiAbility * abi = dynamic_cast<MultiAbility*>(a)) return getCoreAbility(abi->abilities[0]);
|
|
||||||
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AIAction::getEfficiency(){
|
int AIAction::getEfficiency(){
|
||||||
//TODO add multiplier according to what the player wants
|
//TODO add multiplier according to what the player wants
|
||||||
@@ -163,7 +153,7 @@ int AIAction::getEfficiency(){
|
|||||||
Player * p = g->currentlyActing();
|
Player * p = g->currentlyActing();
|
||||||
if (s->has(ability)) return 0;
|
if (s->has(ability)) return 0;
|
||||||
|
|
||||||
MTGAbility * a = getCoreAbility(ability);
|
MTGAbility * a = AbilityFactory::getCoreAbility(ability);
|
||||||
|
|
||||||
if (!a){
|
if (!a){
|
||||||
OutputDebugString("FATAL: Ability is NULL in AIAction::getEfficiency()");
|
OutputDebugString("FATAL: Ability is NULL in AIAction::getEfficiency()");
|
||||||
@@ -341,7 +331,6 @@ int AIPlayer::chooseTarget(TargetChooser * tc){
|
|||||||
target = this->opponent();
|
target = this->opponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!tc->alreadyHasTarget(target) && tc->canTarget(target) && nbtargets < 50){
|
if (!tc->alreadyHasTarget(target) && tc->canTarget(target) && nbtargets < 50){
|
||||||
for (int i = 0; i < 3; i++){ //Increase probability to target a player when this is possible
|
for (int i = 0; i < 3; i++){ //Increase probability to target a player when this is possible
|
||||||
potentialTargets.push_back(target);
|
potentialTargets.push_back(target);
|
||||||
@@ -356,21 +345,21 @@ int AIPlayer::chooseTarget(TargetChooser * tc){
|
|||||||
for (int k=0; k< zone->nb_cards; k++){
|
for (int k=0; k< zone->nb_cards; k++){
|
||||||
MTGCardInstance * card = zone->cards[k];
|
MTGCardInstance * card = zone->cards[k];
|
||||||
if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50){
|
if (!tc->alreadyHasTarget(card) && tc->canTarget(card) && nbtargets < 50){
|
||||||
if (checkOnly) return 1;
|
if (checkOnly) return 1;
|
||||||
int multiplier = 1;
|
int multiplier = 1;
|
||||||
if (getStats() && getStats()->isInTop(card,10)){
|
if (getStats() && getStats()->isInTop(card,10)){
|
||||||
multiplier++;
|
multiplier++;
|
||||||
if (getStats()->isInTop(card,5)){
|
if (getStats()->isInTop(card,5)){
|
||||||
multiplier++;
|
multiplier++;
|
||||||
if (getStats()->isInTop(card,3)){
|
if (getStats()->isInTop(card,3)){
|
||||||
multiplier++;
|
multiplier++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int l=0; l < multiplier; l++){
|
for (int l=0; l < multiplier; l++){
|
||||||
potentialTargets.push_back(card);
|
potentialTargets.push_back(card);
|
||||||
nbtargets++;
|
nbtargets++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +383,7 @@ int AIPlayer::chooseTarget(TargetChooser * tc){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//BIG PROBLEM
|
//Couldn't find any valid target (why did we play that in the first place ?)
|
||||||
gameObs->cancelCurrentAction();
|
gameObs->cancelCurrentAction();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,18 @@ int AbilityFactory::parseRestriction(string s){
|
|||||||
return ActivatedAbility::NO_RESTRICTION;
|
return ActivatedAbility::NO_RESTRICTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTGAbility * AbilityFactory::getCoreAbility(MTGAbility * a){
|
||||||
|
GenericTargetAbility * gta = dynamic_cast<GenericTargetAbility*>(a);
|
||||||
|
if (gta) return getCoreAbility(gta->ability);
|
||||||
|
|
||||||
|
GenericActivatedAbility * gaa = dynamic_cast<GenericActivatedAbility*>(a);
|
||||||
|
if (gaa) return getCoreAbility(gaa->ability);
|
||||||
|
|
||||||
|
if (MultiAbility * abi = dynamic_cast<MultiAbility*>(a)) return getCoreAbility(abi->abilities[0]);
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Parses a string and returns the corresponding MTGAbility object
|
//Parses a string and returns the corresponding MTGAbility object
|
||||||
// Returns NULL if parsing failed
|
// Returns NULL if parsing failed
|
||||||
|
|||||||
Reference in New Issue
Block a user