go_games_collection/minesweeper_stress_test.go

51 lines
1.5 KiB
Go

package main
import (
"math/rand"
"testing"
)
// TestMinesweeperRandomGamesNoCorruption прогоняет много случайных
// партий на каждом классическом пресете размера, проверяя
// отсутствие паник и что каждая партия корректно завершается
// (победой или поражением) за разумное число ходов.
func TestMinesweeperRandomGamesNoCorruption(t *testing.T) {
rnd := rand.New(rand.NewSource(1))
presets := []struct{ w, h, mines int }{
{9, 9, 10},
{16, 16, 40},
{30, 16, 99},
}
for _, p := range presets {
for game := 0; game < 20; game++ {
g := NewMinesweeperGame(p.w, p.h, p.mines)
const maxMoves = 2000
moves := 0
for ; moves < maxMoves && g.Result == nil; moves++ {
var candidates []MinesweeperPos
for r := 0; r < g.Height; r++ {
for c := 0; c < g.Width; c++ {
cell := g.Board[r][c]
if !cell.Revealed && !cell.Flagged {
candidates = append(candidates, msp(r, c))
}
}
}
if len(candidates) == 0 {
break
}
pos := candidates[rnd.Intn(len(candidates))]
if err := g.Reveal(pos); err != nil {
t.Fatalf("пресет %dx%d/%d, игра %d, ход %d: неожиданная ошибка: %v",
p.w, p.h, p.mines, game, moves, err)
}
}
if g.Result == nil {
t.Fatalf("пресет %dx%d/%d, игра %d: партия не завершилась за %d ходов",
p.w, p.h, p.mines, game, maxMoves)
}
}
}
}