A competitive battleship game server where engineering teams build bots to compete via REST API. Build your bot, compete with others, and prove your coding skills!
Ready to build your battleship bot? Start with our comprehensive API documentation and example bot implementations.
POST /bots
Complete OpenAPI 3.0 specification with interactive Swagger UI. Test endpoints, understand schemas, and see examples.
Spectate ongoing battles and learn from other players' strategies in real-time.
Learn by example! Here's how to register a bot and start playing:
Register your bot and receive a game ID immediately. The server automatically pairs you with another bot or puts you in queue.
Poll game state to detect when both players are ready. Game progresses from WAITING_FOR_PLAYERS → PLACING_SHIPS → IN_PROGRESS.
Strategically place all 5 ships when game state is PLACING_SHIPS. Each ship has a specific size:
Poll game state to wait for your turn, then fire at coordinates and repeat until completion
Avoid predictable patterns. Use board dimensions dynamically and query game rules programmatically.
Consider probability-based targeting after hits. Balance systematic searching vs random shots.
Use systematic patterns to efficiently search for enemy ships across the board.
When you hit a ship, focus on sinking it completely before moving to new areas.
Query /api/docs for current rules rather than hardcoding assumptions about board size.
Maintain probability maps and track opponent patterns for predictive targeting.
Understanding how bots get matched and games begin:
When you register, you receive a game ID immediately - no waiting required. The server either pairs you with an existing waiting bot or puts you in queue for the next registration.
Use the game ID to poll GET /games/{gameId}/state and watch for state transitions:
WAITING_FOR_PLAYERS - You're registered but need an opponentPLACING_SHIPS - Opponent found! Time to place your shipsIN_PROGRESS - Both players ready, game activeCOMPLETED - Game finished
// 1. Register and get immediate game assignment
const registration = await fetch('/bots', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'MyBot' })
});
const { gameId, accessToken } = await registration.json();
// 2. Monitor game state until ready
async function waitForGameStart() {
while (true) {
const response = await fetch(`/games/${gameId}/state`, {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
const gameState = await response.json();
if (gameState.state === 'PLACING_SHIPS') {
console.log('Game ready! Start placing ships');
return gameState;
}
console.log('Current state:', gameState.state);
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
class MyBot {
async register(name: string) {
// Register with server and store auth tokens
const response = await fetch('https://battleship.lab.voze.com/bots', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name })
});
return response.json();
}
async placeShips(gameId: string, token: string) {
// Implement your ship placement strategy
const ships = this.generateShipPlacements();
return fetch(`https://battleship.lab.voze.com/games/${gameId}/place-ships`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ ships })
});
}
async waitForTurn(gameId: string, token: string) {
// Poll until it's your turn or game ends
while (true) {
const response = await this.getGameState(gameId, token);
const gameState = await response.json();
if (gameState.state === 'COMPLETED') {
console.log('Game completed!', gameState.winner);
break;
}
if (gameState.isYourTurn) {
console.log('It\'s your turn!');
return gameState;
}
// Wait 2 seconds before polling again
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
async makeMove(gameId: string, token: string) {
// Implement your firing strategy
const coordinate = this.calculateNextShot();
return fetch(`https://battleship.lab.voze.com/games/${gameId}/fire`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ coordinate })
});
}
async getGameState(gameId: string, token: string) {
// Poll for game updates
return fetch(`https://battleship.lab.voze.com/games/${gameId}/state`, {
headers: { 'Authorization': `Bearer ${token}` }
});
}
}When it's your turn, the game state response will look like this:
{
"gameId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"state": "IN_PROGRESS",
"isYourTurn": true,
"boardDimensions": {
"width": 10,
"height": 10
},
"yourBoard": {
"hits": [
{"x": 2, "y": 3},
{"x": 5, "y": 7}
],
"misses": [
{"x": 0, "y": 0},
{"x": 1, "y": 1}
],
"shipsRemaining": 4
},
"opponentBoard": {
"hits": [
{"x": 6, "y": 2},
{"x": 8, "y": 4}
],
"misses": [
{"x": 3, "y": 3},
{"x": 9, "y": 9}
],
"shipsRemaining": 3
},
"winner": null
}
Key fields to monitor: isYourTurn indicates when you can fire, state shows game progress, and boardDimensions provides current board size for coordinate validation.
Built with ❤️ for the engineering community • Health Check • API Docs