mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
- More little improvements to AI attack decisions.
This commit is contained in:
@@ -483,22 +483,8 @@ public class CombatUtil {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
int flankingMagnitude = 0;
|
return totalDamageOfBlockers(attacker, list);
|
||||||
if(attacker.getKeyword().contains("Flanking")) flankingMagnitude = attacker.getAmountOfKeyword("Flanking");
|
|
||||||
|
|
||||||
for (Card c:list)
|
|
||||||
{
|
|
||||||
int flankingOffset = 0;
|
|
||||||
if (!c.getKeyword().contains("Flanking"))
|
|
||||||
flankingOffset = flankingMagnitude;
|
|
||||||
|
|
||||||
if (!isDoranInPlay())
|
|
||||||
i+= c.getNetAttack() - flankingOffset;
|
|
||||||
else
|
|
||||||
i+= c.getNetDefense() - flankingOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function take Doran and Double Strike into account
|
//This function take Doran and Double Strike into account
|
||||||
|
|||||||
@@ -69,23 +69,25 @@ public class ComputerUtil_Attack2 {
|
|||||||
//this checks to make sure that the computer player
|
//this checks to make sure that the computer player
|
||||||
//doesn't lose when the human player attacks
|
//doesn't lose when the human player attacks
|
||||||
//this method is used by getAttackers()
|
//this method is used by getAttackers()
|
||||||
public int blockersNeeded(Combat combat)
|
public CardList notNeededAsBlockers(CardList attackers, Combat combat)
|
||||||
{
|
{
|
||||||
CardListUtil.sortAttack(humanList);
|
CardList notNeededAsBlockers = new CardList(attackers.toArray());
|
||||||
int blockersNeeded = computerList.size();
|
CardListUtil.sortAttackLowFirst(attackers);
|
||||||
|
int blockersNeeded = attackers.size();
|
||||||
|
|
||||||
CardList list = getPossibleBlockers(computerList);
|
CardList list = getPossibleBlockers(attackers);
|
||||||
|
|
||||||
for(int i = 0; i < list.size(); i++) {
|
for(int i = 0; i < list.size(); i++) {
|
||||||
if(!doesHumanAttackAndWin(i)) {
|
if(!doesHumanAttackAndWin(i)) {
|
||||||
blockersNeeded= i;
|
blockersNeeded= i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else notNeededAsBlockers.remove(list.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockersNeeded == list.size()) {
|
if (blockersNeeded == list.size()) {
|
||||||
// Human will win unless everything is kept back to block
|
// Human will win unless everything is kept back to block
|
||||||
return blockersNeeded;
|
return notNeededAsBlockers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increase the total number of blockers needed by 1 if Finest Hour in play
|
// Increase the total number of blockers needed by 1 if Finest Hour in play
|
||||||
@@ -93,6 +95,7 @@ public class ComputerUtil_Attack2 {
|
|||||||
// In addition, if the computer guesses it needs no blockers, make sure that
|
// In addition, if the computer guesses it needs no blockers, make sure that
|
||||||
// it won't be surprised by Exalted
|
// it won't be surprised by Exalted
|
||||||
int humanExaltedBonus = countExaltedBonus(AllZone.HumanPlayer);
|
int humanExaltedBonus = countExaltedBonus(AllZone.HumanPlayer);
|
||||||
|
|
||||||
if (humanExaltedBonus > 0) {
|
if (humanExaltedBonus > 0) {
|
||||||
int nFinestHours = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer, "Finest Hour").size();
|
int nFinestHours = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer, "Finest Hour").size();
|
||||||
|
|
||||||
@@ -108,19 +111,24 @@ public class ComputerUtil_Attack2 {
|
|||||||
2 * humanBaseAttack: humanBaseAttack;
|
2 * humanBaseAttack: humanBaseAttack;
|
||||||
if ((AllZone.ComputerPlayer.getLife() - 3) <= totalExaltedAttack) {
|
if ((AllZone.ComputerPlayer.getLife() - 3) <= totalExaltedAttack) {
|
||||||
// We will lose if there is an Exalted attack -- keep one blocker
|
// We will lose if there is an Exalted attack -- keep one blocker
|
||||||
if (blockersNeeded == 0)
|
if (blockersNeeded == 0 && notNeededAsBlockers.size() > 0)
|
||||||
blockersNeeded++;
|
notNeededAsBlockers.remove(0);
|
||||||
|
|
||||||
// Finest Hour allows a second Exalted attack: keep a blocker for that too
|
// Finest Hour allows a second Exalted attack: keep a blocker for that too
|
||||||
if (nFinestHours > 0)
|
if (nFinestHours > 0 && notNeededAsBlockers.size() > 0)
|
||||||
blockersNeeded++;
|
notNeededAsBlockers.remove(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//re-add creatures with vigilance
|
||||||
|
for (Card c:attackers)
|
||||||
|
{
|
||||||
|
if (c.getKeyword().contains("Vigilance"))
|
||||||
|
notNeededAsBlockers.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (blockersNeeded > list.size())
|
return notNeededAsBlockers;
|
||||||
blockersNeeded = list.size();
|
|
||||||
return blockersNeeded;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//this uses a global variable, which isn't perfect
|
//this uses a global variable, which isn't perfect
|
||||||
@@ -162,17 +170,22 @@ public class ComputerUtil_Attack2 {
|
|||||||
|
|
||||||
Combat combat = new Combat();
|
Combat combat = new Combat();
|
||||||
|
|
||||||
|
CardList attackersLeft = new CardList(attackers.toArray());
|
||||||
|
|
||||||
//Atackers that don't really have a choice
|
//Atackers that don't really have a choice
|
||||||
for (int i=0; i<attackers.size();i++)
|
for (int i=0; i<attackersLeft.size();i++)
|
||||||
{
|
{
|
||||||
if ( (attackers.get(i).getKeyword().contains("CARDNAME attacks each turn if able.")
|
Card attacker = attackersLeft.get(i);
|
||||||
|| attackers.get(i).getKeyword().contains("At the beginning of the end step, destroy CARDNAME.")
|
if ( (attacker.getKeyword().contains("CARDNAME attacks each turn if able.")
|
||||||
|| attackers.get(i).getKeyword().contains("At the beginning of the end step, exile CARDNAME.")
|
|| attacker.getKeyword().contains("At the beginning of the end step, destroy CARDNAME.")
|
||||||
|| attackers.get(i).getKeyword().contains("At the beginning of the end step, sacrifice CARDNAME.")
|
|| attacker.getKeyword().contains("At the beginning of the end step, exile CARDNAME.")
|
||||||
|| attackers.get(i).getSacrificeAtEOT()
|
|| attacker.getKeyword().contains("At the beginning of the end step, sacrifice CARDNAME.")
|
||||||
|| attackers.get(i).getSirenAttackOrDestroy())
|
|| attacker.getSacrificeAtEOT()
|
||||||
&& CombatUtil.canAttack(attackers.get(i), combat))
|
|| attacker.getSirenAttackOrDestroy())
|
||||||
combat.addAttacker(attackers.get(i));
|
&& CombatUtil.canAttack(attacker, combat)) {
|
||||||
|
combat.addAttacker(attacker);
|
||||||
|
attackersLeft.remove(attacker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Exalted
|
//Exalted
|
||||||
@@ -184,10 +197,10 @@ public class ComputerUtil_Attack2 {
|
|||||||
{
|
{
|
||||||
int biggest = 0;
|
int biggest = 0;
|
||||||
Card att = null;
|
Card att = null;
|
||||||
for(int i=0; i<attackers.size();i++){
|
for(int i=0; i<attackersLeft.size();i++){
|
||||||
if (getAttack(attackers.get(i)) > biggest) {
|
if (getAttack(attackersLeft.get(i)) > biggest) {
|
||||||
biggest = getAttack(attackers.get(i));
|
biggest = getAttack(attackersLeft.get(i));
|
||||||
att = attackers.get(i);
|
att = attackersLeft.get(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (att!= null && CombatUtil.canAttack(att, combat))
|
if (att!= null && CombatUtil.canAttack(att, combat))
|
||||||
@@ -198,9 +211,9 @@ public class ComputerUtil_Attack2 {
|
|||||||
//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(doAssault() || (humanList.size() == 1 && 3 < attackers.size()))
|
else if(doAssault() || (humanList.size() == 1 && 3 < attackers.size()))
|
||||||
{
|
{
|
||||||
CardListUtil.sortAttack(attackers);
|
CardListUtil.sortAttack(attackersLeft);
|
||||||
for(int i = 0; i < attackers.size(); i++)
|
for(int i = 0; i < attackersLeft.size(); i++)
|
||||||
if (CombatUtil.canAttack(attackers.get(i), combat)) combat.addAttacker(attackers.get(i));
|
if (CombatUtil.canAttack(attackersLeft.get(i), combat)) combat.addAttacker(attackersLeft.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -209,40 +222,35 @@ public class ComputerUtil_Attack2 {
|
|||||||
//this should only happen 10% of the time when the computer
|
//this should only happen 10% of the time when the computer
|
||||||
//has at least 3 creatures
|
//has at least 3 creatures
|
||||||
boolean notAttack = (Math.abs(random.nextInt(100)) <= 10);
|
boolean notAttack = (Math.abs(random.nextInt(100)) <= 10);
|
||||||
if(notAttack && 3 <= attackers.size())
|
if(notAttack && 3 <= attackersLeft.size())
|
||||||
{
|
{
|
||||||
attackers.shuffle();
|
attackersLeft.shuffle();
|
||||||
attackers.remove(0);
|
attackersLeft.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//this has to be before the sorting below
|
//this has to be before the sorting below
|
||||||
//because this sorts attackers
|
//because this sorts attackers
|
||||||
int i = blockersNeeded(combat); //new
|
//int i = blockersNeeded(combat); //new
|
||||||
|
|
||||||
//so the biggest creature will usually attack
|
//so the biggest creature will usually attack
|
||||||
//I think this works, not sure, may have to change it
|
//I think this works, not sure, may have to change it
|
||||||
//sortNonFlyingFirst has to be done first, because it reverses everything
|
//sortNonFlyingFirst has to be done first, because it reverses everything
|
||||||
CardListUtil.sortNonFlyingFirst(attackers);
|
CardListUtil.sortNonFlyingFirst(attackersLeft);
|
||||||
CardListUtil.sortAttackLowFirst(attackers);
|
CardListUtil.sortAttackLowFirst(attackersLeft);
|
||||||
|
|
||||||
for (Card c:attackers)
|
|
||||||
{
|
|
||||||
if (c.getKeyword().contains("Vigilance"))
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
if (i < 0)
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for(; i < attackers.size(); i++)
|
attackersLeft = notNeededAsBlockers(attackersLeft, combat);
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < attackersLeft.size(); i++)
|
||||||
{
|
{
|
||||||
|
Card attacker = attackersLeft.get(i);
|
||||||
int totalFirstStrikeBlockPower = 0;
|
int totalFirstStrikeBlockPower = 0;
|
||||||
if (!attackers.get(i).hasFirstStrike() && !attackers.get(i).hasDoubleStrike())
|
if (!attacker.hasFirstStrike() && !attacker.hasDoubleStrike())
|
||||||
totalFirstStrikeBlockPower = CombatUtil.getTotalFirstStrikeBlockPower(attackers.get(i), AllZone.HumanPlayer);
|
totalFirstStrikeBlockPower = CombatUtil.getTotalFirstStrikeBlockPower(attacker, AllZone.HumanPlayer);
|
||||||
|
|
||||||
if ( shouldAttack(attackers.get(i),blockers, combat) && totalFirstStrikeBlockPower < attackers.get(i).getKillDamage()
|
if ( shouldAttack(attacker,blockers, combat) && totalFirstStrikeBlockPower < attacker.getKillDamage()
|
||||||
&& CombatUtil.canAttack(attackers.get(i), combat))
|
&& CombatUtil.canAttack(attacker, combat))
|
||||||
combat.addAttacker(attackers.get(i));
|
combat.addAttacker(attacker);
|
||||||
|
|
||||||
}
|
}
|
||||||
}//getAttackers()
|
}//getAttackers()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user