fight unit tests
~1.25h work
This commit is contained in:
parent
37d9f84787
commit
69cb4417fd
@ -15,4 +15,13 @@ public class Pair<T, U> {
|
|||||||
|
|
||||||
public T left() { return this.left; };
|
public T left() { return this.left; };
|
||||||
public U right() { return this.right; };
|
public U right() { return this.right; };
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o instanceof Pair<?,?>) {
|
||||||
|
return left.equals(((Pair<?, ?>) o).left) && right.equals(((Pair<?, ?>) o).right);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.equals(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,15 +12,15 @@ import java.util.List;
|
|||||||
public class Battle {
|
public class Battle {
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
private enum ElementMod {
|
enum ElementMod {
|
||||||
HALF(0.5),
|
HALF(0.5),
|
||||||
NONE(1),
|
NONE(1),
|
||||||
DOUBLE(2);
|
DOUBLE(2);
|
||||||
|
|
||||||
public final double percentMod;
|
public final double percentMod;
|
||||||
}
|
}
|
||||||
private record FightDTO(Combatant player, Card card) {};
|
record FightDTO(Combatant player, Card card) {};
|
||||||
private record RoundResult(FightDTO winner, FightDTO loser, boolean draw, ElementMod winnerMod, ElementMod loserMod) {};
|
record RoundResult(FightDTO winner, FightDTO loser, boolean draw, ElementMod winnerMod, ElementMod loserMod) {};
|
||||||
private Pair<Combatant, Combatant> combatants;
|
private Pair<Combatant, Combatant> combatants;
|
||||||
@Getter
|
@Getter
|
||||||
private volatile List<String> log = new ArrayList<>();
|
private volatile List<String> log = new ArrayList<>();
|
||||||
@ -50,7 +50,7 @@ public class Battle {
|
|||||||
this.combatants.right().updateStats(!leftWins);
|
this.combatants.right().updateStats(!leftWins);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void playRound(int round) {
|
void playRound(int round) {
|
||||||
RoundResult result = this.fight(
|
RoundResult result = this.fight(
|
||||||
new FightDTO(
|
new FightDTO(
|
||||||
this.combatants.left(),
|
this.combatants.left(),
|
||||||
@ -74,7 +74,7 @@ public class Battle {
|
|||||||
result.loser().card());
|
result.loser().card());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isImmune(Card defend, Card attack) {
|
static boolean isImmune(Card defend, Card attack) {
|
||||||
if (defend.name().equals("Dragon") && attack.name().endsWith("Goblin")) return true;
|
if (defend.name().equals("Dragon") && attack.name().endsWith("Goblin")) return true;
|
||||||
if (defend.name().equals("Wizzard") && attack.name().equals("Ork")) return true;
|
if (defend.name().equals("Wizzard") && attack.name().equals("Ork")) return true;
|
||||||
if (defend.name().equals("WaterSpell") && attack.name().equals("Knight")) return true;
|
if (defend.name().equals("WaterSpell") && attack.name().equals("Knight")) return true;
|
||||||
@ -84,7 +84,7 @@ public class Battle {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Element {
|
enum Element {
|
||||||
NORMAL,
|
NORMAL,
|
||||||
FIRE,
|
FIRE,
|
||||||
WATER;
|
WATER;
|
||||||
@ -105,7 +105,7 @@ public class Battle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<ElementMod, ElementMod> getElementMod(Card left, Card right) {
|
static Pair<ElementMod, ElementMod> getElementMod(Card left, Card right) {
|
||||||
Pair<ElementMod, ElementMod> returnMods = new Pair<>(ElementMod.NONE, ElementMod.NONE);
|
Pair<ElementMod, ElementMod> returnMods = new Pair<>(ElementMod.NONE, ElementMod.NONE);
|
||||||
|
|
||||||
if (!left.name().endsWith("Spell") && !right.name().endsWith("Spell")) return returnMods;
|
if (!left.name().endsWith("Spell") && !right.name().endsWith("Spell")) return returnMods;
|
||||||
@ -130,13 +130,13 @@ public class Battle {
|
|||||||
return returnMods;
|
return returnMods;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RoundResult fight(FightDTO left, FightDTO right) {
|
static RoundResult fight(FightDTO left, FightDTO right) {
|
||||||
if (this.isImmune(left.card(), right.card())) return new RoundResult(left, right, false, ElementMod.NONE, ElementMod.NONE);
|
if (isImmune(left.card(), right.card())) return new RoundResult(left, right, false, ElementMod.NONE, ElementMod.NONE);
|
||||||
if (this.isImmune(right.card(), left.card())) return new RoundResult(right, left, false, ElementMod.NONE, ElementMod.NONE);
|
if (isImmune(right.card(), left.card())) return new RoundResult(right, left, false, ElementMod.NONE, ElementMod.NONE);
|
||||||
|
|
||||||
Pair<ElementMod, ElementMod> dmgMods = getElementMod(left.card(), right.card());
|
Pair<ElementMod, ElementMod> dmgMods = getElementMod(left.card(), right.card());
|
||||||
|
|
||||||
boolean leftWins = left.card().damage()*dmgMods.left().percentMod > right.card().damage()*dmgMods.right().percentMod;
|
boolean leftWins = left.card().damage()*dmgMods.left().percentMod >= right.card().damage()*dmgMods.right().percentMod;
|
||||||
return new RoundResult(
|
return new RoundResult(
|
||||||
leftWins ? left : right,
|
leftWins ? left : right,
|
||||||
leftWins ? right : left,
|
leftWins ? right : left,
|
||||||
@ -145,7 +145,7 @@ public class Battle {
|
|||||||
leftWins ? dmgMods.right() : dmgMods.left());
|
leftWins ? dmgMods.right() : dmgMods.left());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createCombatString(int round, RoundResult result) {
|
static String createCombatString(int round, RoundResult result) {
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
stringBuilder
|
stringBuilder
|
||||||
.append(round)
|
.append(round)
|
||||||
|
|||||||
117
src/test/java/at/nanopenguin/mtcg/application/BattleTest.java
Normal file
117
src/test/java/at/nanopenguin/mtcg/application/BattleTest.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
package at.nanopenguin.mtcg.application;
|
||||||
|
|
||||||
|
import at.nanopenguin.mtcg.Pair;
|
||||||
|
import at.nanopenguin.mtcg.application.service.schemas.Card;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
public class BattleTest {
|
||||||
|
private static Card cardWithName(String name) {
|
||||||
|
Card cardMock = Mockito.mock(Card.class);
|
||||||
|
Mockito.when(cardMock.name()).thenReturn(name);
|
||||||
|
return cardMock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Card cardWithNameAndDmg(String name, float dmg) {
|
||||||
|
Card cardMock = Mockito.mock(Card.class);
|
||||||
|
Mockito.when(cardMock.name()).thenReturn(name);
|
||||||
|
Mockito.when(cardMock.damage()).thenReturn(dmg);
|
||||||
|
return cardMock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"WaterGoblin, FireSpell, DOUBLE, HALF", // generic
|
||||||
|
"FireGoblin, NormalSpell, DOUBLE, HALF",
|
||||||
|
"NormalGoblin, WaterSpell, DOUBLE, HALF",
|
||||||
|
"FireGoblin, WaterSpell, HALF, DOUBLE", // generic reverse
|
||||||
|
"NormalGoblin, FireSpell, HALF, DOUBLE",
|
||||||
|
"WaterGoblin, NormalSpell, HALF, DOUBLE",
|
||||||
|
"WaterGoblin, FireTroll, NONE, NONE", // no spell
|
||||||
|
"WaterSpell, FireSpell, DOUBLE, HALF", // two spells
|
||||||
|
"FireGoblin, FireSpell, NONE, NONE", // same element
|
||||||
|
"FireSpell, Dragon, DOUBLE, HALF" // non elemental
|
||||||
|
})
|
||||||
|
void elementMods(String name1, String name2, Battle.ElementMod expectedMod1, Battle.ElementMod expectedMod2){
|
||||||
|
Card card1 = cardWithName(name1);
|
||||||
|
Card card2 = cardWithName(name2);
|
||||||
|
|
||||||
|
Assertions.assertEquals(new Pair<>(expectedMod1, expectedMod2), Battle.getElementMod(card1, card2));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"Dragon, FireGoblin, true",
|
||||||
|
"Dragon, WaterGoblin, true",
|
||||||
|
"Dragon, NormalGoblin, true",
|
||||||
|
"WaterGoblin, Dragon, false",
|
||||||
|
"Wizzard, Ork, true",
|
||||||
|
"Ork, Wizzard, false",
|
||||||
|
"WaterSpell, Knight, true",
|
||||||
|
"FireSpell, Knight, false",
|
||||||
|
"Knight, WaterSpell, false",
|
||||||
|
"Kraken, WaterSpell, true",
|
||||||
|
"Kraken, FireSpell, true",
|
||||||
|
"FireElf, Dragon, true",
|
||||||
|
"NormalElf, Dragon, false"
|
||||||
|
})
|
||||||
|
void immunityTest(String name1, String name2, boolean expected) {
|
||||||
|
Card card1 = cardWithName(name1);
|
||||||
|
Card card2 = cardWithName(name2);
|
||||||
|
|
||||||
|
Assertions.assertEquals(expected, Battle.isImmune(card1, card2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Battle.FightDTO getFightDTO(String cardName, float dmg) {
|
||||||
|
Battle.FightDTO fightDTOmock = Mockito.mock(Battle.FightDTO.class);
|
||||||
|
Card cardMock = cardWithNameAndDmg(cardName, dmg);
|
||||||
|
Mockito.when(fightDTOmock.card()).thenReturn(cardMock);
|
||||||
|
return fightDTOmock;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fightOutcome {
|
||||||
|
LEFT_WINS,
|
||||||
|
DRAW,
|
||||||
|
RIGHT_WINS
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"WaterGoblin, 10, FireTroll, 15, RIGHT_WINS, NONE, NONE",
|
||||||
|
"FireTroll, 15, WaterGoblin, 10, LEFT_WINS, NONE, NONE",
|
||||||
|
"FireSpell, 10, WaterSpell, 20, RIGHT_WINS, DOUBLE, HALF",
|
||||||
|
"FireSpell, 20, WaterSpell, 5, DRAW, HALF, DOUBLE",
|
||||||
|
"FireSpell, 90, WaterSpell, 5, LEFT_WINS, HALF, DOUBLE",
|
||||||
|
"FireSpell, 10, WaterGoblin, 10, RIGHT_WINS, DOUBLE, HALF",
|
||||||
|
"WaterSpell, 10, WaterGoblin, 10, DRAW, NONE, NONE",
|
||||||
|
"RegularSpell, 10, WaterGoblin, 10, LEFT_WINS, DOUBLE, HALF",
|
||||||
|
"RegularSpell, 10, Knight, 15, RIGHT_WINS, NONE, NONE",
|
||||||
|
})
|
||||||
|
void fightTest(String card1, float dmg1, String card2, float dmg2, fightOutcome outcome, Battle.ElementMod expectedMod1, Battle.ElementMod expectedMod2) {
|
||||||
|
Battle.FightDTO fightDTO1 = getFightDTO(card1, dmg1);
|
||||||
|
Battle.FightDTO fightDTO2 = getFightDTO(card2, dmg2);
|
||||||
|
|
||||||
|
Battle.RoundResult result = Battle.fight(fightDTO1, fightDTO2);
|
||||||
|
|
||||||
|
switch (outcome) {
|
||||||
|
case LEFT_WINS -> {
|
||||||
|
Assertions.assertEquals(fightDTO1, result.winner());
|
||||||
|
Assertions.assertFalse(result.draw());
|
||||||
|
}
|
||||||
|
case DRAW -> {
|
||||||
|
Assertions.assertTrue(result.draw());
|
||||||
|
}
|
||||||
|
case RIGHT_WINS -> {
|
||||||
|
Assertions.assertEquals(fightDTO2, result.winner());
|
||||||
|
Assertions.assertFalse(result.draw());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assertions.assertEquals(expectedMod1, result.winnerMod());
|
||||||
|
Assertions.assertEquals(expectedMod2, result.loserMod());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user