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 thePlayer
andShip
class
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
name
length
position
orientation
hits
sunk
coordinates
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 theShip
class with the same properties
Represents each player.
Properties
role
board
ships
death
Main Methods
-
placeShip(ship)
: Adds a ship toships
-
moveShip(ship, newPosition)
: Changes the position of a ship, if valid -
moveToClosestValidPosition(ship, desiredPosition)
: It'smoveShip
on 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 theboard
with the data inships
-
createAttack(position)
: Adds an attack to bothships
andboard
-
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 ofmoveToClosestValidPosition
andpopulateRandomly
Serves as a bridge between Player
and the UI.
Properties
player
htmlBoard
htmlCells
htmlShips
cellSize
Main Methods
-
createBoard()
: Creates a 10x10 board ofhtmlCells
appended tohtmlBoard
-
renderAttacks()
: Renders theplayer.board
data 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 aship
on the board with an HTML ship image -
addInteract(htmlShip)
: Adds drag-and-drop and click interaction to an HTML ship element using theinteract.js
library. 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/battleship
Go to the project directory
cd battleship
Install dependencies
npm install
Start the server
npm run dev