package maps import ( "github.com/BattlesnakeOfficial/rules" ) func init() { globalRegistry.RegisterMap("hz_rivers_bridges", RiverAndBridgesMediumHazardsMap{}) globalRegistry.RegisterMap("hz_rivers_bridges_lg", RiverAndBridgesLargeHazardsMap{}) globalRegistry.RegisterMap("hz_rivers_bridges_xl", RiverAndBridgesExtraLargeHazardsMap{}) globalRegistry.RegisterMap("hz_islands_bridges", IslandsAndBridgesMediumHazardsMap{}) globalRegistry.RegisterMap("hz_islands_bridges_lg", IslandsAndBridgesLargeHazardsMap{}) } func setupRiverAndBridgesBoard(startingPositions [][]rules.Point, hazards []rules.Point, lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { width := lastBoardState.Width height := lastBoardState.Height numSnakes := len(lastBoardState.Snakes) if numSnakes == 0 { return rules.RulesetError("too few snakes - at least one snake must be present") } rand := settings.GetRand(0) snakeIDs := make([]string, 0, len(lastBoardState.Snakes)) for _, snake := range lastBoardState.Snakes { snakeIDs = append(snakeIDs, snake.ID) } tempBoardState := rules.NewBoardState(width, height) tempBoardState.Snakes = make([]rules.Snake, len(snakeIDs)) for i := 0; i < len(snakeIDs); i++ { tempBoardState.Snakes[i] = rules.Snake{ ID: snakeIDs[i], Health: rules.SnakeMaxHealth, } } err := rules.PlaceSnakesInQuadrants(rand, tempBoardState, startingPositions) if err != nil { return err } err = rules.PlaceFoodFixed(rand, tempBoardState) if err != nil { return err } // Copy food from temp board state for _, f := range tempBoardState.Food { // skip the center food if f.X == lastBoardState.Width/2 && f.Y == lastBoardState.Height/2 { continue } editor.AddFood(f) } // Copy snakes from temp board state for _, snake := range tempBoardState.Snakes { editor.PlaceSnake(snake.ID, snake.Body, snake.Health) } for _, p := range hazards { editor.AddHazard(p) } return nil } func placeRiverAndBridgesFood(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { rand := settings.GetRand(lastBoardState.Turn) foodNeeded := checkFoodNeedingPlacement(rand, settings, lastBoardState) if foodNeeded > 0 { pts := rules.GetUnoccupiedPoints(lastBoardState, false, true) placeFoodRandomlyAtPositions(rand, lastBoardState, editor, foodNeeded, pts) } return nil } type RiverAndBridgesMediumHazardsMap struct{} func (m RiverAndBridgesMediumHazardsMap) ID() string { return "hz_rivers_bridges" } func (m RiverAndBridgesMediumHazardsMap) Meta() Metadata { return Metadata{ Name: "hz_rivers_bridges", Description: `Creates fixed maps that have a lake of hazard in the middle with rivers going in the cardinal directions. Each river has one or two 1-square "bridges" over them`, Author: "Battlesnake", Version: 1, MinPlayers: 1, MaxPlayers: 8, BoardSizes: FixedSizes(Dimensions{11, 11}), Tags: []string{TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT}, } } func (m RiverAndBridgesMediumHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) { return rules.RulesetError("This map can only be played on a 11x11 board") } return setupRiverAndBridgesBoard(riversAndBridgesMediumStartPositions, riversAndBridgesMediumHazards, lastBoardState, settings, editor) } func (m RiverAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { return placeRiverAndBridgesFood(lastBoardState, settings, editor) } var riversAndBridgesMediumStartPositions = [][]rules.Point{ { {X: 1, Y: 1}, {X: 3, Y: 3}, }, { {X: 9, Y: 9}, {X: 7, Y: 7}, }, { {X: 1, Y: 9}, {X: 3, Y: 9}, }, { {X: 9, Y: 1}, {X: 7, Y: 3}, }, } var riversAndBridgesMediumHazards = []rules.Point{ {X: 5, Y: 10}, {X: 5, Y: 9}, {X: 5, Y: 7}, {X: 5, Y: 6}, {X: 5, Y: 5}, {X: 5, Y: 4}, {X: 5, Y: 3}, {X: 5, Y: 0}, {X: 5, Y: 1}, {X: 6, Y: 5}, {X: 7, Y: 5}, {X: 9, Y: 5}, {X: 10, Y: 5}, {X: 4, Y: 5}, {X: 3, Y: 5}, {X: 1, Y: 5}, {X: 0, Y: 5}, } type RiverAndBridgesLargeHazardsMap struct{} func (m RiverAndBridgesLargeHazardsMap) ID() string { return "hz_rivers_bridges_lg" } func (m RiverAndBridgesLargeHazardsMap) Meta() Metadata { return Metadata{ Name: "hz_rivers_bridges_lg", Description: `Creates fixed maps that have a lake of hazard in the middle with rivers going in the cardinal directions. Each river has one or two 1-square "bridges" over them`, Author: "Battlesnake", Version: 1, MinPlayers: 1, MaxPlayers: 12, BoardSizes: FixedSizes(Dimensions{19, 19}), Tags: []string{TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT}, } } func (m RiverAndBridgesLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) { return rules.RulesetError("This map can only be played on a 19x19 board") } return setupRiverAndBridgesBoard(riversAndBridgesLargeStartPositions, riversAndBridgesLargeHazards, lastBoardState, settings, editor) } func (m RiverAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { return placeRiverAndBridgesFood(lastBoardState, settings, editor) } var riversAndBridgesLargeStartPositions = [][]rules.Point{ { {X: 1, Y: 1}, {X: 5, Y: 1}, {X: 1, Y: 5}, {X: 5, Y: 5}, }, { {X: 17, Y: 1}, {X: 17, Y: 5}, {X: 13, Y: 5}, {X: 13, Y: 1}, }, { {X: 1, Y: 17}, {X: 5, Y: 17}, {X: 1, Y: 13}, {X: 5, Y: 13}, }, { {X: 17, Y: 17}, {X: 17, Y: 13}, {X: 13, Y: 17}, {X: 13, Y: 13}, }, } var riversAndBridgesLargeHazards = []rules.Point{ {X: 9, Y: 0}, {X: 9, Y: 1}, {X: 9, Y: 2}, {X: 9, Y: 5}, {X: 9, Y: 6}, {X: 9, Y: 7}, {X: 9, Y: 9}, {X: 9, Y: 8}, {X: 9, Y: 10}, {X: 9, Y: 12}, {X: 9, Y: 11}, {X: 9, Y: 13}, {X: 9, Y: 14}, {X: 9, Y: 16}, {X: 9, Y: 17}, {X: 9, Y: 18}, {X: 0, Y: 9}, {X: 2, Y: 9}, {X: 1, Y: 9}, {X: 3, Y: 9}, {X: 5, Y: 9}, {X: 6, Y: 9}, {X: 7, Y: 9}, {X: 8, Y: 9}, {X: 10, Y: 9}, {X: 13, Y: 9}, {X: 12, Y: 9}, {X: 11, Y: 9}, {X: 15, Y: 9}, {X: 16, Y: 9}, {X: 17, Y: 9}, {X: 18, Y: 9}, {X: 9, Y: 4}, {X: 8, Y: 10}, {X: 8, Y: 8}, {X: 10, Y: 8}, {X: 10, Y: 10}, } type RiverAndBridgesExtraLargeHazardsMap struct{} func (m RiverAndBridgesExtraLargeHazardsMap) ID() string { return "hz_rivers_bridges_xl" } func (m RiverAndBridgesExtraLargeHazardsMap) Meta() Metadata { return Metadata{ Name: "hz_rivers_bridges_xl", Description: `Creates fixed maps that have a lake of hazard in the middle with rivers going in the cardinal directions. Each river has one or two 1-square "bridges" over them`, Author: "Battlesnake", Version: 1, MinPlayers: 1, MaxPlayers: 12, BoardSizes: FixedSizes(Dimensions{25, 25}), Tags: []string{TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT}, } } func (m RiverAndBridgesExtraLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) { return rules.RulesetError("This map can only be played on a 25x25 board") } return setupRiverAndBridgesBoard(riversAndBridgesExtraLargeStartPositions, riversAndBridgesExtraLargeHazards, lastBoardState, settings, editor) } func (m RiverAndBridgesExtraLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { return placeRiverAndBridgesFood(lastBoardState, settings, editor) } var riversAndBridgesExtraLargeStartPositions = [][]rules.Point{ { {X: 1, Y: 1}, {X: 9, Y: 9}, {X: 9, Y: 1}, {X: 1, Y: 9}, }, { {X: 23, Y: 23}, {X: 15, Y: 15}, {X: 23, Y: 15}, {X: 15, Y: 23}, }, { {X: 15, Y: 1}, {X: 15, Y: 9}, {X: 23, Y: 9}, {X: 23, Y: 1}, }, { {X: 9, Y: 23}, {X: 1, Y: 23}, {X: 9, Y: 15}, {X: 1, Y: 15}, }, } var riversAndBridgesExtraLargeHazards = []rules.Point{ {X: 12, Y: 24}, {X: 12, Y: 21}, {X: 12, Y: 20}, {X: 12, Y: 19}, {X: 12, Y: 18}, {X: 12, Y: 15}, {X: 12, Y: 14}, {X: 12, Y: 13}, {X: 12, Y: 12}, {X: 12, Y: 11}, {X: 12, Y: 10}, {X: 12, Y: 9}, {X: 12, Y: 5}, {X: 12, Y: 4}, {X: 12, Y: 3}, {X: 12, Y: 0}, {X: 0, Y: 12}, {X: 3, Y: 12}, {X: 4, Y: 12}, {X: 5, Y: 12}, {X: 6, Y: 12}, {X: 9, Y: 12}, {X: 10, Y: 12}, {X: 11, Y: 12}, {X: 13, Y: 12}, {X: 14, Y: 12}, {X: 15, Y: 12}, {X: 18, Y: 12}, {X: 20, Y: 12}, {X: 19, Y: 12}, {X: 21, Y: 12}, {X: 24, Y: 12}, {X: 11, Y: 14}, {X: 10, Y: 13}, {X: 11, Y: 13}, {X: 10, Y: 11}, {X: 11, Y: 11}, {X: 11, Y: 10}, {X: 13, Y: 10}, {X: 14, Y: 11}, {X: 13, Y: 11}, {X: 13, Y: 13}, {X: 14, Y: 13}, {X: 13, Y: 14}, {X: 12, Y: 6}, {X: 12, Y: 2}, {X: 2, Y: 12}, {X: 22, Y: 12}, {X: 12, Y: 22}, {X: 16, Y: 12}, {X: 12, Y: 8}, {X: 8, Y: 12}, {X: 12, Y: 16}, } type IslandsAndBridgesMediumHazardsMap struct{} func (m IslandsAndBridgesMediumHazardsMap) ID() string { return "hz_islands_bridges" } func (m IslandsAndBridgesMediumHazardsMap) Meta() Metadata { return Metadata{ Name: "hz_islands_bridges", Description: `Creates fixed maps that have a lake of hazard in the middle with rivers going in the cardinal directions and around the edges of the map. Bridges across the rivers are provided at key points`, Author: "Battlesnake", Version: 1, MinPlayers: 1, MaxPlayers: 4, BoardSizes: FixedSizes(Dimensions{11, 11}), Tags: []string{TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT}, } } func (m IslandsAndBridgesMediumHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) { return rules.RulesetError("This map can only be played on a 11x11 board") } return setupRiverAndBridgesBoard(islandsAndBridgesMediumStartPositions, islandsAndBridgesMediumHazards, lastBoardState, settings, editor) } func (m IslandsAndBridgesMediumHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { return placeRiverAndBridgesFood(lastBoardState, settings, editor) } var islandsAndBridgesMediumStartPositions = [][]rules.Point{ { {X: 3, Y: 1}, {X: 1, Y: 3}, }, { {X: 9, Y: 7}, {X: 7, Y: 9}, }, { {X: 3, Y: 9}, {X: 1, Y: 7}, }, { {X: 7, Y: 1}, {X: 9, Y: 3}, }, } var islandsAndBridgesMediumHazards = []rules.Point{ {X: 5, Y: 10}, {X: 5, Y: 9}, {X: 5, Y: 7}, {X: 5, Y: 6}, {X: 5, Y: 5}, {X: 5, Y: 4}, {X: 5, Y: 3}, {X: 5, Y: 0}, {X: 5, Y: 1}, {X: 6, Y: 5}, {X: 7, Y: 5}, {X: 9, Y: 5}, {X: 10, Y: 5}, {X: 4, Y: 5}, {X: 3, Y: 5}, {X: 1, Y: 5}, {X: 0, Y: 5}, {X: 1, Y: 10}, {X: 9, Y: 10}, {X: 1, Y: 0}, {X: 9, Y: 0}, {X: 10, Y: 1}, {X: 10, Y: 0}, {X: 10, Y: 10}, {X: 10, Y: 9}, {X: 0, Y: 10}, {X: 0, Y: 9}, {X: 0, Y: 1}, {X: 0, Y: 0}, {X: 0, Y: 6}, {X: 0, Y: 4}, {X: 10, Y: 6}, {X: 10, Y: 4}, {X: 6, Y: 10}, {X: 4, Y: 10}, {X: 6, Y: 0}, {X: 4, Y: 0}, } type IslandsAndBridgesLargeHazardsMap struct{} func (m IslandsAndBridgesLargeHazardsMap) ID() string { return "hz_islands_bridges_lg" } func (m IslandsAndBridgesLargeHazardsMap) Meta() Metadata { return Metadata{ Name: "hz_islands_bridges_lg", Description: `Creates fixed maps that have a lake of hazard in the middle with rivers going in the cardinal directions and around the edges of the map. Bridges across the rivers are provided at key points`, Author: "Battlesnake", Version: 1, MinPlayers: 1, MaxPlayers: 16, BoardSizes: FixedSizes(Dimensions{19, 19}), Tags: []string{TAG_FOOD_PLACEMENT, TAG_HAZARD_PLACEMENT, TAG_SNAKE_PLACEMENT}, } } func (m IslandsAndBridgesLargeHazardsMap) SetupBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { if !m.Meta().BoardSizes.IsAllowable(lastBoardState.Width, lastBoardState.Height) { return rules.RulesetError("This map can only be played on a 19x19 board") } return setupRiverAndBridgesBoard(islandsAndBridgesLargeStartPositions, islandsAndBridgesLargeHazards, lastBoardState, settings, editor) } func (m IslandsAndBridgesLargeHazardsMap) UpdateBoard(lastBoardState *rules.BoardState, settings rules.Settings, editor Editor) error { return placeRiverAndBridgesFood(lastBoardState, settings, editor) } var islandsAndBridgesLargeStartPositions = [][]rules.Point{ { {X: 2, Y: 2}, {X: 2, Y: 6}, {X: 6, Y: 2}, {X: 6, Y: 6}, }, { {X: 12, Y: 2}, {X: 16, Y: 2}, {X: 16, Y: 6}, {X: 12, Y: 6}, }, { {X: 16, Y: 16}, {X: 16, Y: 12}, {X: 12, Y: 12}, {X: 12, Y: 16}, }, { {X: 2, Y: 16}, {X: 6, Y: 16}, {X: 6, Y: 12}, {X: 2, Y: 12}, }, } var islandsAndBridgesLargeHazards = []rules.Point{ {X: 9, Y: 18}, {X: 9, Y: 0}, {X: 9, Y: 1}, {X: 9, Y: 2}, {X: 9, Y: 3}, {X: 9, Y: 5}, {X: 9, Y: 6}, {X: 9, Y: 8}, {X: 9, Y: 7}, {X: 9, Y: 9}, {X: 9, Y: 10}, {X: 9, Y: 11}, {X: 9, Y: 12}, {X: 9, Y: 13}, {X: 9, Y: 15}, {X: 9, Y: 16}, {X: 9, Y: 17}, {X: 2, Y: 9}, {X: 1, Y: 9}, {X: 0, Y: 9}, {X: 3, Y: 9}, {X: 5, Y: 9}, {X: 6, Y: 9}, {X: 7, Y: 9}, {X: 8, Y: 9}, {X: 10, Y: 9}, {X: 16, Y: 9}, {X: 15, Y: 9}, {X: 13, Y: 9}, {X: 12, Y: 9}, {X: 11, Y: 9}, {X: 17, Y: 9}, {X: 18, Y: 9}, {X: 10, Y: 8}, {X: 8, Y: 8}, {X: 8, Y: 10}, {X: 10, Y: 10}, {X: 18, Y: 8}, {X: 18, Y: 7}, {X: 18, Y: 6}, {X: 18, Y: 10}, {X: 18, Y: 11}, {X: 18, Y: 12}, {X: 0, Y: 10}, {X: 0, Y: 11}, {X: 0, Y: 12}, {X: 0, Y: 8}, {X: 0, Y: 7}, {X: 0, Y: 6}, {X: 6, Y: 0}, {X: 7, Y: 0}, {X: 8, Y: 0}, {X: 10, Y: 0}, {X: 11, Y: 0}, {X: 12, Y: 0}, {X: 10, Y: 18}, {X: 11, Y: 18}, {X: 12, Y: 18}, {X: 8, Y: 18}, {X: 7, Y: 18}, {X: 6, Y: 18}, {X: 0, Y: 18}, {X: 0, Y: 17}, {X: 0, Y: 16}, {X: 0, Y: 15}, {X: 1, Y: 18}, {X: 2, Y: 18}, {X: 3, Y: 18}, {X: 1, Y: 17}, {X: 15, Y: 18}, {X: 16, Y: 18}, {X: 17, Y: 18}, {X: 18, Y: 18}, {X: 18, Y: 17}, {X: 18, Y: 16}, {X: 18, Y: 15}, {X: 17, Y: 17}, {X: 18, Y: 3}, {X: 18, Y: 2}, {X: 18, Y: 1}, {X: 18, Y: 0}, {X: 17, Y: 0}, {X: 16, Y: 0}, {X: 15, Y: 0}, {X: 17, Y: 1}, {X: 0, Y: 0}, {X: 1, Y: 0}, {X: 2, Y: 0}, {X: 3, Y: 0}, {X: 0, Y: 1}, {X: 0, Y: 2}, {X: 0, Y: 3}, {X: 1, Y: 1}, {X: 10, Y: 1}, {X: 8, Y: 1}, {X: 8, Y: 17}, {X: 10, Y: 17}, {X: 17, Y: 10}, {X: 17, Y: 8}, {X: 1, Y: 8}, {X: 1, Y: 10}, }