Add "EliminatedBy" to snake eliminations. (#11)
* add eliminated by * add test * make sure largest snake is listed as eliminator on head to head collisions * remove unused type def * Reduce memory usage during elimination checks. Co-authored-by: Daniel Steuernol <dlsteuer@gmail.com>
This commit is contained in:
parent
a241c526b2
commit
8153585f57
4 changed files with 70 additions and 21 deletions
26
standard.go
26
standard.go
|
|
@ -3,6 +3,7 @@ package rules
|
|||
import (
|
||||
"errors"
|
||||
"math/rand"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type StandardRuleset struct{}
|
||||
|
|
@ -256,6 +257,19 @@ func (r *StandardRuleset) reduceSnakeHealth(b *BoardState) error {
|
|||
}
|
||||
|
||||
func (r *StandardRuleset) eliminateSnakes(b *BoardState) error {
|
||||
// First order snake indices by length.
|
||||
// In multi-collision scenarios we want to always attribute elimination to the longest snake.
|
||||
snakeIndicesByLength := make([]int, len(b.Snakes))
|
||||
for i := 0; i < len(b.Snakes); i++ {
|
||||
snakeIndicesByLength[i] = i
|
||||
}
|
||||
sort.Slice(snakeIndicesByLength, func(i int, j int) bool {
|
||||
lenI := len(b.Snakes[snakeIndicesByLength[i]].Body)
|
||||
lenJ := len(b.Snakes[snakeIndicesByLength[j]].Body)
|
||||
return lenI > lenJ
|
||||
})
|
||||
|
||||
// Iterate through snakes checking for eliminations.
|
||||
for i := 0; i < len(b.Snakes); i++ {
|
||||
snake := &b.Snakes[i]
|
||||
if len(snake.Body) <= 0 {
|
||||
|
|
@ -273,14 +287,15 @@ func (r *StandardRuleset) eliminateSnakes(b *BoardState) error {
|
|||
}
|
||||
|
||||
// Always check body collisions before head-to-heads
|
||||
for j := 0; j < len(b.Snakes); j++ {
|
||||
other := &b.Snakes[j]
|
||||
for _, otherIndex := range snakeIndicesByLength {
|
||||
other := &b.Snakes[otherIndex]
|
||||
if r.snakeHasBodyCollided(snake, other) {
|
||||
if snake.ID == other.ID {
|
||||
snake.EliminatedCause = EliminatedBySelfCollision
|
||||
} else {
|
||||
snake.EliminatedCause = EliminatedByCollision
|
||||
}
|
||||
snake.EliminatedBy = other.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -288,11 +303,12 @@ func (r *StandardRuleset) eliminateSnakes(b *BoardState) error {
|
|||
continue
|
||||
}
|
||||
|
||||
// Always check body collisions before head-to-heads
|
||||
for j := 0; j < len(b.Snakes); j++ {
|
||||
other := &b.Snakes[j]
|
||||
// Always check head-to-heads after body collisions
|
||||
for _, otherIndex := range snakeIndicesByLength {
|
||||
other := &b.Snakes[otherIndex]
|
||||
if snake.ID != other.ID && r.snakeHasLostHeadToHead(snake, other) {
|
||||
snake.EliminatedCause = EliminatedByHeadToHeadCollision
|
||||
snake.EliminatedBy = other.ID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue