142 lines
4.8 KiB
Go
142 lines
4.8 KiB
Go
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("действия после завершения боя не должны ничего менять")
|
||
}
|
||
}
|