|
| 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