Skip to content

Instantly share code, notes, and snippets.

@pastullo
Created February 22, 2023 15:43
Show Gist options
  • Save pastullo/aef45847625cff024704712c2a1d9636 to your computer and use it in GitHub Desktop.
Save pastullo/aef45847625cff024704712c2a1d9636 to your computer and use it in GitHub Desktop.
Battleship
const GRID_SIZE = 10;
const SHIP_SIZES = [5, 4, 4];
const board = new Array(GRID_SIZE).fill(null).map(() => new Array(GRID_SIZE).fill(0));
const hits = new Array(GRID_SIZE).fill(null).map(() => new Array(GRID_SIZE).fill(false));
// Let's place the ships on the board
for (let i = 0; i < SHIP_SIZES.length; i++) {
const size = SHIP_SIZES[i];
let row, col, dir;
do {
row = Math.floor(Math.random() * GRID_SIZE);
col = Math.floor(Math.random() * GRID_SIZE);
dir = Math.random() < 0.5 ? 'horizontal' : 'vertical';
} while (!canPlaceShip(row, col, dir, size));
// Each boat has a unique incremental id to distinguish it from the other ships.
// It's important to know if a ship has been fully sunk
for (let j = 0; j < size; j++) {
if (dir === 'horizontal') {
board[row][col + j] = i + 1;
} else {
board[row + j][col] = i + 1;
}
}
}
function canPlaceShip(row, col, dir, size) {
for (let i = 0; i < size; i++) {
if (dir === 'horizontal') {
if (col + i >= GRID_SIZE || board[row][col + i] !== 0) {
return false;
}
} else {
if (row + i >= GRID_SIZE || board[row + i][col] !== 0) {
return false;
}
}
}
return true;
}
function displayBattleshipBoard() {
const table = document.createElement('table');
table.style.borderCollapse = 'collapse';
for (let i = 0; i < GRID_SIZE; i++) {
const row = document.createElement('tr');
for (let j = 0; j < GRID_SIZE; j++) {
const cell = document.createElement('td');
cell.dataset.row = i;
cell.dataset.col = j;
// we display the boats to make it easier to debug the game
switch (board[i][j]) {
case 0:
cell.style.backgroundColor = 'white';
break;
case 1:
cell.style.backgroundColor = 'gray';
break;
case 2:
case 3:
cell.style.backgroundColor = 'lightgray';
break;
default:
cell.style.backgroundColor = 'gray';
}
row.appendChild(cell);
// We add a click event to each cell to let the player play
cell.addEventListener('click', handleClick);
}
table.appendChild(row);
}
document.body.appendChild(table);
}
function handleClick(event) {
const row = Number(event.target.dataset.row);
const col = Number(event.target.dataset.col);
if (hits[row][col]) {
alert('You already fired at this square!');
} else if (board[row][col] === 0) {
event.target.style.backgroundColor = 'blue';
hits[row][col] = true;
} else {
event.target.style.backgroundColor = 'red';
hits[row][col] = true;
const shipNumber = board[row][col];
if (isShipSunk(shipNumber)) {
alert('You sunk a full ship!');
}
}
}
// Define a function to check if a ship has been fully sunk by uysing the "unique" boat number
function isShipSunk(shipNumber) {
for (let i = 0; i < GRID_SIZE; i++) {
for (let j = 0; j < GRID_SIZE; j++) {
if (board[i][j] === shipNumber && !hits[i][j]) {
return false;
}
}
}
return true;
}
// Call the displayBoard function to display the game board
displayBattleshipBoard();
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Battleships Game Board</title>
<style type="text/css">
td {
border: 1px solid black;
width: 20px;
height: 20px;
}
</style>
</head>
<body>
<h3>Extra simple Battleship</h3>
<p style="color: gray;">By Flavio Bezzeccheri</p>
<p style="color: gray; font-size: 80%;">Enemy ships are visible for ease of testing.</p>
<script src="app.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment