forked from colinjfw/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeath.go
94 lines (83 loc) · 2.14 KB
/
death.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
package rules
import "github.com/battlesnakeio/engine/controller/pb"
type deathUpdate struct {
Snake *pb.Snake
Death *pb.Death
}
// checkForDeath looks through the snakes with the updated coords and checks to see if any have died
// possible death options are starvation (health has reached 0), wall collision, snake body collision
// snake head collision (other snake is same size or greater)
func checkForDeath(width, height int32, frame *pb.GameFrame) []deathUpdate {
updates := []deathUpdate{}
for _, s := range frame.AliveSnakes() {
if deathByHealth(s.Health) {
updates = append(updates, deathUpdate{
Snake: s,
Death: &pb.Death{
Turn: frame.Turn,
Cause: DeathCauseStarvation,
},
})
continue
}
head := s.Head()
if head == nil {
continue
}
if deathByOutOfBounds(head, width, height) {
updates = append(updates, deathUpdate{
Snake: s,
Death: &pb.Death{
Turn: frame.Turn,
Cause: DeathCauseWallCollision,
},
})
continue
}
for _, other := range frame.AliveSnakes() {
if deathByHeadCollision(s, other) {
updates = append(updates, deathUpdate{
Snake: s,
Death: &pb.Death{
Turn: frame.Turn,
Cause: DeathCauseHeadToHeadCollision,
},
})
}
for i, b := range other.Body {
if i == 0 {
continue
}
if deathByBodyCollision(s.Head(), b) {
var cause string
if s.ID == other.ID {
cause = DeathCauseSnakeSelfCollision
} else {
cause = DeathCauseSnakeCollision
}
updates = append(updates, deathUpdate{
Snake: s,
Death: &pb.Death{
Turn: frame.Turn,
Cause: cause,
},
})
break
}
}
}
}
return updates
}
func deathByHealth(health int32) bool {
return health <= 0
}
func deathByBodyCollision(head, body *pb.Point) bool {
return head.Equal(body)
}
func deathByOutOfBounds(head *pb.Point, width, height int32) bool {
return (head.X < 0) || (head.X >= width) || (head.Y < 0) || (head.Y >= height)
}
func deathByHeadCollision(snake, other *pb.Snake) bool {
return (other.ID != snake.ID) && (snake.Head().Equal(other.Head())) && (len(snake.Body) <= len(other.Body))
}