mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
- The AI will now attack with Signal Pest.
- Fixed a possible infinite loop in the attack code. - Added SVar:RemRandomDeck:True to Soulcatchers' Aerie.
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -6165,7 +6165,7 @@ res/cardsfolder/soul_stair_expedition.txt -text svneol=native#text/plain
|
|||||||
res/cardsfolder/soul_warden.txt -text svneol=native#text/plain
|
res/cardsfolder/soul_warden.txt -text svneol=native#text/plain
|
||||||
res/cardsfolder/soulbound_guardians.txt -text svneol=native#text/plain
|
res/cardsfolder/soulbound_guardians.txt -text svneol=native#text/plain
|
||||||
res/cardsfolder/soulcatcher.txt -text svneol=native#text/plain
|
res/cardsfolder/soulcatcher.txt -text svneol=native#text/plain
|
||||||
res/cardsfolder/soulcatchers_aerie.txt svneol=native#text/plain
|
res/cardsfolder/soulcatchers_aerie.txt -text svneol=native#text/plain
|
||||||
res/cardsfolder/souldrinker.txt -text svneol=native#text/plain
|
res/cardsfolder/souldrinker.txt -text svneol=native#text/plain
|
||||||
res/cardsfolder/soulquake.txt svneol=native#text/plain
|
res/cardsfolder/soulquake.txt svneol=native#text/plain
|
||||||
res/cardsfolder/souls_attendant.txt -text svneol=native#text/plain
|
res/cardsfolder/souls_attendant.txt -text svneol=native#text/plain
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$
|
|||||||
SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ FEATHER | CounterNum$ 1
|
SVar:TrigPutCounter:AB$PutCounter | Cost$ 0 | Defined$ Self | CounterType$ FEATHER | CounterNum$ 1
|
||||||
K:stPumpAll:Bird:X/X:no Condition:Bird creatures get +1/+1 for each feather counter on CARDNAME.
|
K:stPumpAll:Bird:X/X:no Condition:Bird creatures get +1/+1 for each feather counter on CARDNAME.
|
||||||
SVar:X:Count$CardCounters.FEATHER
|
SVar:X:Count$CardCounters.FEATHER
|
||||||
|
SVar:RemRandomDeck:True
|
||||||
SVar:Rarity:Uncommon
|
SVar:Rarity:Uncommon
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/soulcatchers_aerie.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/soulcatchers_aerie.jpg
|
||||||
SetInfo:JUD|Uncommon|http://magiccards.info/scans/en/ju/25.jpg
|
SetInfo:JUD|Uncommon|http://magiccards.info/scans/en/ju/25.jpg
|
||||||
|
|||||||
@@ -597,11 +597,11 @@ public class CombatUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns the damage an unblocked attacker would deal
|
//Returns the damage an unblocked attacker would deal
|
||||||
public static int damageIfUnblocked(Card attacker, Player attacked)
|
public static int damageIfUnblocked(Card attacker, Player attacked, Combat combat)
|
||||||
{
|
{
|
||||||
int damage = attacker.getNetCombatDamage();
|
int damage = attacker.getNetCombatDamage();
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
damage += predictPowerBonusOfAttacker(attacker,null,null);
|
damage += predictPowerBonusOfAttacker(attacker,null,combat);
|
||||||
if (!attacker.hasKeyword("Infect")) {
|
if (!attacker.hasKeyword("Infect")) {
|
||||||
sum = attacked.predictDamage(damage, attacker, true);
|
sum = attacked.predictDamage(damage, attacker, true);
|
||||||
if (attacker.hasKeyword("Double Strike")) sum += attacked.predictDamage(damage, attacker, true);
|
if (attacker.hasKeyword("Double Strike")) sum += attacked.predictDamage(damage, attacker, true);
|
||||||
@@ -610,7 +610,7 @@ public class CombatUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Returns the poison an unblocked attacker would deal
|
//Returns the poison an unblocked attacker would deal
|
||||||
public static int poisonIfUnblocked(Card attacker, Player attacked)
|
public static int poisonIfUnblocked(Card attacker, Player attacked, Combat combat)
|
||||||
{
|
{
|
||||||
int damage = attacker.getNetCombatDamage();
|
int damage = attacker.getNetCombatDamage();
|
||||||
int poison = 0;
|
int poison = 0;
|
||||||
@@ -628,7 +628,7 @@ public class CombatUtil {
|
|||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for(Card attacker: attackers) {
|
for(Card attacker: attackers) {
|
||||||
sum += damageIfUnblocked(attacker, attacked);
|
sum += damageIfUnblocked(attacker, attacked, null);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@@ -638,7 +638,7 @@ public class CombatUtil {
|
|||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for(Card attacker: attackers) {
|
for(Card attacker: attackers) {
|
||||||
sum += poisonIfUnblocked(attacker, attacked);
|
sum += poisonIfUnblocked(attacker, attacked, null);
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,19 @@ public class ComputerUtil_Attack2 {
|
|||||||
return list;
|
return list;
|
||||||
}//sortAttackers()
|
}//sortAttackers()
|
||||||
|
|
||||||
|
//Is there any reward for attacking? (for 0/1 creatures there is not)
|
||||||
|
public boolean isEffectiveAttacker(Card attacker, Combat combat)
|
||||||
|
{
|
||||||
|
if (CombatUtil.damageIfUnblocked(attacker, AllZone.HumanPlayer, combat) > 0) return true;
|
||||||
|
if (CombatUtil.poisonIfUnblocked(attacker, AllZone.HumanPlayer, combat) > 0) return true;
|
||||||
|
|
||||||
|
ArrayList<Trigger> registeredTriggers = AllZone.TriggerHandler.getRegisteredTriggers();
|
||||||
|
for(Trigger trigger : registeredTriggers)
|
||||||
|
if (CombatUtil.combatTriggerWillTrigger(attacker,null,trigger, combat)) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public CardList getPossibleAttackers(CardList in)
|
public CardList getPossibleAttackers(CardList in)
|
||||||
{
|
{
|
||||||
CardList list = new CardList(in.toArray());
|
CardList list = new CardList(in.toArray());
|
||||||
@@ -240,14 +253,6 @@ public class ComputerUtil_Attack2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attackersLeft = attackersLeft.filter(new CardListFilter() {
|
|
||||||
public boolean addCard(Card c) {
|
|
||||||
return (0 < AllZone.HumanPlayer.predictDamage(c.getNetCombatDamage(),c,true) || c.getName().equals("Guiltfeeder"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (attackersLeft.isEmpty()) return combat;
|
|
||||||
|
|
||||||
// *******************
|
// *******************
|
||||||
// start of edits
|
// start of edits
|
||||||
// *******************
|
// *******************
|
||||||
@@ -289,7 +294,7 @@ public class ComputerUtil_Attack2 {
|
|||||||
|
|
||||||
candidateAttackers.add(pCard);
|
candidateAttackers.add(pCard);
|
||||||
if(pCard.getNetCombatDamage() > 0){
|
if(pCard.getNetCombatDamage() > 0){
|
||||||
candidateUnblockedDamage += CombatUtil.damageIfUnblocked(pCard,AllZone.HumanPlayer);
|
candidateUnblockedDamage += CombatUtil.damageIfUnblocked(pCard,AllZone.HumanPlayer,combat);
|
||||||
computerForces += 1;
|
computerForces += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +335,7 @@ public class ComputerUtil_Attack2 {
|
|||||||
}
|
}
|
||||||
// until the attackers are used up or the player would run out of life
|
// until the attackers are used up or the player would run out of life
|
||||||
int attackRounds = 1;
|
int attackRounds = 1;
|
||||||
while(attritionalAttackers.size() > 0 && playerLife > 0){
|
while(attritionalAttackers.size() > 0 && playerLife > 0 && attackRounds < 99){
|
||||||
// sum attacker damage
|
// sum attacker damage
|
||||||
int damageThisRound = 0;
|
int damageThisRound = 0;
|
||||||
for(int y = 0; y < attritionalAttackers.size(); y++){
|
for(int y = 0; y < attritionalAttackers.size(); y++){
|
||||||
@@ -367,7 +372,7 @@ public class ComputerUtil_Attack2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isUnblockableCreature){
|
if(isUnblockableCreature){
|
||||||
unblockableDamage += CombatUtil.damageIfUnblocked(attacker,AllZone.HumanPlayer);
|
unblockableDamage += CombatUtil.damageIfUnblocked(attacker,AllZone.HumanPlayer,combat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(unblockableDamage > 0){turnsUntilDeathByUnblockable = AllZone.HumanPlayer.life/unblockableDamage;}
|
if(unblockableDamage > 0){turnsUntilDeathByUnblockable = AllZone.HumanPlayer.life/unblockableDamage;}
|
||||||
@@ -426,7 +431,7 @@ public class ComputerUtil_Attack2 {
|
|||||||
|
|
||||||
//do assault (all creatures attack) if the computer would win the game
|
//do assault (all creatures attack) if the computer would win the game
|
||||||
//or if the computer has 4 creatures and the player has 1
|
//or if the computer has 4 creatures and the player has 1
|
||||||
else if(bAssault || (humanList.size() == 1 && 3 < attackers.size()))
|
else if(bAssault)
|
||||||
{
|
{
|
||||||
System.out.println("Assault");
|
System.out.println("Assault");
|
||||||
CardListUtil.sortAttack(attackersLeft);
|
CardListUtil.sortAttack(attackersLeft);
|
||||||
@@ -491,6 +496,8 @@ public class ComputerUtil_Attack2 {
|
|||||||
boolean isWorthLessThanAllKillers = true;
|
boolean isWorthLessThanAllKillers = true;
|
||||||
boolean canBeBlocked = false;
|
boolean canBeBlocked = false;
|
||||||
|
|
||||||
|
if (!isEffectiveAttacker(attacker,combat)) return false;
|
||||||
|
|
||||||
// look at the attacker in relation to the blockers to establish a number of factors about the attacking
|
// look at the attacker in relation to the blockers to establish a number of factors about the attacking
|
||||||
// context that will be relevant to the attackers decision according to the selected strategy
|
// context that will be relevant to the attackers decision according to the selected strategy
|
||||||
for (Card defender:defenders) {
|
for (Card defender:defenders) {
|
||||||
|
|||||||
Reference in New Issue
Block a user