diff --git a/engine/bot_local.go b/engine/bot_local.go index b71bf95..459e98b 100644 --- a/engine/bot_local.go +++ b/engine/bot_local.go @@ -77,7 +77,8 @@ func (b *RandomBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range state.Bots { if bot.Owner == state.You.ID { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + // Note: RandomBot doesn't have wall info, so pass nil for wallSet + if zoneDir := getZoneEscapeDirection(bot.Position, state, nil); zoneDir != DirNone { moves = append(moves, Move{ Position: bot.Position, Direction: zoneDir, diff --git a/engine/bot_strategies.go b/engine/bot_strategies.go index 8b8b43c..73b5416 100644 --- a/engine/bot_strategies.go +++ b/engine/bot_strategies.go @@ -8,7 +8,8 @@ import ( // getZoneEscapeDirection returns the direction toward the zone center if the bot is outside // or near the edge of the safe zone radius. Returns DirNone if the bot is safe or zone is disabled. -func getZoneEscapeDirection(botPos Position, state *VisibleState) Direction { +// Avoids walls when choosing the escape direction. +func getZoneEscapeDirection(botPos Position, state *VisibleState, wallSet map[Position]bool) Direction { if state.Zone == nil || !state.Zone.Active { return DirNone } @@ -40,7 +41,7 @@ func getZoneEscapeDirection(botPos Position, state *VisibleState) Direction { // This accounts for zone shrinking (1 tile/turn) and gives time to reach safety safetyMargin2 := 25 // (5 tiles)^2 - anticipates ~5 turns of zone shrink if dist2 >= radius2-safetyMargin2 { - // Move toward center: choose direction that reduces distance + // Move toward center: choose direction that reduces distance and avoids walls bestDir := DirNone bestReduction := 0 @@ -51,6 +52,13 @@ func getZoneEscapeDirection(botPos Position, state *VisibleState) Direction { Col: ((botPos.Col+ddc)%cols + cols) % cols, } + // Skip if blocked by wall (only check if wallSet is provided) + if wallSet != nil && wallSet[newPos] { + continue + } + // If wallSet is nil, assume all tiles are passable (RandomBot fallback) + // This is safe because the engine will ignore moves into walls + newDr := newPos.Row - center.Row newDc := newPos.Col - center.Col @@ -150,7 +158,7 @@ func (b *GathererBot) computeBotMove( state *VisibleState, ) *Move { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { return &Move{ Position: bot.Position, Direction: zoneDir, @@ -408,7 +416,7 @@ func (b *RusherBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range myBots { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { moves = append(moves, Move{Position: bot.Position, Direction: zoneDir}) continue } @@ -641,7 +649,7 @@ func (b *GuardianBot) computeBotMove( state *VisibleState, ) *Move { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { return &Move{Position: bot.Position, Direction: zoneDir} } @@ -868,7 +876,7 @@ func (b *SwarmBot) computeBotMove( state *VisibleState, ) *Move { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { return &Move{Position: bot.Position, Direction: zoneDir} } @@ -1113,7 +1121,7 @@ func (b *HunterBot) GetMoves(state *VisibleState) ([]Move, error) { } // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { moves = append(moves, Move{Position: bot.Position, Direction: zoneDir}) assignedHunters[bot.Position] = true continue @@ -1141,7 +1149,7 @@ func (b *HunterBot) GetMoves(state *VisibleState) ([]Move, error) { } // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallPositions); zoneDir != DirNone { moves = append(moves, Move{Position: bot.Position, Direction: zoneDir}) continue } diff --git a/engine/bot_strategies_phase13.go b/engine/bot_strategies_phase13.go index 12da89e..5597ca6 100644 --- a/engine/bot_strategies_phase13.go +++ b/engine/bot_strategies_phase13.go @@ -61,7 +61,7 @@ func (b *DefenderBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -155,7 +155,7 @@ func (b *ScoutBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range myBots { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dest := simulateMove(bot.Position, zoneDir, config.Rows, config.Cols) if !claimed[dest] { claimed[dest] = true @@ -260,7 +260,7 @@ func (b *FarmerBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -339,7 +339,7 @@ func (b *PacifistBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range myBots { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dest := simulateMove(bot.Position, zoneDir, config.Rows, config.Cols) if !claimed[dest] && !wallSet[dest] { claimed[dest] = true @@ -427,7 +427,7 @@ func (b *PhalanxBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range myBots { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dest := simulateMove(bot.Position, zoneDir, config.Rows, config.Cols) if !claimed[dest] && !wallSet[dest] { claimed[dest] = true @@ -518,7 +518,7 @@ func (b *RaiderBot) GetMoves(state *VisibleState) ([]Move, error) { } // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dest := simulateMove(bot.Position, zoneDir, config.Rows, config.Cols) if !claimed[dest] { claimed[dest] = true @@ -563,7 +563,7 @@ func (b *RaiderBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -656,7 +656,7 @@ func (b *NomadBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -767,7 +767,7 @@ func (b *OpportunistBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -865,7 +865,7 @@ func (b *AssassinBot) GetMoves(state *VisibleState) ([]Move, error) { var dir Direction // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dir = zoneDir } @@ -920,7 +920,7 @@ func (b *KamikazeBot) GetMoves(state *VisibleState) ([]Move, error) { for _, bot := range myBots { // Priority 1: Escape zone if threatened - if zoneDir := getZoneEscapeDirection(bot.Position, state); zoneDir != DirNone { + if zoneDir := getZoneEscapeDirection(bot.Position, state, wallSet); zoneDir != DirNone { dest := simulateMove(bot.Position, zoneDir, config.Rows, config.Cols) if !claimed[dest] && !wallSet[dest] { claimed[dest] = true