212 lines
4.8 KiB
JavaScript
Executable file
212 lines
4.8 KiB
JavaScript
Executable file
var model = {
|
|
boardSize: 7,
|
|
numShips: 3,
|
|
shipLength: 3,
|
|
shipsSunk: 0,
|
|
|
|
ships: [
|
|
{ locations: [0, 0, 0], hits: ["", "", ""] },
|
|
{ locations: [0, 0, 0], hits: ["", "", ""] },
|
|
{ locations: [0, 0, 0], hits: ["", "", ""] }
|
|
],
|
|
|
|
// original hard-coded values for ship locations
|
|
/*
|
|
ships: [
|
|
{ locations: ["06", "16", "26"], hits: ["", "", ""] },
|
|
{ locations: ["24", "34", "44"], hits: ["", "", ""] },
|
|
{ locations: ["10", "11", "12"], hits: ["", "", ""] }
|
|
],
|
|
*/
|
|
|
|
fire: function(guess) {
|
|
for (var i = 0; i < this.numShips; i++) {
|
|
var ship = this.ships[i];
|
|
var index = ship.locations.indexOf(guess);
|
|
|
|
// here's an improvement! Check to see if the ship
|
|
// has already been hit, message the user, and return true.
|
|
if (ship.hits[index] === "hit") {
|
|
view.displayMessage("Oops, you already hit that location!");
|
|
return true;
|
|
} else if (index >= 0) {
|
|
ship.hits[index] = "hit";
|
|
view.displayHit(guess);
|
|
view.displayMessage("HIT!");
|
|
|
|
if (this.isSunk(ship)) {
|
|
view.displayMessage("You sank my battleship!");
|
|
this.shipsSunk++;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
view.displayMiss(guess);
|
|
view.displayMessage("You missed.");
|
|
return false;
|
|
},
|
|
|
|
isSunk: function(ship) {
|
|
for (var i = 0; i < this.shipLength; i++) {
|
|
if (ship.hits[i] !== "hit") {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
},
|
|
|
|
generateShipLocations: function() {
|
|
var locations;
|
|
for (var i = 0; i < this.numShips; i++) {
|
|
do {
|
|
locations = this.generateShip();
|
|
} while (this.collision(locations));
|
|
this.ships[i].locations = locations;
|
|
}
|
|
console.log("Ships array: ");
|
|
console.log(this.ships);
|
|
},
|
|
|
|
generateShip: function() {
|
|
var direction = Math.floor(Math.random() * 2);
|
|
var row, col;
|
|
|
|
if (direction === 1) { // horizontal
|
|
row = Math.floor(Math.random() * this.boardSize);
|
|
col = Math.floor(Math.random() * (this.boardSize - this.shipLength + 1));
|
|
} else { // vertical
|
|
row = Math.floor(Math.random() * (this.boardSize - this.shipLength + 1));
|
|
col = Math.floor(Math.random() * this.boardSize);
|
|
}
|
|
|
|
var newShipLocations = [];
|
|
for (var i = 0; i < this.shipLength; i++) {
|
|
if (direction === 1) {
|
|
newShipLocations.push(row + "" + (col + i));
|
|
} else {
|
|
newShipLocations.push((row + i) + "" + col);
|
|
}
|
|
}
|
|
return newShipLocations;
|
|
},
|
|
|
|
collision: function(locations) {
|
|
for (var i = 0; i < this.numShips; i++) {
|
|
var ship = this.ships[i];
|
|
for (var j = 0; j < locations.length; j++) {
|
|
if (ship.locations.indexOf(locations[j]) >= 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
};
|
|
|
|
|
|
var view = {
|
|
displayMessage: function(msg) {
|
|
var messageArea = document.getElementById("messageArea");
|
|
messageArea.innerHTML = msg;
|
|
},
|
|
|
|
displayHit: function(location) {
|
|
var cell = document.getElementById(location);
|
|
cell.setAttribute("class", "hit");
|
|
},
|
|
|
|
displayMiss: function(location) {
|
|
var cell = document.getElementById(location);
|
|
cell.setAttribute("class", "miss");
|
|
}
|
|
|
|
};
|
|
|
|
var controller = {
|
|
guesses: 0,
|
|
|
|
processGuess: function(guess) {
|
|
var location = parseGuess(guess);
|
|
if (location) {
|
|
this.guesses++;
|
|
var hit = model.fire(location);
|
|
if (hit && model.shipsSunk === model.numShips) {
|
|
view.displayMessage("You sank all my battleships, in " + this.guesses + " guesses");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// helper function to parse a guess from the user
|
|
|
|
function parseGuess(guess) {
|
|
var alphabet = ["A", "B", "C", "D", "E", "F", "G"];
|
|
|
|
if (guess === null || guess.length !== 2) {
|
|
alert("Oops, please enter a letter and a number on the board.");
|
|
} else {
|
|
var firstChar = guess.charAt(0);
|
|
var row = alphabet.indexOf(firstChar);
|
|
var column = guess.charAt(1);
|
|
|
|
if (isNaN(row) || isNaN(column)) {
|
|
alert("Oops, that isn't on the board.");
|
|
} else if (row < 0 || row >= model.boardSize ||
|
|
column < 0 || column >= model.boardSize) {
|
|
alert("Oops, that's off the board!");
|
|
} else {
|
|
return row + column;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
// event handlers
|
|
|
|
function handleFireButton() {
|
|
var guessInput = document.getElementById("guessInput");
|
|
var guess = guessInput.value.toUpperCase();
|
|
|
|
controller.processGuess(guess);
|
|
|
|
guessInput.value = "";
|
|
}
|
|
|
|
function handleKeyPress(e) {
|
|
var fireButton = document.getElementById("fireButton");
|
|
|
|
// in IE9 and earlier, the event object doesn't get passed
|
|
// to the event handler correctly, so we use window.event instead.
|
|
e = e || window.event;
|
|
|
|
if (e.keyCode === 13) {
|
|
fireButton.click();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// init - called when the page has completed loading
|
|
|
|
window.onload = init;
|
|
|
|
function init() {
|
|
// Fire! button onclick handler
|
|
var fireButton = document.getElementById("fireButton");
|
|
fireButton.onclick = handleFireButton;
|
|
|
|
// handle "return" key press
|
|
var guessInput = document.getElementById("guessInput");
|
|
guessInput.onkeypress = handleKeyPress;
|
|
|
|
// place the ships on the game board
|
|
model.generateShipLocations();
|
|
}
|
|
|
|
|
|
|
|
|
|
|