Refactor RoyaleRuleset and move hazard damage into StandardRuleset (#50)
* move hazard damage into StandardRuleset * OutOfBounds -> Hazards * remove "out of bounds" in comment * add cases for eating food to hazard damage test
This commit is contained in:
parent
dabbe7dfb5
commit
e416384007
8 changed files with 341 additions and 288 deletions
78
standard.go
78
standard.go
|
|
@ -6,8 +6,9 @@ import (
|
|||
)
|
||||
|
||||
type StandardRuleset struct {
|
||||
FoodSpawnChance int32 // [0, 100]
|
||||
MinimumFood int32
|
||||
FoodSpawnChance int32 // [0, 100]
|
||||
MinimumFood int32
|
||||
HazardDamagePerTurn int32
|
||||
}
|
||||
|
||||
func (r *StandardRuleset) Name() string { return "standard" }
|
||||
|
|
@ -50,14 +51,14 @@ func (r *StandardRuleset) placeSnakesFixed(b *BoardState) error {
|
|||
// Create start 8 points
|
||||
mn, md, mx := int32(1), (b.Width-1)/2, b.Width-2
|
||||
startPoints := []Point{
|
||||
Point{mn, mn},
|
||||
Point{mn, md},
|
||||
Point{mn, mx},
|
||||
Point{md, mn},
|
||||
Point{md, mx},
|
||||
Point{mx, mn},
|
||||
Point{mx, md},
|
||||
Point{mx, mx},
|
||||
{mn, mn},
|
||||
{mn, md},
|
||||
{mn, mx},
|
||||
{md, mn},
|
||||
{md, mx},
|
||||
{mx, mn},
|
||||
{mx, md},
|
||||
{mx, mx},
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
|
|
@ -107,10 +108,10 @@ func (r *StandardRuleset) placeFoodFixed(b *BoardState) error {
|
|||
for i := 0; i < len(b.Snakes); i++ {
|
||||
snakeHead := b.Snakes[i].Body[0]
|
||||
possibleFoodLocations := []Point{
|
||||
Point{snakeHead.X - 1, snakeHead.Y - 1},
|
||||
Point{snakeHead.X - 1, snakeHead.Y + 1},
|
||||
Point{snakeHead.X + 1, snakeHead.Y - 1},
|
||||
Point{snakeHead.X + 1, snakeHead.Y + 1},
|
||||
{snakeHead.X - 1, snakeHead.Y - 1},
|
||||
{snakeHead.X - 1, snakeHead.Y + 1},
|
||||
{snakeHead.X + 1, snakeHead.Y - 1},
|
||||
{snakeHead.X + 1, snakeHead.Y + 1},
|
||||
}
|
||||
availableFoodLocations := []Point{}
|
||||
|
||||
|
|
@ -175,10 +176,11 @@ func (r *StandardRuleset) isKnownBoardSize(b *BoardState) bool {
|
|||
func (r *StandardRuleset) CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error) {
|
||||
// We specifically want to copy prevState, so as not to alter it directly.
|
||||
nextState := &BoardState{
|
||||
Height: prevState.Height,
|
||||
Width: prevState.Width,
|
||||
Food: append([]Point{}, prevState.Food...),
|
||||
Snakes: make([]Snake, len(prevState.Snakes)),
|
||||
Height: prevState.Height,
|
||||
Width: prevState.Width,
|
||||
Food: append([]Point{}, prevState.Food...),
|
||||
Snakes: make([]Snake, len(prevState.Snakes)),
|
||||
Hazards: append([]Point{}, prevState.Hazards...),
|
||||
}
|
||||
for i := 0; i < len(prevState.Snakes); i++ {
|
||||
nextState.Snakes[i].ID = prevState.Snakes[i].ID
|
||||
|
|
@ -202,6 +204,11 @@ func (r *StandardRuleset) CreateNextBoardState(prevState *BoardState, moves []Sn
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err = r.maybeDamageHazards(nextState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: LOG?
|
||||
// bvanvugt: We specifically want this to happen before elimination for two reasons:
|
||||
// 1) We want snakes to be able to eat on their very last turn and still survive.
|
||||
|
|
@ -307,6 +314,41 @@ func (r *StandardRuleset) reduceSnakeHealth(b *BoardState) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *StandardRuleset) maybeDamageHazards(b *BoardState) error {
|
||||
for i := 0; i < len(b.Snakes); i++ {
|
||||
snake := &b.Snakes[i]
|
||||
if snake.EliminatedCause != NotEliminated {
|
||||
continue
|
||||
}
|
||||
head := snake.Body[0]
|
||||
for _, p := range b.Hazards {
|
||||
if head == p {
|
||||
// If there's a food in this square, don't reduce health
|
||||
foundFood := false
|
||||
for _, food := range b.Food {
|
||||
if p == food {
|
||||
foundFood = true
|
||||
}
|
||||
}
|
||||
if foundFood {
|
||||
continue
|
||||
}
|
||||
|
||||
// Snake is in a hazard, reduce health
|
||||
snake.Health = snake.Health - r.HazardDamagePerTurn
|
||||
if snake.Health < 0 {
|
||||
snake.Health = 0
|
||||
}
|
||||
if r.snakeIsOutOfHealth(snake) {
|
||||
snake.EliminatedCause = EliminatedByOutOfHealth
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *StandardRuleset) maybeEliminateSnakes(b *BoardState) error {
|
||||
// First order snake indices by length.
|
||||
// In multi-collision scenarios we want to always attribute elimination to the longest snake.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue