Two-Player Terminal Battleship: Ship Placement From Input, Then Turn-Based Attacks
Company: Citadel
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
Write a Battleship game from scratch as a class that runs in the terminal. Two players share the terminal and take turns. Each player places ships on their own board by typing a ship's coordinates and size at the prompt. As a follow-up, the players take turns attacking each other's ships.
The interviewer expects runnable code, not only a design, and the amount of code is large for a phone screen, so plan an order of work that gets a playable version running in the terminal early.
### Constraints and Clarifications
- The board size, the fleet and the input format were not specified. Choose them, state them, and make the board size and the fleet easy to change.
- All input arrives as lines typed in the terminal and may be malformed. The program must ask again rather than crash.
- Each player has a separate board, and a player must never be shown where the opponent's ships are.
### Clarifying Questions
- How large is the board, and does each player place a fixed set of ship sizes or choose sizes freely?
- How is a ship described: a start cell, a size and an orientation, or a start cell and an end cell? Are coordinates numbers, or a letter and a number such as `B4`?
- Must ships lie fully on the board, and may they touch or overlap?
- During setup, does each player place the whole fleet in one turn, or do the players alternate ship by ship?
- Because both players share one terminal, should a player's board be hidden before the other player's turn?
### Part 1 — Board, ships and placement
Implement the game class, and the classes it needs, so that the two players in turn place their ships by entering a ship's coordinates and size in the terminal. Reject an invalid placement with a message and ask again, and let the player see their own board while placing.
```hint Model before the loop
Decide which objects exist (game, player, board, ship) and what each one owns before writing any input parsing. A ship that knows its own cells makes the follow-up much easier.
```
```hint One place to say no
Off-board cells, overlaps, a size the player cannot use and malformed input are all reasons to reject a placement. Gather the checks so that a rejection leaves the board exactly as it was.
```
#### What This Part Should Cover
- A class structure that separates game flow, per-player state, the board and ships
- Parsing a typed line into a placement, with recoverable error messages
- Placement validation (bounds, overlap, allowed size) that never leaves a partly placed ship
- Turn handling between the two players during setup
### Part 2 — Follow-up: attacking
Extend the game so that, once both fleets are placed, the players take turns attacking a cell on the opponent's board. Report the result of each attack to the attacker, show the attacker what they know of the opponent's board, and end the game when one player's ships have all been sunk.
```hint What a shot needs to know
To report a hit, a sinking or a win without scanning the whole board, think about which lookup the board needs from a cell to a ship, and what each ship should keep count of.
```
```hint The same cell twice
Decide what happens when a player targets a cell they have already shot, and make sure it cannot change any ship's state.
```
#### Clarifying Questions for this Part
- Does a hit earn the attacker another shot, or do turns always alternate?
- Should the result distinguish a hit from a hit that sinks the ship?
- Is shooting an already targeted cell an error that lets the player shoot again, or a wasted turn?
#### What This Part Should Cover
- Resolving an attack: miss, hit, sunk, repeated target and off-board target
- Tracking hits per ship and detecting the end of the game
- Two different views: a player's own board and the tracking view of the opponent's board
- The complete game loop from placement through attacks to a winner
### What a Strong Answer Covers
- A runnable game in the terminal, reached early and extended in small steps
- Game rules kept separate from terminal input and output, so the rules can be tested without typing
- Robust handling of bad input at every prompt, without crashes or corrupted state
- Data structures that make placement checks and attack resolution simple and fast
- Readable code with small methods and clear names, given the volume of code
### Follow-up Questions
- How would you unit test placement and attacks without driving the terminal by hand?
- How would you add a computer opponent that places ships and chooses targets?
- What would change if the two players played from separate terminals or machines?
- How would you support ships that are not straight lines, or a much larger board, without rewriting the core classes?
Overview: Build a two-player Battleship game as a class that runs in the terminal, with players taking turns to place ships by typing coordinates and sizes, then extend it so they can attack each other's fleets. It tests object modeling, input parsing and validation, turn handling, and delivering a large amount of working code under time pressure.