147 lines
4.2 KiB
Go
147 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestSenetModelRollViaKey(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
|
|
next, _ := m.Update(key("r"))
|
|
m = next.(SenetModel)
|
|
if m.game.DiceValue == 0 {
|
|
t.Errorf("после броска значение кости не должно оставаться нулевым")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelApplyMoveViaDigitKey(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
m.game.Roll(2)
|
|
if m.game.CurrentPlayer != SenetPlayerA {
|
|
t.Fatalf("тест предполагает ход человека")
|
|
}
|
|
moves := m.game.LegalMoves()
|
|
if len(moves) == 0 {
|
|
t.Fatalf("ожидался хотя бы один легальный ход")
|
|
}
|
|
|
|
next, _ := m.Update(key("1"))
|
|
m = next.(SenetModel)
|
|
if m.isError {
|
|
t.Fatalf("неожиданная ошибка: %s", m.message)
|
|
}
|
|
}
|
|
|
|
func TestSenetModelRejectsMoveKeyBeforeRoll(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
|
|
next, _ := m.Update(key("1"))
|
|
m = next.(SenetModel)
|
|
if m.game.BorneOff[SenetPlayerA] != 0 || m.game.Rolled {
|
|
t.Errorf("ход не должен был приняться до броска костей")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelBotPlaysWhenNotHumanTurn(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerB)
|
|
m.humanColor = SenetPlayerA
|
|
|
|
next, _ := m.Update(botMoveMsg{})
|
|
m = next.(SenetModel)
|
|
if m.game.CurrentPlayer != SenetPlayerA && m.game.Result == nil {
|
|
t.Errorf("после хода бота (без доп.бросков) очередь должна была перейти к человеку")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelIgnoresBotMoveMsgOnHumanTurn(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
|
|
next, _ := m.Update(botMoveMsg{})
|
|
m = next.(SenetModel)
|
|
if m.game.Rolled {
|
|
t.Errorf("botMoveMsg не должно было ничего менять, пока сейчас ход человека")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelQReturnsToMenuNotQuitsApp(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
next, _ := m.Update(key("q"))
|
|
m = next.(SenetModel)
|
|
if !m.backToMenu {
|
|
t.Errorf("ожидался флаг backToMenu после 'q'")
|
|
}
|
|
if m.quitting {
|
|
t.Errorf("'q' не должно завершать приложение целиком")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelActionsIgnoredAfterGameOver(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyEasy)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
m.game.Result = &SenetResult{Winner: SenetPlayerA}
|
|
|
|
next, _ := m.Update(key("r"))
|
|
m = next.(SenetModel)
|
|
if m.game.Rolled {
|
|
t.Errorf("действия после завершения партии не должны приниматься")
|
|
}
|
|
}
|
|
|
|
func TestSenetModelFullAutoPlaythrough(t *testing.T) {
|
|
m := NewSenetModel(SenetDifficultyMedium)
|
|
m.game = NewSenetGame(SenetPlayerA)
|
|
m.humanColor = SenetPlayerA
|
|
humanBot := SenetBot{Difficulty: SenetDifficultyMedium}
|
|
|
|
steps := 0
|
|
for m.game.Result == nil && steps < 30000 {
|
|
steps++
|
|
if m.game.CurrentPlayer != m.humanColor {
|
|
next, _ := m.Update(botMoveMsg{})
|
|
m = next.(SenetModel)
|
|
continue
|
|
}
|
|
if !m.game.Rolled {
|
|
next, _ := m.Update(key("r"))
|
|
m = next.(SenetModel)
|
|
continue
|
|
}
|
|
moves := m.game.LegalMoves()
|
|
if len(moves) == 0 {
|
|
t.Fatalf("LegalMoves пуст при Rolled=true для хода человека — не должно происходить")
|
|
}
|
|
if len(moves) > 9 {
|
|
t.Fatalf("число легальных ходов превысило 9: %d", len(moves))
|
|
}
|
|
chosen := humanBot.DecideMove(m.game, m.rng)
|
|
idx := -1
|
|
for i, mv := range moves {
|
|
if mv.From == chosen {
|
|
idx = i
|
|
break
|
|
}
|
|
}
|
|
if idx < 0 {
|
|
idx = 0
|
|
}
|
|
next, _ := m.Update(key(fmt.Sprintf("%d", idx+1)))
|
|
m = next.(SenetModel)
|
|
if m.isError {
|
|
t.Fatalf("неожиданная ошибка при ходе: %s", m.message)
|
|
}
|
|
}
|
|
if m.game.Result == nil {
|
|
t.Fatalf("партия не завершилась за %d шагов", steps)
|
|
}
|
|
}
|