Project Plateau
Project Plateau: four glass plates, one living valley, and the road back to camp.
A Punic Wars themed Battleship game: Rome versus Carthage.
Translation pending
GamesTypeScript · CSSGitHub @ianmotz21OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
A Punic Wars–themed Battleship game built with Next.js and TypeScript, developed and debugged with Devin.
Loading the full README.
Read the full README ↗A Punic Wars-themed Battleship game built with Next.js and TypeScript. You command the Roman fleet against an AI-controlled Carthaginian navy, in a single-page browser game.
localStorage). It ranks your best victories by fewest shots, can filter by difficulty, and shows your win/loss record.R key), with a live preview that shows valid and invalid squares. Overlapping and off-board placements are blocked.Requires Node.js 20.9 or later.
git clone https://github.com/ianmotz21/ianmotz-battleship.git
cd ianmotz-battleship
npm install
npm run dev
Then open http://localhost:3000.
| Command | Purpose |
|---|---|
npm run dev | Development server with hot reload |
npm run build then npm run start | Production build and server |
npm test | Core game logic tests |
npm run lint | ESLint |
npx tsc --noEmit | Type check |
eslint-config-next)src/
app/
page.tsx Page layout: title, sound toggle, game
globals.css Theme colours and fonts
components/
Game.tsx Home/battle screens, game state and turn flow (single source of truth)
HomeScreen.tsx Main menu: difficulty, Start Battle, Leaderboard, How to Play
Board.tsx Presentational 10x10 board used for both fleets
PlayerFleet.tsx Ship selection and placement controls
Celebration.tsx Victory confetti and defeat ash overlay
BattleIntro.tsx "The Battle Begins" title card shown as a battle opens
Insignia.tsx SVG standards, laurels and commander medallions
SoundToggle.tsx Mute button, saved in localStorage
lib/
fleet.ts Fleet definitions and placement/hit/sunk rules (pure functions)
ai.ts Carthage's targeting for each difficulty level
leaderboard.ts Saved game results and leaderboard ranking (localStorage)
sound.ts Synthesized sound effects
battleMessages.ts Themed hit and miss commentary
gameLogic.test.ts Tests for shots, sinking, winning, placement and the AI
fleet.ts holds the rules as pure functions that don't touch React: checkPlacement, randomPlacements, shipAt, sunkShipIds, and fireShot, which resolves a single shot. Both the player's placement and the AI's placement use the same rules.Game.tsx shows the home screen first. Start Battle opens a fresh battle against the chosen difficulty. Main menu returns home, and asks for confirmation if a battle is under way. Every finished game is saved to the leaderboard; abandoned games are not.Game.tsx owns all game state: both fleets, both sets of shots (Map<coord, "hit" | "miss">), whose turn it is, and the winner. The boards only display what they're given.fireShot also rejects a repeat shot.cacheComponents, and doesn't allow random values during that step. The layout is kept in a React ref, so it doesn't appear in the page until a ship is sunk.This is the beginning of the README. Read the rest at the original. Read the full README ↗