Skip to content

Commit c5f96c6

Browse files
committed
adding chapter 8 code
1 parent 02e8156 commit c5f96c6

File tree

7 files changed

+616
-0
lines changed

7 files changed

+616
-0
lines changed

chapter8/battleship.html

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<title>Battleship</title>
5+
<meta charset="utf-8">
6+
<style>
7+
html, body {
8+
margin: auto;
9+
width: 1024px;
10+
background-color: black;
11+
}
12+
div#board {
13+
position: relative;
14+
width: 1024px;
15+
height: 863px;
16+
background: black url("board.jpg") no-repeat left top;
17+
}
18+
div#messageArea {
19+
position: absolute;
20+
top: 0px;
21+
left: 0px;
22+
color: rgb(83, 175, 19);
23+
}
24+
.hit {
25+
background: transparent url("ship.png") no-repeat center center;
26+
}
27+
.miss {
28+
background: transparent url("miss.png") no-repeat center center;
29+
}
30+
form {
31+
position: absolute;
32+
bottom: 0px;
33+
right: 0px;
34+
padding: 15px;
35+
background-color: rgb(83, 175, 19);
36+
}
37+
form input {
38+
background-color: #98CF71;
39+
border-color: rgb(83, 175, 19);
40+
font-size: 1em;
41+
}
42+
table {
43+
border-spacing: 0px;
44+
position: absolute;
45+
left: 173px;
46+
top: 98px;
47+
}
48+
td {
49+
width: 94px;
50+
height: 94px;
51+
}
52+
</style>
53+
</head>
54+
<body>
55+
<div id="board">
56+
<div id="messageArea"></div>
57+
<table>
58+
<tr>
59+
<td id="00"></td> <td id="01"></td> <td id="02"></td> <td id="03"></td>
60+
<td id="04"></td> <td id="05"></td> <td id="06"></td>
61+
</tr>
62+
<tr>
63+
<td id="10"></td> <td id="11"></td> <td id="12"></td> <td id="13"></td>
64+
<td id="14"></td> <td id="15"></td> <td id="16"></td>
65+
</tr>
66+
<tr>
67+
<td id="20"></td> <td id="21"></td> <td id="22"></td> <td id="23"></td>
68+
<td id="24"></td> <td id="25"></td> <td id="26"></td>
69+
</tr>
70+
<tr>
71+
<td id="30"></td> <td id="31"></td> <td id="32"></td> <td id="33"></td>
72+
<td id="34"></td> <td id="35"></td> <td id="36"></td>
73+
</tr>
74+
<tr>
75+
<td id="40"></td> <td id="41"></td> <td id="42"></td> <td id="43"></td>
76+
<td id="44"></td> <td id="45"></td> <td id="46"></td>
77+
</tr>
78+
<tr>
79+
<td id="50"></td> <td id="51"></td> <td id="52"></td> <td id="53"></td>
80+
<td id="54"></td> <td id="55"></td> <td id="56"></td>
81+
</tr>
82+
<tr>
83+
<td id="60"></td> <td id="61"></td> <td id="62"></td> <td id="63"></td>
84+
<td id="64"></td> <td id="65"></td> <td id="66"></td>
85+
</tr>
86+
</table>
87+
<form>
88+
<input type="text" id="guessInput" placeholder="A0">
89+
<input type="button" id="fireButton" value="Fire!">
90+
</form>
91+
</div>
92+
<script src="battleship.js">
93+
</script>
94+
</body>
95+
</html>

chapter8/battleship.js

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
var model = {
2+
boardSize: 7,
3+
numShips: 3,
4+
shipLength: 3,
5+
shipsSunk: 0,
6+
7+
ships: [
8+
{ locations: [0, 0, 0], hits: ["", "", ""] },
9+
{ locations: [0, 0, 0], hits: ["", "", ""] },
10+
{ locations: [0, 0, 0], hits: ["", "", ""] }
11+
],
12+
13+
// original hard-coded values for ship locations
14+
/*
15+
ships: [
16+
{ locations: ["06", "16", "26"], hits: ["", "", ""] },
17+
{ locations: ["24", "34", "44"], hits: ["", "", ""] },
18+
{ locations: ["10", "11", "12"], hits: ["", "", ""] }
19+
],
20+
*/
21+
22+
fire: function(guess) {
23+
for (var i = 0; i < this.numShips; i++) {
24+
var ship = this.ships[i];
25+
var index = ship.locations.indexOf(guess);
26+
27+
// here's an improvement! Check to see if the ship
28+
// has already been hit, message the user, and return true.
29+
if (ship.hits[index] === "hit") {
30+
view.displayMessage("Oops, you already hit that location!");
31+
return true;
32+
} else if (index >= 0) {
33+
ship.hits[index] = "hit";
34+
view.displayHit(guess);
35+
view.displayMessage("HIT!");
36+
37+
if (this.isSunk(ship)) {
38+
view.displayMessage("You sank my battleship!");
39+
this.shipsSunk++;
40+
}
41+
return true;
42+
}
43+
}
44+
view.displayMiss(guess);
45+
view.displayMessage("You missed.");
46+
return false;
47+
},
48+
49+
isSunk: function(ship) {
50+
for (var i = 0; i < this.shipLength; i++) {
51+
if (ship.hits[i] !== "hit") {
52+
return false;
53+
}
54+
}
55+
return true;
56+
},
57+
58+
generateShipLocations: function() {
59+
var locations;
60+
for (var i = 0; i < this.numShips; i++) {
61+
do {
62+
locations = this.generateShip();
63+
} while (this.collision(locations));
64+
this.ships[i].locations = locations;
65+
}
66+
console.log("Ships array: ");
67+
console.log(this.ships);
68+
},
69+
70+
generateShip: function() {
71+
var direction = Math.floor(Math.random() * 2);
72+
var row, col;
73+
74+
if (direction === 1) { // horizontal
75+
row = Math.floor(Math.random() * this.boardSize);
76+
col = Math.floor(Math.random() * (this.boardSize - this.shipLength));
77+
} else { // vertical
78+
row = Math.floor(Math.random() * (this.boardSize - this.shipLength));
79+
col = Math.floor(Math.random() * this.boardSize);
80+
}
81+
82+
var newShipLocations = [];
83+
for (var i = 0; i < this.shipLength; i++) {
84+
if (direction === 1) {
85+
newShipLocations.push(row + "" + (col + i));
86+
} else {
87+
newShipLocations.push((row + i) + "" + col);
88+
}
89+
}
90+
return newShipLocations;
91+
},
92+
93+
collision: function(locations) {
94+
for (var i = 0; i < this.numShips; i++) {
95+
var ship = this.ships[i];
96+
for (var j = 0; j < locations.length; j++) {
97+
if (ship.locations.indexOf(locations[j]) >= 0) {
98+
return true;
99+
}
100+
}
101+
}
102+
return false;
103+
}
104+
105+
};
106+
107+
108+
var view = {
109+
displayMessage: function(msg) {
110+
var messageArea = document.getElementById("messageArea");
111+
messageArea.innerHTML = msg;
112+
},
113+
114+
displayHit: function(location) {
115+
var cell = document.getElementById(location);
116+
cell.setAttribute("class", "hit");
117+
},
118+
119+
displayMiss: function(location) {
120+
var cell = document.getElementById(location);
121+
cell.setAttribute("class", "miss");
122+
}
123+
124+
};
125+
126+
var controller = {
127+
guesses: 0,
128+
129+
processGuess: function(guess) {
130+
var location = parseGuess(guess);
131+
if (location) {
132+
this.guesses++;
133+
var hit = model.fire(location);
134+
if (hit && model.shipsSunk === model.numShips) {
135+
view.displayMessage("You sank all my battleships, in " + this.guesses + " guesses");
136+
}
137+
}
138+
}
139+
}
140+
141+
142+
// helper function to parse a guess from the user
143+
144+
function parseGuess(guess) {
145+
var alphabet = ["A", "B", "C", "D", "E", "F", "G"];
146+
147+
if (guess === null || guess.length !== 2) {
148+
alert("Oops, please enter a letter and a number on the board.");
149+
} else {
150+
var row = alphabet.indexOf(guess.charAt(0));
151+
var column = guess.charAt(1);
152+
153+
if (isNaN(row) || isNaN(column)) {
154+
alert("Oops, that isn't on the board.");
155+
} else if (row < 0 || row >= model.boardSize ||
156+
column < 0 || column >= model.boardSize) {
157+
alert("Oops, that's off the board!");
158+
} else {
159+
return row + column;
160+
}
161+
}
162+
return null;
163+
}
164+
165+
166+
// event handlers
167+
168+
function handleFireButton() {
169+
var guessInput = document.getElementById("guessInput");
170+
var guess = guessInput.value.toUpperCase();
171+
172+
controller.processGuess(guess);
173+
174+
guessInput.value = "";
175+
}
176+
177+
function handleKeyPress(e) {
178+
var fireButton = document.getElementById("fireButton");
179+
180+
// in IE9 and earlier, the event object doesn't get passed
181+
// to the event handler correctly, so we use window.event instead.
182+
e = e || window.event;
183+
184+
if (e.keyCode === 13) {
185+
fireButton.click();
186+
return false;
187+
}
188+
}
189+
190+
191+
// init - called when the page has completed loading
192+
193+
window.onload = init;
194+
195+
function init() {
196+
// Fire! button onclick handler
197+
var fireButton = document.getElementById("fireButton");
198+
fireButton.onclick = handleFireButton;
199+
200+
// handle "return" key press
201+
var guessInput = document.getElementById("guessInput");
202+
guessInput.onkeypress = handleKeyPress;
203+
204+
// place the ships on the game board
205+
model.generateShipLocations();
206+
}
207+
208+
209+
210+
211+

0 commit comments

Comments
 (0)