Skip to content

Commit

Permalink
AI, combat: fixed that computer safely blocks the weakest creature in…
Browse files Browse the repository at this point in the history
…stead most powerfull
  • Loading branch information
JayDi85 committed Dec 22, 2024
1 parent 89b2509 commit 1387886
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ private void declareBlockers(Game game, UUID activePlayerId) {
return;
}

CombatUtil.sortByPower(attackers, false);
CombatUtil.sortByPower(attackers, false); // most powerfull go to first

CombatInfo combatInfo = CombatUtil.blockWithGoodTrade2(game, attackers, possibleBlockers);
Player player = game.getPlayer(playerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static List<Permanent> canKillOpponent(Game game, List<Permanent> attacke
}
}

sortByPower(blockableAttackers, true);
sortByPower(blockableAttackers, false); // most powerfull go to first

// imagine that most powerful will be blocked as 1-vs-1
List<Permanent> attackersThatWontBeBlocked = new ArrayList<>(blockableAttackers);
Expand Down Expand Up @@ -87,9 +87,9 @@ public static void sortByPower(List<Permanent> permanents, final boolean ascendi
@Override
public int compare(Permanent o1, Permanent o2) {
if (ascending) {
return o2.getPower().getValue() - o1.getPower().getValue();
} else {
return o1.getPower().getValue() - o2.getPower().getValue();
} else {
return o2.getPower().getValue() - o1.getPower().getValue();
}
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package org.mage.test.AI.basic;

import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;

/**
* @author JayDi85
*/
public class BlockSimulationAITest extends CardTestPlayerBaseWithAIHelps {

@Test
public void test_Block_1_small_attacker_vs_1_big_blocker() {
addCard(Zone.BATTLEFIELD, playerA, "Arbor Elf", 1); // 1/1
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 1); // 2/2

attack(1, playerA, "Arbor Elf");

// ai must block
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Arbor Elf", 1);
}

@Test
public void test_Block_1_small_attacker_vs_2_big_blockers() {
addCard(Zone.BATTLEFIELD, playerA, "Arbor Elf", 1); // 1/1
addCard(Zone.BATTLEFIELD, playerB, "Balduvian Bears", 2); // 2/2

attack(1, playerA, "Arbor Elf");

// ai must block
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Arbor Elf", 1);
}

@Test
public void test_Block_1_small_attacker_vs_1_small_blocker() {
addCard(Zone.BATTLEFIELD, playerA, "Arbor Elf", 1); // 1/1
addCard(Zone.BATTLEFIELD, playerB, "Arbor Elf", 1); // 1/1

attack(1, playerA, "Arbor Elf");

// ai must block
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Arbor Elf", 1);
assertGraveyardCount(playerB, "Arbor Elf", 1);
}

@Test
public void test_Block_1_big_attacker_vs_1_small_blocker() {
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
addCard(Zone.BATTLEFIELD, playerB, "Arbor Elf", 1); // 1/1

attack(1, playerA, "Balduvian Bears");

// ai must not block
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20 - 2);
assertGraveyardCount(playerA, "Balduvian Bears", 0);
assertGraveyardCount(playerB, "Arbor Elf", 0);
}

@Test
public void test_Block_2_big_attackers_vs_1_small_blocker() {
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
addCard(Zone.BATTLEFIELD, playerA, "Deadbridge Goliath", 1); // 5/5
addCard(Zone.BATTLEFIELD, playerB, "Arbor Elf", 1); // 1/1

attack(1, playerA, "Balduvian Bears");
attack(1, playerA, "Deadbridge Goliath");

// ai must not block
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20 - 2 - 5);
assertGraveyardCount(playerA, "Balduvian Bears", 0);
assertGraveyardCount(playerA, "Deadbridge Goliath", 0);
assertGraveyardCount(playerB, "Arbor Elf", 0);
}

@Test
public void test_Block_2_big_attackers_vs_1_big_blocker_a() {
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
addCard(Zone.BATTLEFIELD, playerA, "Deadbridge Goliath", 1); // 5/5
addCard(Zone.BATTLEFIELD, playerB, "Colossal Dreadmaw", 1); // 6/6

attack(1, playerA, "Balduvian Bears");
attack(1, playerA, "Deadbridge Goliath");

// ai must block bigger attacker and survive (6/6 must block 5/5)
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20 - 2);
assertGraveyardCount(playerA, "Balduvian Bears", 0);
assertGraveyardCount(playerA, "Deadbridge Goliath", 1);
assertGraveyardCount(playerB, "Colossal Dreadmaw", 0);
}

@Test
public void test_Block_2_big_attackers_vs_1_big_blocker_b() {
addCard(Zone.BATTLEFIELD, playerA, "Arbor Elf", 1); // 1/1
addCard(Zone.BATTLEFIELD, playerA, "Balduvian Bears", 1); // 2/2
addCard(Zone.BATTLEFIELD, playerA, "Deadbridge Goliath", 1); // 5/5
addCard(Zone.BATTLEFIELD, playerA, "Colossal Dreadmaw", 1); // 6/6
//
addCard(Zone.BATTLEFIELD, playerB, "Spectral Bears", 1); // 3/3

attack(1, playerA, "Arbor Elf");
attack(1, playerA, "Balduvian Bears");
attack(1, playerA, "Deadbridge Goliath");
attack(1, playerA, "Colossal Dreadmaw");

// ai must block bigger attacker and survive (3/3 must block 2/2)
aiPlayStep(1, PhaseStep.DECLARE_BLOCKERS, playerB);

setStopAt(1, PhaseStep.END_TURN);
setStrictChooseMode(true);
execute();

assertLife(playerA, 20);
assertLife(playerB, 20 - 1 - 5 - 6);
assertGraveyardCount(playerA, "Balduvian Bears", 1);
assertPermanentCount(playerB, "Spectral Bears", 1);
}

// TODO: add tests for DeathtouchAbility
// TODO: add tests for FirstStrikeAbility
// TODO: add tests for DoubleStrikeAbility
// TODO: add tests for IndestructibleAbility
// TODO: add tests for FlyingAbility
// TODO: add tests for ReachAbility
// TODO: add tests for ExaltedAbility???
}

0 comments on commit 1387886

Please sign in to comment.