go_games_collection/wayfarer_combat_test.go

142 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"math/rand"
"testing"
)
func TestApplyDamageAbsorbedByShieldFirst(t *testing.T) {
shield, hull := 10, 50
applyDamage(&shield, &hull, 6)
if shield != 4 || hull != 50 {
t.Errorf("урон должен был полностью уйти в щит: shield=%d hull=%d", shield, hull)
}
}
func TestApplyDamageOverflowsToHull(t *testing.T) {
shield, hull := 5, 50
applyDamage(&shield, &hull, 12)
if shield != 0 || hull != 43 {
t.Errorf("избыток урона должен был перейти в корпус: shield=%d hull=%d", shield, hull)
}
}
func TestApplyDamageHullNeverNegative(t *testing.T) {
shield, hull := 0, 5
applyDamage(&shield, &hull, 100)
if hull != 0 {
t.Errorf("корпус не должен уходить в минус, получено %d", hull)
}
}
func TestAttackCanDefeatEnemy(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 5, 5, 100, 100, 50, 50, 100, true)
c.Attack(rnd)
if c.Outcome != CombatWon {
t.Fatalf("огромный урон игрока должен был сразу уничтожить слабого врага, получен исход %v (EnemyHull=%d)",
c.Outcome, c.EnemyHull)
}
if c.LastEnemyDamage != 0 {
t.Errorf("уничтоженный враг не должен успевать ответным ударом")
}
}
func TestAttackEnemySurvivesAndRetaliates(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 1000, 5, 100, 100, 50, 50, 5, true)
beforeHull := c.PlayerHull + c.PlayerShield
c.Attack(rnd)
if c.Outcome != CombatOngoing {
t.Fatalf("бой должен был продолжиться, получен исход %v", c.Outcome)
}
afterHull := c.PlayerHull + c.PlayerShield
if afterHull >= beforeHull {
t.Errorf("выживший враг должен был нанести ответный урон")
}
}
func TestAttackCanDefeatPlayer(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 1000, 500, 1, 100, 0, 50, 1, true)
c.Attack(rnd)
if c.Outcome != CombatLost {
t.Fatalf("слабый игрок против огромного урона должен был проиграть, получен исход %v (PlayerHull=%d)",
c.Outcome, c.PlayerHull)
}
}
func TestFleeEventuallySucceedsOrFails(t *testing.T) {
successSeen, failSeen := false, false
for seed := int64(0); seed < 200 && !(successSeen && failSeen); seed++ {
rnd := rand.New(rand.NewSource(seed))
c := NewWayfarerCombat("enemy.pirate", 1000, 5, 1000, 1000, 100, 100, 5, true)
if c.Flee(rnd) {
successSeen = true
} else {
failSeen = true
}
}
if !successSeen || !failSeen {
t.Errorf("ожидались оба исхода бегства среди множества попыток: успех=%v неудача=%v", successSeen, failSeen)
}
}
func TestFailedFleeStillTakesDamage(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 1000, 20, 1000, 1000, 0, 0, 5, true)
for i := 0; i < 50 && c.Outcome == CombatOngoing; i++ {
fled := c.Flee(rnd)
if !fled {
if c.LastEnemyDamage <= 0 {
t.Errorf("неудачное бегство должно было нанести урон игроку")
}
return
}
}
}
func TestNegotiateOnlyAvailableWhenNegotiable(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 1000, 5, 1000, 1000, 100, 100, 5, false)
before := *c
ok := c.Negotiate(rnd)
if ok {
t.Errorf("переговоры не должны быть доступны, если Negotiable=false")
}
if c.Round != before.Round {
t.Errorf("недоступная попытка переговоров не должна тратить раунд")
}
}
func TestNegotiateEventuallySucceedsOrFails(t *testing.T) {
successSeen, failSeen := false, false
for seed := int64(0); seed < 200 && !(successSeen && failSeen); seed++ {
rnd := rand.New(rand.NewSource(seed))
c := NewWayfarerCombat("enemy.pirate", 1000, 5, 1000, 1000, 100, 100, 5, true)
if c.Negotiate(rnd) {
successSeen = true
} else {
failSeen = true
}
}
if !successSeen || !failSeen {
t.Errorf("ожидались оба исхода переговоров среди множества попыток: успех=%v неудача=%v", successSeen, failSeen)
}
}
func TestActionsAfterCombatOverAreNoOps(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
c := NewWayfarerCombat("enemy.pirate", 5, 5, 100, 100, 50, 50, 100, true)
c.Attack(rnd)
if c.Outcome != CombatWon {
t.Fatalf("бой должен был завершиться победой для настройки теста")
}
roundAfter := c.Round
c.Attack(rnd)
c.Flee(rnd)
c.Negotiate(rnd)
if c.Round != roundAfter {
t.Errorf("действия после завершения боя не должны ничего менять")
}
}