use of cardgame1.Hero in project cardgame1 by joey101937.
the class AI method getValueOfCard.
/**
* gets the value that playing a card represents
* @param c card to evaluate
* @return the value playing the card presents
*/
public static int getValueOfCard(Card c) {
Board.getMainBoard().tick();
Hero enemy;
if (c.getOwner() == Board.topHero) {
enemy = Board.botHero;
} else {
enemy = Board.topHero;
}
int value = 0;
switch(c.cardPurpose) {
case VanillaMinion:
value = c.summon.attack + c.summon.health + c.intrinsicValue;
if (c.cost < c.getOwner().minions.numOccupants()) {
// small minions are penalized for taking a board slot
value -= c.cost - c.getOwner().minions.numOccupants();
}
// if there is no place to summon the minion, it has 0 value.
if (c.getOwner().minions.isFull())
return 0;
if (isVulnerable(c.summon)) {
value = c.summon.attack + c.intrinsicValue;
}
return value;
case BattlecryMinionDamage:
// if there is no place to summon the minion, it has 0 value.
if (c.getOwner().minions.isFull())
return 0;
Minion target = AI.getBestTarget(new SimulatedMinion(c.spellDamage, 0, c.getOwner()));
// System.out.println("best target for " + c + " is " + target);
if (target != null)
value += getWorth(target) - AI.getWorthAfterDamage(target, c.spellDamage);
else
// there are no minions to use it on so this is the value of using the damage on the opponent's hero
value += c.spellDamage / 2;
if (isVulnerable(c.summon)) {
value += c.summon.attack;
} else {
value += c.summon.attack + c.summon.maxHealth;
}
return value + c.intrinsicValue;
case BattlecryMinionHeal:
// if there is no place to summon the minion, it has 0 value.
if (c.getOwner().minions.isFull())
return 0;
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (isVulnerable(m)) {
if (!isVulnerable(new SimulatedMinion(m.attack, m.health + c.spellDamage, c.getOwner()))) {
// if we can save a minion
if (getWorth(m) > value) {
// the value of the card becomes teh value of the minion saved. use the value of the most important minion we can save
value = getWorth(m);
}
}
}
}
if (value == 0)
value = c.spellDamage;
value += getWorth(c.summon);
return value + c.intrinsicValue;
case AOEDamage:
value = 0;
for (Minion m : c.getOwner().opponent.minions.getOccupants()) {
if (m.health <= c.spellDamage)
value += getWorth(m) + 1;
else
value += c.spellDamage;
}
return value + c.intrinsicValue;
case DirectDamage:
value = 0;
Minion optimalTarget = null;
if (c.spellDamage == 0)
return -1;
if (c.getOwner() == Board.topHero) {
for (Minion m : Board.botHero.minions.getStorage()) {
if (m == null)
continue;
int thisValue = getWorth(m) - AI.getWorthAfterDamage(m, c.spellDamage);
if (thisValue > value) {
value = thisValue;
optimalTarget = m;
}
}
} else {
for (Minion m : Board.topHero.minions.getStorage()) {
if (m == null)
continue;
int thisValue = getWorth(m) - AI.getWorthAfterDamage(m, c.spellDamage);
if (thisValue > value) {
value = thisValue;
optimalTarget = m;
}
}
}
// System.out.println("best target for " + c + " is " + optimalTarget);
return value + c.intrinsicValue;
case Debuff:
if (c.getOwner() == Board.botHero) {
if (Board.topHero.minions.numOccupants() == 0)
return -1;
if (AI.canFavorablyTrade(AI.getBiggestThreatOf(Board.topHero))) {
if (!canFavorablyTrade(new SimulatedMinion(getBiggestThreatOf(Board.topHero).attack - c.spellDamage, getBiggestThreatOf(Board.topHero).health, c.getOwner()))) {
// if the enemy's biggest threat can no longer trade up
value += 1;
}
if (!AI.isVulnerable(getBiggestThreatOf(Board.topHero))) {
if (isVulnerable(new SimulatedMinion(getBiggestThreatOf(Board.topHero).attack - c.spellDamage, getBiggestThreatOf(Board.topHero).health, c.getOwner()))) {
// if the enemy's biggest threat is now vulnerable
value += 1;
}
}
}
if (getWorth(getBiggestThreatOf(Board.topHero)) > c.spellDamage) {
value += getBiggestThreatOf(Board.topHero).health;
} else {
value += c.spellDamage;
}
} else {
if (Board.botHero.minions.numOccupants() == 0)
return -1;
if (AI.canFavorablyTrade(AI.getBiggestThreatOf(Board.botHero))) {
if (!canFavorablyTrade(new SimulatedMinion(getBiggestThreatOf(Board.botHero).attack - c.spellDamage, getBiggestThreatOf(Board.botHero).health, c.getOwner()))) {
// if the enemy's biggest threat can no longer trade up
value += 1;
}
if (!AI.isVulnerable(getBiggestThreatOf(Board.botHero))) {
if (isVulnerable(new SimulatedMinion(getBiggestThreatOf(Board.botHero).attack - c.spellDamage, getBiggestThreatOf(Board.botHero).health, c.getOwner()))) {
// if the enemy's biggest threat is now vulnerable
value += 1;
}
}
}
if (getWorth(getBiggestThreatOf(Board.botHero)) > c.spellDamage) {
value += getBiggestThreatOf(Board.botHero).health;
} else {
value += c.spellDamage;
}
}
return value + c.intrinsicValue;
case AOEHeal:
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
int missingHealth = (m.maxHealth - m.health);
if (missingHealth > c.spellDamage) {
value += c.spellDamage;
} else {
value += missingHealth;
}
}
return value + c.intrinsicValue;
case DirectHeal:
// TODO: Analyze hero hp for potential hero heal
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (isVulnerable(m)) {
if (!isVulnerable(new SimulatedMinion(m.attack, m.health + c.spellDamage, c.getOwner()))) {
// if we can save a minion
if (getWorth(m) > value) {
// the value of the card becomes teh value of the minion saved. use the value of the most important minion we can save
value = getWorth(m);
}
}
}
}
if (value == 0) {
value = c.spellDamage;
}
if (AI.isHeroVulnerable(c.getOwner())) {
int damagePotential = 0;
for (Minion m : enemy.minions.getStorage()) {
if (m == null)
continue;
damagePotential += m.attack;
}
// if this heal would take the hero out of lethal range, its worth alot
if (damagePotential < c.getOwner().health + c.spellDamage)
return 30;
}
return value + c.intrinsicValue;
case Buff:
for (Minion m : c.getOwner().minions.getStorage()) {
if (!canFavorablyTrade(m)) {
if (canFavorablyTrade(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) {
value += AI.getTradeValue(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner), AI.getBestTarget(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner)));
}
}
}
if (value == 0)
value = c.spellDamage - 1;
return value;
case BattleCryMinionBuff:
for (Minion m : c.getOwner().minions.getStorage()) {
if (!canFavorablyTrade(m)) {
if (canFavorablyTrade(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) {
value += AI.getTradeValue(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner), AI.getBestTarget(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner)));
}
}
}
if (value == 0)
value = c.spellDamage - 1;
value += AI.getWorth(c.summon);
return value + c.intrinsicValue;
case ChargeMinion:
if (c.getOwner().minions.isFull())
return 0;
if (getBestTarget(c.summon) == null)
return getWorth(c.summon);
value += getTradeValue(new SimulatedMinion(c.summon), getBestTarget(new SimulatedMinion(c.summon))) + AI.getWorthAfterCombat(c.summon, getBestTarget(c.summon));
// System.out.println("best target for " + c + " is " + getBestTarget(new SimulatedMinion(c.summon)));
if (value < 1)
return getWorth(c.summon);
return value + c.intrinsicValue;
case BattlecryMinionDraw:
if (c.getOwner().minions.isFull())
return 0;
value = getWorth(c.summon) + c.intrinsicValue;
// number of cards we can draw.
int numDrawable = Hero.maxHandSize - c.getOwner().hand.size();
if (// reduce value if it will cause overdraw
c.spellDamage > numDrawable)
// reduce value if it will cause overdraw
value -= (c.spellDamage - numDrawable) * 2;
else
value += (numDrawable - c.spellDamage);
return value;
case Draw:
value = c.intrinsicValue;
// number of cards we can draw.
int amountDrawable = Hero.maxHandSize - c.getOwner().hand.size() + 1;
if (// reduce value if it will cause overdraw
c.spellDamage > amountDrawable)
// reduce value if it will cause overdraw
value -= (c.spellDamage - amountDrawable) * 2;
else
value += (amountDrawable - c.spellDamage);
return value;
case Special:
value = c.getValue();
return value + c.intrinsicValue;
case Trap:
for (Trap t : c.getOwner().traps.getOccupants()) {
if (t.name.equals(c.name)) {
return 0;
}
}
value = c.getValue();
return value + c.intrinsicValue;
}
System.out.println("error finding value for " + c);
return value + c.intrinsicValue;
}
use of cardgame1.Hero in project cardgame1 by joey101937.
the class AI method playCard.
/**
* plays card with minion target
* @param c
* @param target
*/
public static void playCard(Card c) {
Board.getMainBoard().tick();
System.out.println("casting " + c);
if (!c.canAfford()) {
System.out.println("cannot play " + c + "; cannot afford");
return;
}
Hero enemy = null;
if (c.getOwner() == Board.topHero) {
enemy = Board.botHero;
} else {
enemy = Board.topHero;
}
int value = 0;
switch(c.cardPurpose) {
case VanillaMinion:
case ChargeMinion:
case AOEDamage:
case AOEHeal:
case BattlecryMinionDraw:
case Trap:
case Draw:
c.cast(null);
break;
case BattlecryMinionDamage:
Minion bestTarget = AI.getBestTarget(new SimulatedMinion(c.spellDamage, 1, c.getOwner()));
if (bestTarget != null) {
System.out.println("casting " + c + "on " + bestTarget);
c.cast(bestTarget);
} else {
c.castOnHero(enemy);
}
break;
case BattlecryMinionHeal:
value = -999;
Minion bestHealTarget = null;
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (isVulnerable(m)) {
if (!isVulnerable(new SimulatedMinion(m.attack, m.health + c.spellDamage, c.getOwner()))) {
// if we can save a minion
if (getWorth(m) > value) {
// the value of the card becomes teh value of the minion saved. use the value of the most important minion we can save
value = getWorth(m);
bestHealTarget = m;
}
}
}
}
if (bestHealTarget != null)
c.cast(bestHealTarget);
else
c.castOnHero(c.getOwner());
break;
case BattleCryMinionBuff:
value = 0;
Minion BestFit = null;
for (Minion m : c.getOwner().minions.getStorage()) {
if (!AI.canFavorablyTrade(m)) {
if (canFavorablyTrade(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) {
if (AI.getTradeValue(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner), AI.getBestTarget(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) > value) {
value = AI.getTradeValue(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner), AI.getBestTarget(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner)));
BestFit = m;
}
}
}
if (BestFit != null) {
c.cast(BestFit);
} else {
if (c.getOwner().minions.numOccupants() > 0) {
c.cast(AI.getBiggestThreatOf(c.getOwner()));
}
}
}
break;
case DirectDamage:
if (enemy.health <= c.spellDamage) {
c.castOnHero(enemy);
break;
}
Minion target = AI.getBestTarget(new SimulatedMinion(c.spellDamage, 0, c.getOwner()));
if (target != null) {
System.out.println("casting " + c + "on " + target);
c.cast(target);
break;
} else {
c.castOnHero(enemy);
System.out.println("no minion target for " + c);
break;
}
case Debuff:
// TODO
break;
case DirectHeal:
if (isHeroVulnerable(c.getOwner())) {
c.castOnHero(c.getOwner());
break;
} else {
Minion potential = null;
int valGained = 0;
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (isVulnerable(m)) {
if (!isVulnerable(new SimulatedMinion(m.attack, m.health + c.spellDamage, m.owner))) {
if (getWorth(m) > valGained) {
valGained = getWorth(m);
potential = m;
}
}
}
}
if (valGained != 0) {
c.cast(potential);
break;
}
if (AI.getBiggestThreatOf(c.getOwner()) != null) {
c.cast(getBiggestThreatOf(c.getOwner()));
break;
} else {
c.castOnHero(c.getOwner());
break;
}
}
case Buff:
int best = 0;
Minion buffTarget = null;
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (!canTradeUp(m)) {
if (canTradeUp(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) {
if (m.attack + c.spellDamage > best) {
best = m.attack + c.spellDamage;
buffTarget = m;
}
}
}
}
if (buffTarget != null) {
c.cast(buffTarget);
break;
}
for (Minion m : c.getOwner().minions.getStorage()) {
if (m == null)
continue;
if (!canFavorablyTrade(m)) {
if (canFavorablyTrade(new SimulatedMinion(m.attack + c.spellDamage, m.health, m.owner))) {
if (getWorth(m) > best) {
best = getWorth(m);
buffTarget = m;
}
}
}
}
if (buffTarget != null) {
c.cast(buffTarget);
break;
}
if (c.getOwner().minions.numOccupants() > 0) {
c.cast(getBiggestThreatOf(c.getOwner()));
break;
} else {
System.out.println("No target for " + c);
}
break;
case Special:
if (!c.isTargeted) {
c.cast(null);
} else {
c.smartCast();
return;
}
break;
}
}
use of cardgame1.Hero in project cardgame1 by joey101937.
the class AI method playOutHand.
/**
* plays all cards we can in the best way possible, recursively
*/
public static void playOutHand(Hero h) {
Board.getMainBoard().tick();
boolean playOver = true;
for (Card c : h.hand) {
// there is something we want to play
if (c.canAfford() && AI.getValueOfCard(c) > 0)
playOver = false;
}
if (playOver)
return;
ArrayList<Card> playable = new ArrayList<>();
for (Card c : h.hand) {
if (c.canAfford() && getValueOfCard(c) > 0)
playable.add(c);
}
// orders the cards using their comparable interface, ordering based on value rather than worth (value accounts for cost, worth does not)
playable.sort(null);
if (playable.get(playable.size() - 1).cardPurpose == CardPurpose.Trap) {
// let user know we are playing a trap card
Sticker s = new Sticker(SpriteHandler.trapPlaceholder, 1700, 200, speed * 3);
} else {
// let user know what non-trap card we are playing
Sticker s = new Sticker(playable.get(playable.size() - 1), 1700, 200, speed * 3);
}
Main.wait(speed * 3);
System.out.println("attempting to play: " + playable.get(playable.size() - 1));
AI.playCard(playable.get(playable.size() - 1));
playOutHand(h);
}
use of cardgame1.Hero in project cardgame1 by joey101937.
the class AI method isHeroVulnerable.
/**
* returns true if the given hero would be killed by an attack from each of the opponents minions
* @param h hero to evaluate
* @return result
*/
public static boolean isHeroVulnerable(Hero h) {
Hero enemy = null;
if (h == Board.topHero) {
enemy = Board.botHero;
} else {
enemy = Board.topHero;
}
int damagePotential = 0;
for (Minion m : enemy.minions.getStorage()) {
if (m == null)
continue;
damagePotential += m.attack;
}
return damagePotential >= h.health;
}
use of cardgame1.Hero in project cardgame1 by joey101937.
the class ArcherCard method castOnHero.
@Override
public int castOnHero(Hero target) {
int outcome = defaultMinionSummon();
if (outcome == 1) {
Sticker s = new Sticker(SpriteHandler.slashEffect, target, AI.AI.speed / 3);
Main.wait(AI.AI.speed / 3);
target.takeDamage(summonDamage);
}
return outcome;
}