51 lines
1.5 KiB
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)
|
|
}
|
|
}
|
|
}
|
|
}
|