forked from BattlesnakeOfficial/rules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
solo_test.go
149 lines (134 loc) · 3.45 KB
/
solo_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package rules
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestSoloRulesetInterface(t *testing.T) {
var _ Ruleset = (*SoloRuleset)(nil)
}
func TestSoloName(t *testing.T) {
r := SoloRuleset{}
require.Equal(t, "solo", r.Name())
}
func TestSoloCreateNextBoardStateSanity(t *testing.T) {
boardState := &BoardState{}
r := SoloRuleset{}
_, err := r.CreateNextBoardState(boardState, []SnakeMove{})
require.NoError(t, err)
}
func TestSoloIsGameOver(t *testing.T) {
tests := []struct {
Snakes []Snake
Expected bool
}{
{[]Snake{}, true},
{[]Snake{{}}, false},
{[]Snake{{}, {}, {}}, false},
{[]Snake{{EliminatedCause: EliminatedByOutOfBounds}}, true},
{
[]Snake{
{EliminatedCause: EliminatedByOutOfBounds},
{EliminatedCause: EliminatedByOutOfBounds},
{EliminatedCause: EliminatedByOutOfBounds},
},
true,
},
}
r := SoloRuleset{}
for _, test := range tests {
b := &BoardState{
Height: 11,
Width: 11,
Snakes: test.Snakes,
Food: []Point{},
}
actual, err := r.IsGameOver(b)
require.NoError(t, err)
require.Equal(t, test.Expected, actual)
}
}
// Checks that a single snake doesn't end the game
// also that:
// - snake moves okay
// - food gets consumed
// - snake grows and gets health from food
var soloCaseNotOver = gameTestCase{
"Solo Case Game Not Over",
&BoardState{
Width: 10,
Height: 10,
Snakes: []Snake{
{
ID: "one",
Body: []Point{{1, 1}, {1, 2}},
Health: 100,
},
},
Food: []Point{{0, 0}, {1, 0}},
Hazards: []Point{},
},
[]SnakeMove{
{ID: "one", Move: MoveDown},
},
nil,
&BoardState{
Width: 10,
Height: 10,
Snakes: []Snake{
{
ID: "one",
Body: []Point{{1, 0}, {1, 1}, {1, 1}},
Health: 100,
},
},
Food: []Point{{0, 0}},
Hazards: []Point{},
},
}
func TestSoloCreateNextBoardState(t *testing.T) {
cases := []gameTestCase{
// inherits these test cases from standard
standardCaseErrNoMoveFound,
standardCaseErrZeroLengthSnake,
standardCaseMoveEatAndGrow,
standardMoveAndCollideMAD,
soloCaseNotOver,
}
r := SoloRuleset{}
rb := NewRulesetBuilder().WithParams(map[string]string{
ParamGameType: GameTypeSolo,
})
for _, gc := range cases {
gc.requireValidNextState(t, &r)
// also test a RulesBuilder constructed instance
gc.requireValidNextState(t, rb.Ruleset())
// also test a pipeline with the same settings
gc.requireValidNextState(t, NewRulesetBuilder().PipelineRuleset(GameTypeSolo, NewPipeline(soloRulesetStages...)))
}
}
// Test a snake running right into the wall is properly eliminated
func TestSoloEliminationOutOfBounds(t *testing.T) {
r := SoloRuleset{}
// Using MaxRand is important because it ensures that the snakes are consistently placed in a way this test will work.
// Actually random placement could result in the assumptions made by this test being incorrect.
initialState, err := CreateDefaultBoardState(MaxRand, 2, 2, []string{"one"})
require.NoError(t, err)
_, next, err := r.Execute(
initialState,
r.Settings(),
[]SnakeMove{{ID: "one", Move: "right"}},
)
require.NoError(t, err)
require.NotNil(t, initialState)
ended, next, err := r.Execute(
next,
r.Settings(),
[]SnakeMove{{ID: "one", Move: "right"}},
)
require.NoError(t, err)
require.NotNil(t, initialState)
require.True(t, ended)
require.Equal(t, EliminatedByOutOfBounds, next.Snakes[0].EliminatedCause)
require.Equal(t, "", next.Snakes[0].EliminatedBy)
require.Equal(t, 1, next.Snakes[0].EliminatedOnTurn)
}