diff --git a/maps/healing_pools.go b/maps/healing_pools.go new file mode 100644 index 0000000..703dff2 --- /dev/null +++ b/maps/healing_pools.go @@ -0,0 +1,92 @@ +package maps + +import ( + "github.com/BattlesnakeOfficial/rules" +) + +type HealingPoolsMap struct{} + +func init() { + globalRegistry.RegisterMap("healing_pools", HealingPoolsMap{}) +} + +func (m HealingPoolsMap) ID() string { + return "healing_pools" +} + +func (m HealingPoolsMap) Meta() Metadata { + return Metadata{ + Name: "Healing Pools", + Description: "A simple map that spawns fixed single cell hazard areas based on the map size.", + Author: "Battlesnake", + Version: 1, + MinPlayers: 1, + MaxPlayers: 8, + BoardSizes: FixedSizes(Dimensions{7, 7}, Dimensions{11, 11}, Dimensions{19, 19}), + } +} + +func (m HealingPoolsMap) SetupBoard(initialBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { + if err := (StandardMap{}).SetupBoard(initialBoardState, settings, editor); err != nil { + return err + } + + rand := settings.GetRand(0) + + options, ok := poolLocationOptions[rules.Point{X: initialBoardState.Width, Y: initialBoardState.Height}] + if !ok { + return rules.RulesetError("board size is not supported by this map") + } + + i := rand.Intn(len(options)) + + for _, p := range options[i] { + editor.AddHazard(p) + } + + return nil +} + +func (m HealingPoolsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { + return StandardMap{}.UpdateBoard(lastBoardState, settings, editor) +} + +var poolLocationOptions = map[rules.Point][][]rules.Point{ + {X: 7, Y: 7}: { + { + {X: 3, Y: 3}, + }, + }, + {X: 11, Y: 11}: { + { + {X: 3, Y: 3}, + {X: 7, Y: 7}, + }, + { + {X: 3, Y: 7}, + {X: 7, Y: 3}, + }, + { + {X: 3, Y: 5}, + {X: 7, Y: 5}, + }, + { + {X: 5, Y: 7}, + {X: 5, Y: 3}, + }, + }, + {X: 19, Y: 19}: { + { + {X: 5, Y: 5}, + {X: 13, Y: 13}, + {X: 5, Y: 13}, + {X: 13, Y: 5}, + }, + { + {X: 5, Y: 10}, + {X: 13, Y: 10}, + {X: 10, Y: 13}, + {X: 10, Y: 5}, + }, + }, +} diff --git a/maps/healing_pools_test.go b/maps/healing_pools_test.go new file mode 100644 index 0000000..9a856a1 --- /dev/null +++ b/maps/healing_pools_test.go @@ -0,0 +1,58 @@ +package maps_test + +import ( + "fmt" + "testing" + + "github.com/BattlesnakeOfficial/rules" + "github.com/BattlesnakeOfficial/rules/maps" + "github.com/stretchr/testify/require" +) + +func TestHealingPoolsMap(t *testing.T) { + + tests := []struct { + boardSize int + expectedHazards int + allowableHazards []rules.Point + }{ + {7, 1, []rules.Point{{X: 3, Y: 3}}}, + {11, 2, []rules.Point{{X: 3, Y: 3}, + {X: 7, Y: 7}, + {X: 3, Y: 7}, + {X: 7, Y: 3}, + {X: 3, Y: 5}, + {X: 7, Y: 5}, + {X: 5, Y: 7}, + {X: 5, Y: 3}}}, + {19, 4, []rules.Point{{X: 5, Y: 5}, + {X: 13, Y: 13}, + {X: 5, Y: 13}, + {X: 13, Y: 5}, + {X: 5, Y: 10}, + {X: 13, Y: 10}, + {X: 10, Y: 13}, + {X: 10, Y: 5}}}, + } + + for _, tc := range tests { + + t.Run(fmt.Sprintf("%dx%d", tc.boardSize, tc.boardSize), func(t *testing.T) { + m := maps.HealingPoolsMap{} + state := rules.NewBoardState(tc.boardSize, tc.boardSize) + settings := rules.Settings{} + + // ensure the ring of hazards is added to the board at setup + editor := maps.NewBoardStateEditor(state) + require.Empty(t, state.Hazards) + err := m.SetupBoard(state, settings, editor) + require.NoError(t, err) + require.NotEmpty(t, state.Hazards) + require.Len(t, state.Hazards, tc.expectedHazards) + + for _, p := range state.Hazards { + require.Contains(t, tc.allowableHazards, p) + } + }) + } +}