update
This commit is contained in:
@@ -12,6 +12,8 @@ func check(cond: bool, msg: String) -> void:
|
||||
else:
|
||||
failed += 1
|
||||
printerr("FEHLER: " + msg)
|
||||
print("%d Prüfungen bestanden, Abbruch beim ersten Fehler" % passed)
|
||||
quit(1)
|
||||
|
||||
|
||||
func C(id: String) -> Cards.Card:
|
||||
@@ -55,6 +57,7 @@ func _initialize() -> void:
|
||||
test_kombos()
|
||||
test_mana_und_kosten()
|
||||
test_ziehen()
|
||||
test_abwerfen()
|
||||
test_wesen_und_angriff()
|
||||
test_elementvorteil()
|
||||
test_verdeckt()
|
||||
@@ -129,64 +132,44 @@ func test_mana_und_kosten() -> void:
|
||||
h.energy = 5
|
||||
check(g.play_card(h, h.hand[0]) == "" and h.energy == 5 - C("f_wolf").cost, "Ausspielen kostet die Kartenkosten")
|
||||
check(g.can_play(h, h.hand[0])[1] == "Nicht genug Mana", "Drache (5) zu teuer bei %d Mana" % h.energy)
|
||||
check(Cards.fusion_value(4, 2) == 5 and Cards.fusion_value(8, 1) == 9 and Cards.fusion_value(2, 2) == 3 and Cards.fusion_value(0, 4) == 4 and Cards.fusion_value(8, 8) == 11, "Fusionswert: besserer Wert plus ein Drittel des schwächeren")
|
||||
check(Cards.fusion_value(4, 2) == 5 and Cards.fusion_value(8, 1) == 9 and Cards.fusion_value(2, 2) == 3 and Cards.fusion_value(0, 4) == 5 and Cards.fusion_value(8, 8) == 11, "Fusionswert: besserer Wert plus ein Drittel des schwächeren, mindestens 1")
|
||||
|
||||
|
||||
## Start: fünf im ersten Zug bezahlbare Karten, keine Wahl. Jeder Zug beginnt mit einer Karte;
|
||||
## Ziehen: 2 Mana, eine weitere bezahlbare Karte vom Stapel.
|
||||
## Start: fünf im ersten Zug bezahlbare Karten, drei offene auf dem Stapel. Ziehen: eine der drei
|
||||
## wählen, eine neue rückt nach; das erste Ziehen im Zug ist frei, jedes weitere kostet 2 Mana.
|
||||
func test_ziehen() -> void:
|
||||
var r := RandomNumberGenerator.new()
|
||||
r.seed = 1
|
||||
var g := Game.new_battle(r)
|
||||
check(g.deck.size() == Cards.all().size() * DeckGen.COPIES - 2 * Game.START_HAND, "Stapel: jede Karte dreimal, zehn schon ausgegeben")
|
||||
check(g.deck.size() == Cards.all().size() * DeckGen.COPIES - 2 * (Game.START_HAND + Game.OFFER), "Stapel: jede Karte dreimal, Hände und Angebote schon ausgegeben")
|
||||
for p in g.players:
|
||||
check(p.hand.size() == Game.START_HAND, "Start: fünf Karten auf der Hand")
|
||||
check(p.hand.all(func(c): return c.cost <= Game.START_MANA), "nur Karten, die im ersten Zug spielbar sind")
|
||||
check(p.hand.all(func(c): return c != Cards.by_id(c.id)), "eigene Exemplare")
|
||||
check(p.offer.size() == Game.OFFER and p.offer.all(func(c): return c.cost <= Game.START_MANA), "drei offene Karten auf dem Stapel, alle bezahlbar")
|
||||
var first: Game.Player = g.current()
|
||||
check(g.draw(first) == "Deine Hand ist voll", "fünf Handkarten sind das Limit")
|
||||
first.hand.pop_back()
|
||||
check(g.draw(first) == "Nicht genug Mana", "im ersten Zug reicht das Mana nicht zum Ziehen")
|
||||
first.energy = 3
|
||||
first.max_energy = 3
|
||||
var mana := first.energy
|
||||
var wanted: Cards.Card = first.offer[1]
|
||||
var deck_before := g.deck.size()
|
||||
check(g.draw(first) == "" and first.energy == mana - Game.DRAW_COST and first.hand.size() == Game.START_HAND, "gezogen: 2 Mana, eine Karte")
|
||||
check(first.hand.back().cost <= first.max_energy and g.deck.size() == deck_before - 1, "bezahlbar; zu teure liegen wieder unten im Stapel")
|
||||
first.energy = 0
|
||||
check(g.draw_cost(first) == 0 and g.draw(first, 1) == "" and first.energy == Game.START_MANA and first.hand.back().id == wanted.id, "erstes Ziehen frei: die gewählte Karte kommt auf die Hand")
|
||||
check(first.offer.size() == Game.OFFER and first.offer[1] != wanted and first.offer[1].cost <= first.max_energy and g.deck.size() == deck_before - 1, "eine bezahlbare neue Karte rückt an die Stelle")
|
||||
first.hand.pop_back()
|
||||
check(g.draw(first) == "Nicht genug Mana", "ohne Mana kein Ziehen")
|
||||
check(g.draw_cost(first) == Game.DRAW_COST and g.draw(first) == "Nicht genug Mana", "zweites Ziehen kostet 2, im ersten Zug zu teuer")
|
||||
first.energy = 3
|
||||
check(g.draw(first, 0) == "" and first.energy == 3 - Game.DRAW_COST, "mit Mana: 2 bezahlt")
|
||||
var second: Game.Player = g.enemy_of(first)
|
||||
check(g.draw(second) == "Nicht dein Zug", "nur im eigenen Zug")
|
||||
# Leerer Stapel wird neu gemischt
|
||||
g.deck = []
|
||||
first.hand.pop_back()
|
||||
first.energy = 3
|
||||
check(g.draw(first) == "" and g.deck.size() > 0 and g.log.any(func(l): return l.begins_with("Der Stapel wird neu gemischt")), "leerer Stapel: neu gemischt")
|
||||
# Mit viel Mana tauchen auch teure Karten auf
|
||||
first.max_energy = 20
|
||||
first.energy = 20
|
||||
var seen_expensive := false
|
||||
for i in 12:
|
||||
first.hand = []
|
||||
first.energy = 20
|
||||
g.draw(first)
|
||||
if first.hand[0].cost > 5:
|
||||
seen_expensive = true
|
||||
check(seen_expensive, "mit 20 Mana kommen auch teure Karten")
|
||||
# Zugbeginn: eine Karte gratis, solange die Hand nicht voll ist
|
||||
var g5 := Game.new_battle(r)
|
||||
var p1: Game.Player = g5.current()
|
||||
var p2: Game.Player = g5.enemy_of(p1)
|
||||
g5.end_turn()
|
||||
check(p2.hand.size() == Game.START_HAND, "volle Hand: zu Zugbeginn kommt nichts")
|
||||
p2.hand.pop_back()
|
||||
p2.hand.pop_back()
|
||||
g5.end_turn()
|
||||
p1.hand.pop_back()
|
||||
g5.end_turn()
|
||||
check(p2.hand.size() == Game.START_HAND - 1 and p2.hand.back().cost <= p2.max_energy, "Zugbeginn: eine bezahlbare Karte gezogen")
|
||||
g5.end_turn()
|
||||
check(p1.hand.size() == Game.START_HAND, "auch der Startspieler zieht zu Zugbeginn")
|
||||
# Nächster Zug: nichts kommt von selbst, das erste Ziehen ist wieder frei
|
||||
var hand_now := first.hand.size()
|
||||
g.end_turn()
|
||||
g.end_turn()
|
||||
check(g.current() == first and first.hand.size() == hand_now and g.draw_cost(first) == 0, "neuer Zug: keine Karte von selbst, das erste Ziehen wieder frei")
|
||||
|
||||
|
||||
## Gelegte Wesen greifen erst im nächsten Zug an; kein Durchschlag, keine Heilung zu Zugbeginn.
|
||||
@@ -243,6 +226,20 @@ func test_elementvorteil() -> void:
|
||||
var t3 := put(s3[2], "w_tiefen")
|
||||
s3[0].attack(w3, t3)
|
||||
check(t3.health == 6 - 2 and w3.health == 2 - 5, "Feuer gegen Wasser: 1 weniger Schaden, der Konter macht 1 mehr")
|
||||
# 0 Angriff: nur mit Elementvorteil geht etwas
|
||||
var s4 := setup()
|
||||
var funke := put(s4[1], "f_funke") # Feuer 0/2
|
||||
var hauch := put(s4[2], "l_hauch") # Luft 0/2
|
||||
var wall := put(s4[2], "e_wall") # Erde 0/4
|
||||
check(s4[0].can_attack(funke, wall)[1] == "Glutfunke würde keinen Schaden machen", "0 Angriff ohne Vorteil: kein Angriff")
|
||||
check(s4[0].attack(funke, hauch) == "" and hauch.health == 1 and funke.health == 2, "0 Angriff mit Vorteil: 1 Schaden, kein Konter")
|
||||
var s5 := setup()
|
||||
var hauch2 := put(s5[1], "l_hauch")
|
||||
var funke2 := put(s5[2], "f_funke")
|
||||
check(s5[0].attack(hauch2, funke2) == "Windhauch würde keinen Schaden machen" and funke2.health == 2, "im Nachteil nichts")
|
||||
var wall2 := put(s5[2], "e_wall")
|
||||
var geist5 := put(s5[1], "w_geist") # Wasser 2/2
|
||||
check(s5[0].attack(geist5, wall2) == "" and wall2.health == 4 - 1 and geist5.health == 2 - 1, "Steinwall kontert mit Elementvorteil für 1")
|
||||
var s2 := setup()
|
||||
var g2: Game = s2[0]
|
||||
var geist := put(s2[1], "w_geist") # Wasser 2/2
|
||||
@@ -286,46 +283,52 @@ func test_verdeckt() -> void:
|
||||
|
||||
|
||||
## Elementboni: zwei eigene offene Wesen eines Elements geben den Sondereffekt (Erde Spott, Luft
|
||||
## Flink, Wasser Regeneration, Feuer Doppelschlag); drei auf dem Tisch geben dem Element +1/+1.
|
||||
## Flink, Wasser Regeneration, Feuer Doppelschlag); je 10 Mana an ausgespielten Karten eines Elements geben
|
||||
## den eigenen Wesen des Elements +1 Angriff. Jeder Spieler zählt für sich.
|
||||
func test_elementboni() -> void:
|
||||
var s := setup()
|
||||
var s := setup(["f_asche", "f_ritter"])
|
||||
var g: Game = s[0]
|
||||
var h: Game.Player = s[1]
|
||||
var o: Game.Player = s[2]
|
||||
var fire := [put(h, "f_wolf"), put(h, "f_kobold")]
|
||||
var bird := put(o, "l_wind") # Luft 1/1
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 0 and fire[1].aura == 0, "zwei reichen nicht für +1/+1")
|
||||
check(fire[0].aura == 0 and int(h.played["Feuer"]) == 0, "nur gelegt, nicht ausgespielt: kein Bonus")
|
||||
check(fire[0].has("Doppelschlag") and fire[0].attacks_per_turn() == 2 and fire[0].keywords() == ["Doppelschlag"], "zwei eigene Feuer: Doppelschlag für beide")
|
||||
var hidden_fire := put(o, "f_asche", true, true)
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 0 and g.element_counts()["Feuer"] == 2 and not hidden_fire.has("Doppelschlag"), "verdeckte zählen nicht und bekommen nichts")
|
||||
var third := put(o, "f_ritter") # Feuer beim Gegner zählt für den Tisch
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 1 and fire[0].power() == 4 and fire[0].health == 3 and third.aura == 1, "drei Feuer auf dem Tisch: +1/+1 für alle Feuerwesen")
|
||||
check(bird.aura == 0 and bird.health == 1, "kein Malus für das geschlagene Element")
|
||||
check(not third.has("Doppelschlag"), "der Gegner hat nur ein offenes Feuer: kein Sondereffekt")
|
||||
check(not hidden_fire.has("Doppelschlag") and o.element_count("Feuer") == 0, "verdeckte zählen nicht fürs Paar")
|
||||
# Ausgespielte Karten zählen; je vier gibt es +1 Angriff für die eigenen Wesen des Elements
|
||||
h.played["Feuer"] = 7
|
||||
g.play_card(h, h.hand[0]) # Aschekrieger für 3: macht 10 Mana voll
|
||||
check(int(h.played["Feuer"]) == 10 and fire[0].aura == 1 and fire[0].power() == 4 and fire[0].health == 2 and h.board[2].aura == 1, "10 Mana Feuer ausgespielt: +1 Angriff für alle eigenen Feuerwesen, Leben bleibt")
|
||||
check(bird.aura == 0 and bird.health == 1 and hidden_fire.aura == 0, "der Gegner zählt für sich: nichts")
|
||||
g._flip(hidden_fire)
|
||||
check(hidden_fire.aura == 1 and third.has("Doppelschlag") and hidden_fire.has("Doppelschlag"), "aufgedeckt zählt es sofort: Bonus und Paar")
|
||||
fire[0].health = 1
|
||||
o.board.erase(third)
|
||||
o.board.erase(hidden_fire)
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 0 and fire[0].max_health == 2 and fire[0].health == 1 and fire[1].health == 1, "Bonus geht wieder: nur das Höchstleben sinkt, Leben wird höchstens gekappt")
|
||||
check(hidden_fire.aura == 0 and int(o.played["Feuer"]) == 0, "aufgedeckt, aber nie ausgespielt gezählt: kein Bonus")
|
||||
g.play_card(h, h.hand[0], true) # Ritter verdeckt
|
||||
var secret: Game.Creature = h.board.back()
|
||||
check(secret.hidden and secret.aura == 0 and int(h.played["Feuer"]) == 13, "verdeckt gelegt zählt als ausgespielt, der Bonus kommt erst offen")
|
||||
g._flip(secret)
|
||||
check(secret.aura == 1 and secret.power() == 5 and secret.health == 3, "aufgedeckt kommt der Bonus")
|
||||
# Vorschau
|
||||
check(g.forecast(h, C("f_asche")) == 1 and g.forecast(h, C("l_wind")) == 0, "Vorschau: Feuer würde den Stapel voll machen")
|
||||
h.played["Luft"] = 9
|
||||
check(g.forecast(h, C("l_wind")) == 1 and g.forecast(h, C("w_geist")) == 0, "Vorschau: der Windgeist macht 10 Mana Luft voll und bekäme +1")
|
||||
# Merkmal: doppelt
|
||||
h.perks = ["element_doppelt"]
|
||||
put(h, "f_asche")
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 2 and fire[0].power() == 5, "Elementbonus zählt doppelt")
|
||||
h.perks = []
|
||||
h.played["Feuer"] = 20
|
||||
g.apply_auras()
|
||||
check(fire[0].aura == 2 and fire[0].power() == 5 and fire[0].max_health == 2, "20 Mana Feuer: +2 Angriff")
|
||||
# Die anderen Paare
|
||||
var walls := [put(h, "e_wall"), put(h, "e_wall")]
|
||||
check(walls[0].has("Spott") and not fire[0].has("Spott"), "zwei Erde: Spott nur für Erdwesen")
|
||||
var winds := [put(h, "l_wind", false), put(h, "l_wind", false)]
|
||||
var s5 := setup()
|
||||
var walls := [put(s5[1], "e_wall"), put(s5[1], "e_wall")]
|
||||
check(walls[0].has("Spott") and not put(s5[1], "f_wolf").has("Spott"), "zwei Erde: Spott nur für Erdwesen")
|
||||
var winds := [put(s5[1], "l_wind", false), put(s5[1], "l_wind", false)]
|
||||
check(winds[0].has("Flink") and winds[0].can_attack(), "zwei Luft: Flink, frisch gelegt greift an")
|
||||
var geister := [put(h, "w_geist"), put(h, "w_geist")]
|
||||
var s6 := setup()
|
||||
var geister := [put(s6[1], "w_geist"), put(s6[1], "w_geist")]
|
||||
check(geister[0].has("Regeneration"), "zwei Wasser: Regeneration")
|
||||
# Verschmolzene Wesen zählen für beide Elemente und bekommen beide Effekte und Boni
|
||||
var s2 := setup()
|
||||
@@ -338,10 +341,25 @@ func test_elementboni() -> void:
|
||||
g2.apply_auras()
|
||||
check(dampf.has("Doppelschlag") and dampf.has("Regeneration") and dampf.keywords() == ["Regeneration", "Doppelschlag"], "Dampf hat beide Sondereffekte")
|
||||
check(fw.has("Doppelschlag") and ww.has("Regeneration"), "und zählt für beide Paare")
|
||||
put(s2[2], "f_asche")
|
||||
put(s2[2], "w_reiter")
|
||||
h2.played["Feuer"] = 10
|
||||
h2.played["Wasser"] = 10
|
||||
g2.apply_auras()
|
||||
check(dampf.aura == 2 and fw.aura == 1 and ww.aura == 1, "drei Feuer und drei Wasser: Dampf bekommt +2/+2")
|
||||
check(dampf.aura == 2 and fw.aura == 1 and ww.aura == 1, "10 Mana Feuer und 10 Mana Wasser: Dampf bekommt +2 Angriff")
|
||||
|
||||
|
||||
## Abwerfen: eine Handkarte loswerden, dafür 1 Mana.
|
||||
func test_abwerfen() -> void:
|
||||
var s := setup(["f_wolf", "f_kobold"])
|
||||
var g: Game = s[0]
|
||||
var h: Game.Player = s[1]
|
||||
var o: Game.Player = s[2]
|
||||
var card: Cards.Card = h.hand[0]
|
||||
check(g.discard(h, card) == "" and h.hand.size() == 1 and h.energy == 10 + Game.DISCARD_GAIN and not (card in h.hand), "abgeworfen: Karte weg, 1 Mana mehr")
|
||||
check(g.log.back() == "Spieler wirft Flammenwolf ab.", "Verlauf")
|
||||
check(g.discard(h, card) == "Nicht auf der Hand", "nicht zweimal")
|
||||
h.energy = 0
|
||||
check(g.discard(h, h.hand[0]) == "" and h.energy == 1, "auch ohne Mana, bringt eins")
|
||||
check(g.discard(o, C("f_wolf")) == "Nicht dein Zug", "nur im eigenen Zug")
|
||||
|
||||
|
||||
## Spott zieht Angriffe auf sich; Regeneration heilt am Ende des eigenen Zugs.
|
||||
@@ -419,17 +437,15 @@ func test_verschmelzen() -> void:
|
||||
var h3: Game.Player = s3[1]
|
||||
var fa := put(h3, "f_wolf")
|
||||
var fb := put(h3, "w_tiefen")
|
||||
for i in 2:
|
||||
put(h3, "f_kobold")
|
||||
h3.played["Feuer"] = 10
|
||||
g3.apply_auras()
|
||||
check(fa.aura == 1 and fa.max_health == 3, "drei Feuer vor dem Verschmelzen")
|
||||
check(fa.aura == 1 and fa.power() == 4 and fa.max_health == 2, "10 Mana Feuer ausgespielt vor dem Verschmelzen")
|
||||
g3.fuse(h3, fa, fb)
|
||||
var ff: Game.Creature = h3.board[0]
|
||||
check(ff.aura == 1 and ff.max_health == 8 and ff.health == 8 and ff.power() == 6, "nach dem Verschmelzen zählt der Bonus nur einmal (7 + 1)")
|
||||
for i in 2:
|
||||
put(h3, "w_geist")
|
||||
check(ff.aura == 1 and ff.max_health == 7 and ff.health == 7 and ff.power() == 6, "nach dem Verschmelzen: 5 + 1 Angriff, Leben ohne Bonus")
|
||||
h3.played["Wasser"] = 10
|
||||
g3.apply_auras()
|
||||
check(g3.element_counts()["Wasser"] == 3 and ff.aura == 2 and ff.max_health == 9, "Feuer und Wasser voll: Dampf bekommt +2/+2")
|
||||
check(ff.aura == 2 and ff.power() == 7 and ff.max_health == 7, "Feuer und Wasser voll: Dampf bekommt +2 Angriff")
|
||||
# Auf der Hand
|
||||
var s4 := setup(["f_wolf", "w_tiefen", "l_wind"])
|
||||
var g4: Game = s4[0]
|
||||
@@ -653,6 +669,8 @@ func test_spielstand_migration() -> void:
|
||||
check(p.coins == 300 and p.dust == 70 and p.campaign_stage == 2, "alter Stand gelesen")
|
||||
check(p.collection.is_empty() and p.perk == "", "Sammlung auf Standard, unbekanntes Merkmal verworfen")
|
||||
check(is_equal_approx(p.settings.volume, 0.3) and p.settings.animations, "Einstellungen übernommen")
|
||||
var fresh := Profile.new()
|
||||
check(fresh.settings.volume == 0.0 and fresh.settings.music == 0.0, "Ton und Musik sind standardmäßig aus")
|
||||
p.collection["f_wolf"] = 3
|
||||
var d := p.to_dict()
|
||||
check(d.version == Profile.SAVE_VERSION, "Version gespeichert")
|
||||
@@ -731,6 +749,8 @@ func test_merkmale() -> void:
|
||||
g.play_card(h, h.hand[0])
|
||||
check(h.board[1].power() == 3 + 1, "Luft: nur Wesen +1")
|
||||
g.deck = DeckGen.deck(g.rng)
|
||||
h.offer = g.draw_cards(Game.OFFER)
|
||||
h.drew = true # das erste Ziehen wäre ohnehin frei
|
||||
var mana := h.energy
|
||||
check(g.draw(h) == "" and h.energy == mana and h.hand.size() == 1, "Merkmal: Ziehen kostet nichts")
|
||||
for perk in Game.PERKS:
|
||||
@@ -784,6 +804,7 @@ func test_snapshot() -> void:
|
||||
h.energy = 5
|
||||
o.energy = 5
|
||||
g.deck = DeckGen.deck(g.rng)
|
||||
h.offer = g.draw_cards(Game.OFFER)
|
||||
g.draw(h)
|
||||
var snap := g.snapshot(hi)
|
||||
var json: Dictionary = JSON.parse_string(JSON.stringify(snap))
|
||||
@@ -793,6 +814,8 @@ func test_snapshot() -> void:
|
||||
check(g2.players[oi].hand.size() == 1 and g2.players[oi].hand[0].id != "w_frost", "fremde Hand nur als Anzahl")
|
||||
var cr2 := g2.find_creature(h.board[0].uid)
|
||||
check(cr2 != null and cr2.card.id == "f_wolf" and cr2.owner() == g2.players[hi] and not cr2.ready, "Wesen mit Besitzer und Zustand")
|
||||
check(int(g2.players[hi].played["Feuer"]) == C("f_wolf").cost, "ausgespieltes Elementmana reist mit")
|
||||
check(g2.players[hi].offer.size() == Game.OFFER and snap.players[oi].offer.is_empty(), "das eigene Angebot reist mit, das des Gegners bleibt verborgen")
|
||||
var troll2 := g2.find_creature(troll.uid)
|
||||
check(troll2.ready and troll2.attacks_done == 1, "Bereitschaft und Angriffe reisen mit")
|
||||
check(g2.events.size() == g.events.size() and g2.events.back().type == g.events.back().type, "Ereignisse übertragen")
|
||||
|
||||
Reference in New Issue
Block a user