Complete Go starter kit for AI Code Battle with: - main.go: HTTP server with HMAC authentication, placeholder computeMoves() - game/ package: Shared utilities (types, auth, grid) for reuse - types.go: Game state types, Direction constants, Position, etc. - auth.go: HMAC-SHA256 signing/verification with timestamp validation - grid.go: Toroidal distance, BFS pathfinding, neighbor functions - Tests: Comprehensive test coverage for grid and auth utilities - Dockerfile: Multi-stage build with Go 1.24-alpine - README: Complete documentation with examples and protocol reference The starter kit provides a minimal working bot that holds position by default. Participants implement their strategy in computeMoves() using the provided grid utilities. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
181 lines
5.8 KiB
Markdown
181 lines
5.8 KiB
Markdown
# acb-starter-go
|
|
|
|
Go starter kit for [AI Code Battle](https://aicodebattle.com) — a competitive bot programming platform where you write HTTP servers that control units on a grid world.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Set your bot secret (required for HMAC authentication)
|
|
export BOT_SECRET=your-secret-here
|
|
|
|
# Run locally
|
|
go run main.go
|
|
|
|
# Or build and run
|
|
go build -o bot && ./bot
|
|
```
|
|
|
|
Your bot listens on port 8080 and responds to `POST /turn` with move commands.
|
|
|
|
## Run with Docker
|
|
|
|
```bash
|
|
# Build the container
|
|
docker build -t my-go-bot .
|
|
|
|
# Run the container
|
|
docker run -e BOT_SECRET=your-secret-here -p 8080:8080 my-go-bot
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
.
|
|
├── main.go # HTTP server, request/response handling
|
|
├── game/ # Shared package (reuse in other projects!)
|
|
│ ├── types.go # Game state types and constants
|
|
│ ├── auth.go # HMAC signature verification
|
|
│ └── grid.go # Grid utilities (distance, BFS, neighbors)
|
|
├── go.mod # Go module definition
|
|
├── Dockerfile # Multi-stage container build
|
|
└── README.md # This file
|
|
```
|
|
|
|
## Implement Your Strategy
|
|
|
|
Edit `computeMoves()` in `main.go` to implement your bot's strategy. The function receives a `game.GameState` struct with:
|
|
|
|
- **`state.Bots`** — all visible bots (yours and enemies)
|
|
- **`state.Energy`** — visible energy pickup locations
|
|
- **`state.Cores`** — visible core positions
|
|
- **`state.Walls`** — visible wall positions
|
|
- **`state.You.ID`** — your player ID (0, 1, 2, etc.)
|
|
- **`state.You.Energy`** — your current energy count
|
|
- **`state.You.Score`** — your current score
|
|
- **`state.Config`** — match parameters (grid size, attack range, etc.)
|
|
|
|
Return a slice of `game.Move` structs, each with:
|
|
- **`Position`** — your bot's current position (row, col)
|
|
- **`Direction`** — one of: `"N"`, `"E"`, `"S"`, `"W"`
|
|
|
|
Any bot not included in the response stays in place.
|
|
|
|
### Example Strategy
|
|
|
|
```go
|
|
func computeMoves(state *game.GameState) []game.Move {
|
|
var moves []game.Move
|
|
|
|
for _, bot := range state.Bots {
|
|
if bot.Owner != state.You.ID {
|
|
continue
|
|
}
|
|
|
|
// Find nearest energy and move toward it
|
|
if len(state.Energy) > 0 {
|
|
nearest := state.Energy[0]
|
|
bestDist := game.ToroidalManhattan(bot.Position, nearest,
|
|
state.Config.Rows, state.Config.Cols)
|
|
|
|
for _, e := range state.Energy[1:] {
|
|
dist := game.ToroidalManhattan(bot.Position, e,
|
|
state.Config.Rows, state.Config.Cols)
|
|
if dist < bestDist {
|
|
bestDist = dist
|
|
nearest = e
|
|
}
|
|
}
|
|
|
|
// Use BFS to find direction toward energy
|
|
passable := func(p game.Position) bool {
|
|
// Simple passable check (you can add wall checking)
|
|
return true
|
|
}
|
|
dir := game.BFSDirection(bot.Position, nearest, passable,
|
|
state.Config.Rows, state.Config.Cols)
|
|
|
|
if dir != "" {
|
|
moves = append(moves, game.Move{
|
|
Position: bot.Position,
|
|
Direction: dir,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return moves
|
|
}
|
|
```
|
|
|
|
## Grid Utilities
|
|
|
|
The `game` package provides utility functions for the toroidal grid:
|
|
|
|
### Distance Calculations
|
|
|
|
- **`game.ToroidalManhattan(a, b, rows, cols)`** — Manhattan distance with wrap-around
|
|
- **`game.ToroidalDistance2(a, b, rows, cols)`** — Squared Euclidean distance with wrap
|
|
|
|
### Movement
|
|
|
|
- **`game.Neighbors(pos, rows, cols)`** — 4 cardinal neighbors (N, E, S, W)
|
|
- **`game.NeighborInDirection(pos, dir, rows, cols)`** — Move one step in a direction
|
|
- **`game.AllNeighbors(pos, rows, cols)`** — 8-directional neighbors (including diagonals)
|
|
|
|
### Pathfinding
|
|
|
|
- **`game.BFSDirection(start, goal, passable, rows, cols)`** — BFS pathfinding, returns the first direction to move (or empty string if no path)
|
|
|
|
The `passable` function should return `true` for positions the bot can enter (e.g., not walls).
|
|
|
|
## Authentication
|
|
|
|
The bot uses HMAC-SHA256 signatures for authentication:
|
|
|
|
- **Request verification**: Validates the `X-ACB-Signature` header from the engine
|
|
- **Response signing**: Adds `X-ACB-Signature` to all responses
|
|
- **Timestamp validation**: Rejects requests with timestamps outside ±30 seconds
|
|
|
|
The `BOT_SECRET` environment variable must be set. This secret is shared only between you and the game engine — never expose it publicly.
|
|
|
|
## Register Your Bot
|
|
|
|
Once your bot is deployed and accessible via HTTPS:
|
|
|
|
```bash
|
|
curl -X POST https://api.aicodebattle.com/api/register \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"name": "my-go-bot",
|
|
"endpoint_url": "https://my-bot.example.com",
|
|
"owner": "your-name",
|
|
"description": "My awesome Go bot"
|
|
}'
|
|
```
|
|
|
|
Save the `bot_id` and `shared_secret` from the response — the secret is shown only once.
|
|
|
|
## Protocol
|
|
|
|
- **`POST /turn`** — Main game loop endpoint (receives game state, returns moves)
|
|
- **`GET /health`** — Health check (must return 200 OK)
|
|
- **Timeout**: 3 seconds per turn
|
|
- **Authentication**: HMAC-SHA256 via `X-ACB-Signature` header
|
|
|
|
## Tips
|
|
|
|
- **The grid wraps around** — use the toroidal distance functions for accurate calculations
|
|
- **Fog of war** — you only see tiles within your vision radius
|
|
- **Energy spawns periodically** — check `state.Config.EnergyInterval`
|
|
- **Spawn cost** — spawning a bot costs 3 energy (`state.Config.SpawnCost`)
|
|
- **Combat** — bots within `AttackRadius2` may be destroyed each turn
|
|
|
|
## Further Reading
|
|
|
|
- [Full Game Protocol](https://aicodebattle.com/docs/protocol)
|
|
- [Replay Format](https://aicodebattle.com/docs/replay-format)
|
|
- [Strategy Guide](https://aicodebattle.com/docs/strategy)
|
|
|
|
## License
|
|
|
|
MIT — feel free to use this starter kit as a template for your own bot.
|