Battleship game with vanilla TypeScript.
The app has been built to be very user friendly.
Ship Placements
- Random shuffle as much as you want
- Drag-and-drop for positioning
- Click to switch orientation
- If a ship is placed on an invalid position, instead of throwing an error or not doing anything, the UI cleverly places it in a close valid position available
Quick Start
- Start playing in seconds with just two Enter key presses using the initial random ship shuffle
Visual UI
- Animations and disctintive colors for the different events make the game easy to follow and understand
Responsive
- Adapts to various screen sizes: desktop, tablet and mobile.
- Languages: TypeScript, CSS, HTML
- Build Tool: Vite
- Deployment: Netlify
- Interaction Dependency: interact.js
- Testing: ts-jest
Located in src:
styles: CSS stylests/classes: TypeScript classests/main.ts: Main functionality of the app with class usage and DOM manipulationts/__tests__: Jest tests for thePlayerandShipclass
Located in the root:
public: Images, font and screenshotsindex.html: Entry point for the app with dynamic injection of TypeScript and CSS
The project utilizes several TypeScript classes to organize data and encapsulate functionality.
Represents each ship.
Properties
namelengthpositionorientationhitssunkcoordinates
Methods
-
hit(): Increments the number of hits on the ship -
isSunk(): Returns a boolean indicating whether the ship is sunk -
get coordinates(): Getter method that computes coordinates based on lenght, position and orientation -
clone(): Creates a duplicate instance of theShipclass with the same properties
Represents each player.
Properties
roleboardshipsdeath
Main Methods
-
placeShip(ship): Adds a ship toships -
moveShip(ship, newPosition): Changes the position of a ship, if valid -
moveToClosestValidPosition(ship, desiredPosition): It'smoveShipon steroids. If the desired position is not valid, it explores close positions and places the ship as soon as it finds one. It also returns a boolean indicating if the valid position was found. -
switchShipOrientation(ship): Switches the orientation of a ship, if the switch results in an invalid placement, moves the ship to a close valid position by callingmoveToClosestValidPosition -
syncShipsToBoard(): Updates theboardwith the data inships -
createAttack(position): Adds an attack to bothshipsandboard -
async createDelayedRandomUnrepAttack(): Creates a delayed random unrepeated attack used by the computer. The delay improves the UX by giving the impression the computer is 'thinking' -
populateRandomly(): Randomly populates the player'sships -
isInvalidPlacement(candidateShip): Checks if a ship is in an invalid position (i.e. overlaps with other ships or goes out of bounds). This method is crucial for the correct functioning ofmoveToClosestValidPositionandpopulateRandomly
Serves as a bridge between Player and the UI.
Properties
playerhtmlBoardhtmlCellshtmlShipscellSize
Main Methods
-
createBoard(): Creates a 10x10 board ofhtmlCellsappended tohtmlBoard -
renderAttacks(): Renders theplayer.boarddata onhtmlBoard, setting the right color for each cell based on its hit status -
renderAttackAnimation(position): Renders an attack animation at the specified position -
renderShip(ship): Renders ashipon the board with an HTML ship image -
addInteract(htmlShip): Adds drag-and-drop and click interaction to an HTML ship element using theinteract.jslibrary. It reads the result of the interaction and updates the data inPlayer, ensuring it's always in sync with the UI -
removeInteractToAll(): Removes interaction from all HTML ship elements. Crucial for when the game starts -
setCellSize(): Sets and returns the cell size based on the window width for responsive design
Clone the project
git clone https://github.com/amadeuio/battleshipGo to the project directory
cd battleshipInstall dependencies
npm installStart the server
npm run dev
