coding-horror/basic-computer-games · error · RuntimeException
Could not place any more ships
Error message
Could not place any more ships
What it means
Thrown as a RuntimeException by Ship.placeRandom() in the Battleship-style game after 1000 failed random attempts to fit the ship onto the Sea grid. Each attempt picks a random (x,y) start cell and one of four orientations, then calls place(). If none succeed, the sea is effectively saturated and the ship cannot fit. This is a constraint-violation: the total area demanded by all ships exceeds (or crowds out) the available board capacity given random placement.
Source
Thrown at 09_Battle/java/Ship.java:80
offset = (y - startY) / orientY;
}
return hits.get(offset);
};
// Place the ship in the sea.
// choose a random starting position, and a random direction
// if that doesn't fit, keep picking different positions and directions
public void placeRandom(Sea s) {
Random random = new Random();
for (int tries = 0 ; tries < 1000 ; ++tries) {
int x = random.nextInt(s.size());
int y = random.nextInt(s.size());
int orient = random.nextInt(4);
if (place(s, x, y, orient)) return;
}
throw new RuntimeException("Could not place any more ships");
}
// Attempt to fit the ship into the sea, starting from a given position and
// in a given direction
// This is by far the most complicated part of the program.
// It will start at the position provided, and attempt to occupy tiles in the
// requested direction. If it does not fit, either because of the edge of the
// sea, or because of ships already in place, it will try to extend the ship
// in the opposite direction instead. If that is not possible, it fails.
public boolean place(Sea s, int x, int y, int orient) {
if (placed) {
throw new RuntimeException("Program error - placed ship " + id + " twice");
}
switch(orient) {
case ORIENT_E: // east is increasing X coordinate
orientX = 1; orientY = 0;
break;
case ORIENT_SE: // southeast is increasing X and YView on GitHub (pinned to 5301155192)
Solutions
- Increase the Sea board size so total ship area fits comfortably.
- Reduce the number or sizes of ships placed.
- Raise the retry cap (1000) or switch placeRandom to a deterministic scan over every cell/orientation so a valid placement is found if one exists.
- Place larger ships before smaller ones to reduce fragmentation.
Example fix
// before
for (int tries = 0 ; tries < 1000 ; ++tries) {
int x = random.nextInt(s.size());
int y = random.nextInt(s.size());
int orient = random.nextInt(4);
if (place(s, x, y, orient)) return;
}
throw new RuntimeException("Could not place any more ships");
// after: exhaustive fallback before giving up
for (int x = 0; x < s.size(); x++)
for (int y = 0; y < s.size(); y++)
for (int orient = 0; orient < 4; orient++)
if (place(s, x, y, orient)) return;
throw new RuntimeException("Could not place any more ships"); Defensive patterns
Strategy: validation
Validate before calling
// Java: ensure the ship fleet fits the board before placing
public static boolean fleetFits(int boardSize, List<Integer> shipSizes) {
int total = shipSizes.stream().mapToInt(Integer::intValue).sum();
return total * 2 <= boardSize * boardSize; // leave headroom for random placement
} Try / catch
// Wrap placeRandom so a failed placement doesn't kill the game loop
try { ship.placeRandom(sea); }
catch (RuntimeException e) {
if (e.getMessage().contains("Could not place")) { /* retry with larger board or fewer ships */ }
else throw e;
} Prevention
- Place the largest ships first to reduce fragmentation.
- Keep the sum of ship lengths well below board area (e.g. <= 25-30%).
- Use an exhaustive scan fallback before declaring failure so a valid placement is always found if one exists.
When it happens
Trigger: Calling placeRandom() on a Sea whose free cells are too few or too fragmented to hold the ship's size; many ships already placed leaving no contiguous run long enough; a board size configuration where ship sizes sum close to or above size*size.
Common situations: Tuning game config to too many ships or too-large ships for a small grid; the fleet-to-board ratio makes random placement statistically fail within 1000 tries even when a valid placement exists (unlucky clustering).
Related errors
- YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE, IT MI
- AI RAN OUT OF OPTIONS!
- Failed to read line
AI-assisted analysis of coding-horror/basic-computer-games@5301155192 (2026-08-13).
Data as JSON: /api/errors/8a6c10ffd4893811.
Report an issue: GitHub.