2020-07-25 17:37:41 -07:00
|
|
|
package rules
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
2020-07-29 10:24:38 -07:00
|
|
|
"math/rand"
|
2020-07-25 17:37:41 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type RoyaleRuleset struct {
|
|
|
|
|
StandardRuleset
|
|
|
|
|
|
2020-07-29 13:14:42 -07:00
|
|
|
Seed int64
|
|
|
|
|
|
2020-07-25 17:37:41 -07:00
|
|
|
ShrinkEveryNTurns int32
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-02 20:09:55 -07:00
|
|
|
func (r *RoyaleRuleset) Name() string { return "royale" }
|
|
|
|
|
|
2020-07-25 17:37:41 -07:00
|
|
|
func (r *RoyaleRuleset) CreateNextBoardState(prevState *BoardState, moves []SnakeMove) (*BoardState, error) {
|
2021-08-17 16:47:06 -07:00
|
|
|
if r.StandardRuleset.HazardDamagePerTurn < 1 {
|
|
|
|
|
return nil, errors.New("royale damage per turn must be greater than zero")
|
2020-07-25 17:37:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nextBoardState, err := r.StandardRuleset.CreateNextBoardState(prevState, moves)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-17 16:47:06 -07:00
|
|
|
// Royale's only job is now to populate the hazards for next turn - StandardRuleset takes care of applying hazard damage.
|
2021-08-27 13:28:12 -07:00
|
|
|
err = r.populateHazards(nextBoardState, prevState.Turn+1)
|
2020-07-25 17:37:41 -07:00
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nextBoardState, nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-17 16:47:06 -07:00
|
|
|
func (r *RoyaleRuleset) populateHazards(b *BoardState, turn int32) error {
|
|
|
|
|
b.Hazards = []Point{}
|
2020-07-25 17:37:41 -07:00
|
|
|
|
|
|
|
|
if r.ShrinkEveryNTurns < 1 {
|
2021-08-17 16:47:06 -07:00
|
|
|
return errors.New("royale game can't shrink more frequently than every turn")
|
2020-07-25 17:37:41 -07:00
|
|
|
}
|
|
|
|
|
|
2020-07-27 10:59:52 -07:00
|
|
|
if turn < r.ShrinkEveryNTurns {
|
2020-07-25 17:37:41 -07:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-29 13:14:42 -07:00
|
|
|
randGenerator := rand.New(rand.NewSource(r.Seed))
|
2020-07-29 10:24:38 -07:00
|
|
|
|
2020-07-27 10:59:52 -07:00
|
|
|
numShrinks := turn / r.ShrinkEveryNTurns
|
2020-07-29 10:24:38 -07:00
|
|
|
minX, maxX := int32(0), b.Width-1
|
|
|
|
|
minY, maxY := int32(0), b.Height-1
|
|
|
|
|
for i := int32(0); i < numShrinks; i++ {
|
|
|
|
|
switch randGenerator.Intn(4) {
|
|
|
|
|
case 0:
|
|
|
|
|
minX += 1
|
|
|
|
|
case 1:
|
|
|
|
|
maxX -= 1
|
|
|
|
|
case 2:
|
|
|
|
|
minY += 1
|
|
|
|
|
case 3:
|
|
|
|
|
maxY -= 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-25 17:37:41 -07:00
|
|
|
for x := int32(0); x < b.Width; x++ {
|
|
|
|
|
for y := int32(0); y < b.Height; y++ {
|
|
|
|
|
if x < minX || x > maxX || y < minY || y > maxY {
|
2021-08-17 16:47:06 -07:00
|
|
|
b.Hazards = append(b.Hazards, Point{x, y})
|
2020-07-25 17:37:41 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|