- Add ZoneBounds type to bot state structs (Go, Rust, TypeScript) - GathererBot now moves toward zone center when outside or near edge - Bots can see zone bounds in fog-filtered state (per plan §3.7.1) - Fixes gofmt formatting in types.go and bot_strategies.go This improves bot survival and combat behavior by making them zone-aware, preventing unnecessary zone deaths when the safe area shrinks. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
110 lines
2.3 KiB
TypeScript
110 lines
2.3 KiB
TypeScript
/**
|
|
* Game state types for AI Code Battle protocol.
|
|
*/
|
|
|
|
export interface Position {
|
|
row: number;
|
|
col: number;
|
|
}
|
|
|
|
export interface GameConfig {
|
|
rows: number;
|
|
cols: number;
|
|
max_turns: number;
|
|
vision_radius2: number;
|
|
attack_radius2: number;
|
|
spawn_cost: number;
|
|
energy_interval: number;
|
|
}
|
|
|
|
export interface PlayerInfo {
|
|
id: number;
|
|
energy: number;
|
|
score: number;
|
|
}
|
|
|
|
export interface VisibleBot {
|
|
position: Position;
|
|
owner: number;
|
|
}
|
|
|
|
export interface VisibleCore {
|
|
position: Position;
|
|
owner: number;
|
|
active: boolean;
|
|
}
|
|
|
|
export interface ZoneBounds {
|
|
center: Position;
|
|
radius: number;
|
|
active: boolean;
|
|
}
|
|
|
|
export interface GameState {
|
|
match_id: string;
|
|
turn: number;
|
|
config: GameConfig;
|
|
you: PlayerInfo;
|
|
bots: VisibleBot[];
|
|
energy: Position[];
|
|
cores: VisibleCore[];
|
|
walls: Position[];
|
|
dead: VisibleBot[];
|
|
zone?: ZoneBounds;
|
|
}
|
|
|
|
export type Direction = 'N' | 'E' | 'S' | 'W';
|
|
|
|
export interface Move {
|
|
position: Position;
|
|
direction: Direction;
|
|
}
|
|
|
|
export interface MoveResponse {
|
|
moves: Move[];
|
|
}
|
|
|
|
// Utility functions
|
|
|
|
export function posKey(pos: Position): string {
|
|
return `${pos.row},${pos.col}`;
|
|
}
|
|
|
|
export function posEquals(a: Position, b: Position): boolean {
|
|
return a.row === b.row && a.col === b.col;
|
|
}
|
|
|
|
export function moveToward(pos: Position, dir: Direction, rows: number, cols: number): Position {
|
|
switch (dir) {
|
|
case 'N':
|
|
return { row: (pos.row - 1 + rows) % rows, col: pos.col };
|
|
case 'E':
|
|
return { row: pos.row, col: (pos.col + 1) % cols };
|
|
case 'S':
|
|
return { row: (pos.row + 1) % rows, col: pos.col };
|
|
case 'W':
|
|
return { row: pos.row, col: (pos.col - 1 + cols) % cols };
|
|
}
|
|
}
|
|
|
|
export function distance2(a: Position, b: Position, rows: number, cols: number): number {
|
|
let dr = Math.abs(a.row - b.row);
|
|
let dc = Math.abs(a.col - b.col);
|
|
dr = Math.min(dr, rows - dr);
|
|
dc = Math.min(dc, cols - dc);
|
|
return dr * dr + dc * dc;
|
|
}
|
|
|
|
export function manhattanDistance(a: Position, b: Position, rows: number, cols: number): number {
|
|
let dr = Math.abs(a.row - b.row);
|
|
let dc = Math.abs(a.col - b.col);
|
|
dr = Math.min(dr, rows - dr);
|
|
dc = Math.min(dc, cols - dc);
|
|
return dr + dc;
|
|
}
|
|
|
|
export const ALL_DIRECTIONS: Direction[] = ['N', 'E', 'S', 'W'];
|
|
|
|
export function buildPositionSet(positions: Position[]): Set<string> {
|
|
return new Set(positions.map(posKey));
|
|
}
|