diff options
| author | Aiden Woodruff <aiden.woodruff@gmail.com> | 2018-04-14 12:58:50 -0500 |
|---|---|---|
| committer | Aiden Woodruff <aiden.woodruff@gmail.com> | 2018-04-14 12:58:50 -0500 |
| commit | 0f78eff7d00f90595010d63ccc1b8ef0f3e622d3 (patch) | |
| tree | b9ce7165c4f7fe5f348b911514d64563abe4edb3 | |
| parent | 9648ca074bc4df6b32f56776c20b5a00d550078b (diff) | |
| download | sweeper-0f78eff7d00f90595010d63ccc1b8ef0f3e622d3.tar.gz sweeper-0f78eff7d00f90595010d63ccc1b8ef0f3e622d3.tar.bz2 sweeper-0f78eff7d00f90595010d63ccc1b8ef0f3e622d3.zip | |
Fully works and added flagging
Created flag.png
Updated CSS for clagged cells
Signed-off-by: Aiden Woodruff <aiden.woodruff@gmail.com>
| -rw-r--r-- | ChangeLog | 88 | ||||
| -rw-r--r-- | flag.png | bin | 0 -> 224 bytes | |||
| -rw-r--r-- | index.html | 7 | ||||
| -rw-r--r-- | sweeper.js | 218 | ||||
| -rw-r--r-- | tiles.css | 6 |
5 files changed, 267 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..6b6f97f --- /dev/null +++ b/ChangeLog | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | 2018-04-14 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 2 | |||
| 3 | * flag.png: Flag image added. | ||
| 4 | |||
| 5 | * ChangeLog: Added, up to date based off Git logs. | ||
| 6 | |||
| 7 | * index.html: Added JavaScript populated mine count. | ||
| 8 | Added form to reload. | ||
| 9 | |||
| 10 | * tiles.css: Added CSS block for flagged class. | ||
| 11 | Gives TD background image. | ||
| 12 | |||
| 13 | * sweeper.js: Changed test for empty variables to test for any falsity. | ||
| 14 | Added mine count. | ||
| 15 | Each map value is an object rather than just a value. | ||
| 16 | Cell count is string rather than number. | ||
| 17 | Mines are filtered to insure 10 different mines. | ||
| 18 | `if' statements in count changed to executing {} blocks. | ||
| 19 | Assigns click and contextmenu listeners at page load. | ||
| 20 | (reveal): Removed debug log at beginning of onclick handler. | ||
| 21 | Changes behavior if argument is Event or HTML object. | ||
| 22 | Removes right click action. | ||
| 23 | Changed to switch case setup. | ||
| 24 | (flag): Added for right clicks on unrevealed cells. | ||
| 25 | Updates mine count. | ||
| 26 | |||
| 27 | 2018-04-13 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 28 | |||
| 29 | * index.html: JavaScript moved out. | ||
| 30 | Auto-indentation fixed. | ||
| 31 | Includes JavaScript files. | ||
| 32 | |||
| 33 | * sweeper.js: Script moved here. | ||
| 34 | |||
| 35 | 2018-04-12 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 36 | |||
| 37 | * http-get.js: File created. | ||
| 38 | Reads HTTP-GET variables. | ||
| 39 | |||
| 40 | * index.html: Create board with JavaScript. | ||
| 41 | |||
| 42 | * index.php: File deleted. | ||
| 43 | |||
| 44 | * other.html: Script moved from here to http-get.js | ||
| 45 | Includes http-get.js | ||
| 46 | |||
| 47 | 2018-04-12 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 48 | |||
| 49 | * index.php: Count tests for identicality, not equality after type-juggling. | ||
| 50 | Corrected some limit tests. | ||
| 51 | Removed most of debug comments. | ||
| 52 | |||
| 53 | * other.html: File added to test retrieving HTTP-GET parameters. | ||
| 54 | |||
| 55 | 2018-04-11 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 56 | |||
| 57 | * index.php: Corrected range of mines, where it was possible for them to be created outside of dimensions. | ||
| 58 | Changed bounds for x from height to width. | ||
| 59 | When assigning mines onto map, explicitly set keys to ints. | ||
| 60 | HTML comments output by PHP to determine source of some errors. | ||
| 61 | Dump $boardmap to determine why no numbers were output. | ||
| 62 | Partially fixed count loop. | ||
| 63 | JavaScript no longer included from sweeper.js | ||
| 64 | EventListeners added with PHP rather than with JavaScript | ||
| 65 | |||
| 66 | * tiles.css Darkened revealed tile colors | ||
| 67 | Change cursor type on unrevealed tiles. | ||
| 68 | Added definitions for unrevealed class. | ||
| 69 | |||
| 70 | 2018-04-10 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 71 | |||
| 72 | * .gitignore: File added. | ||
| 73 | Defined to ignore nano and Emacs autosaves. | ||
| 74 | |||
| 75 | * index.php: File added. | ||
| 76 | |||
| 77 | * tiles.css: File added. | ||
| 78 | |||
| 79 | 2018-04-09 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 80 | |||
| 81 | * LICENSE: LGPLv3 incorrectly added. Replaced with GPLv3. | ||
| 82 | |||
| 83 | 2018-04-08 Aiden Woodruff <aiden.woodruff@gmail.com> | ||
| 84 | |||
| 85 | * LICENSE: GPLv3 added. | ||
| 86 | |||
| 87 | * README.md: File added. | ||
| 88 | |||
diff --git a/flag.png b/flag.png new file mode 100644 index 0000000..be39164 --- /dev/null +++ b/flag.png | |||
| Binary files differ | |||
| @@ -11,5 +11,12 @@ | |||
| 11 | <body> | 11 | <body> |
| 12 | <h1>Minesweeper</h1> | 12 | <h1>Minesweeper</h1> |
| 13 | <table id="board" class="board"></table> | 13 | <table id="board" class="board"></table> |
| 14 | <p id="minecount"></p> | ||
| 15 | <form method="get" action="index.html"> | ||
| 16 | Width: <input type="text" name="width"> | ||
| 17 | Height: <input type="text" name="height"> | ||
| 18 | Mines: <input type="text" name="mines"> | ||
| 19 | <input type="submit" value="New Game"> | ||
| 20 | </form> | ||
| 14 | </body> | 21 | </body> |
| 15 | </html> | 22 | </html> |
| @@ -1,112 +1,226 @@ | |||
| 1 | // Test for HTTP-GET variables | ||
| 1 | var dimensions = read_http_get(["width", "height", "mines"]); | 2 | var dimensions = read_http_get(["width", "height", "mines"]); |
| 2 | if (dimensions["width"] === undefined || dimensions["width"] < 1) { | 3 | if (!dimensions["width"] || dimensions["width"] < 1) { |
| 3 | dimensions["width"] = 10; | 4 | dimensions["width"] = 10; |
| 4 | } | 5 | } |
| 5 | if (dimensions["height"] === undefined || dimensions["height"] < 1) { | 6 | if (!dimensions["height"] || dimensions["height"] < 1) { |
| 6 | dimensions["height"] = 10; | 7 | dimensions["height"] = 10; |
| 7 | } | 8 | } |
| 8 | if (dimensions["mines"] === undefined || dimensions["mines"] > dimensions["width"] * dimensions["height"]) { | 9 | if (!dimensions["mines"] || dimensions["mines"] > dimensions["width"] * dimensions["height"]) { |
| 9 | dimensions["mines"] = 20; | 10 | dimensions["mines"] = 20; |
| 10 | } | 11 | } |
| 12 | |||
| 11 | var boardmap = Array(); | 13 | var boardmap = Array(); |
| 12 | var mines = Array(); | 14 | var mines = Array(); |
| 15 | var unflagged = 0; | ||
| 16 | |||
| 17 | // Initialize Board array | ||
| 13 | for (var y = 0; y < dimensions["height"]; y++) { | 18 | for (var y = 0; y < dimensions["height"]; y++) { |
| 14 | boardmap[y] = Array(); | 19 | boardmap[y] = Array(); |
| 15 | for (x = 0; x < dimensions["width"]; x++) { | 20 | for (x = 0; x < dimensions["width"]; x++) { |
| 16 | boardmap[y][x] = 0; | 21 | boardmap[y][x] = { |
| 22 | value: "0", | ||
| 23 | state: "U" | ||
| 24 | } | ||
| 17 | } | 25 | } |
| 18 | } | 26 | } |
| 19 | for (var i = 0; i < dimensions["mines"]; i++) { | 27 | |
| 20 | boardmap[Math.floor(Math.random() * dimensions["height"])][Math.floor(Math.random() * dimensions["width"])] = "M"; | 28 | // Filter method |
| 29 | function onlyUnique(value, index, self) { | ||
| 30 | return self.indexOf(value) === index; | ||
| 31 | } | ||
| 32 | |||
| 33 | // Get random mine values | ||
| 34 | while (mines.length < dimensions["mines"]) { | ||
| 35 | mines.push( { | ||
| 36 | x: Math.floor(Math.random() * dimensions["width"]), | ||
| 37 | y: Math.floor(Math.random() * dimensions["height"]) | ||
| 38 | }); | ||
| 39 | mines.filter(onlyUnique); | ||
| 40 | } | ||
| 41 | |||
| 42 | unflagged = mines.length; | ||
| 43 | |||
| 44 | // Place mines | ||
| 45 | for (var i = 0; i < mines.length; i++) { | ||
| 46 | boardmap[mines[i].y][mines[i].x].value = "M"; | ||
| 21 | } | 47 | } |
| 22 | 48 | ||
| 23 | // Assign numbers | 49 | // Assign numbers |
| 24 | for (var y = 0, count = 0, width = dimensions["width"], height = dimensions["height"]; y < height; y++) { | 50 | for (var y = 0, count = 0, width = dimensions["width"], height = dimensions["height"]; y < height; y++) { |
| 25 | for (var x = 0; x < width; x++, count = 0) { | 51 | for (var x = 0; x < width; x++, count = 0) { |
| 26 | if (x > 0 && boardmap[y][x - 1] === "M") count++; | 52 | if (boardmap[y][x].value === "M") { |
| 27 | if (y > 0 && boardmap[y - 1][x] === "M") count++; | 53 | continue; |
| 28 | if (x < width - 1 && boardmap[y][x + 1] === "M") count++; | 54 | } |
| 29 | if (y < height - 1 && boardmap[y+1][x] === "M") count++; | 55 | if (x > 0 && boardmap[y][x - 1].value === "M") { |
| 30 | if (x > 0 && y > 0 && boardmap[y-1][x - 1] === "M") count++; | 56 | count++; |
| 31 | if (x > 0 && y < height - 1 && boardmap[y+1][x - 1] === "M") count++; | 57 | } |
| 32 | if (x < width - 1 && y > 0 && boardmap[y-1][x + 1] === "M") count++; | 58 | if (y > 0 && boardmap[y - 1][x].value === "M") { |
| 33 | if (x < width - 1 && y < height - 1 && boardmap[y + 1][x + 1] === "M") count++; | 59 | count++; |
| 34 | if (boardmap[y][x] !== "M") boardmap[y][x] = count; | 60 | } |
| 61 | if (x < width - 1 && boardmap[y][x + 1].value === "M") { | ||
| 62 | count++; | ||
| 63 | } | ||
| 64 | if (y < height - 1 && boardmap[y+1][x].value === "M") { | ||
| 65 | count++; | ||
| 66 | } | ||
| 67 | if (x > 0 && y > 0 && boardmap[y-1][x - 1].value === "M") { | ||
| 68 | count++; | ||
| 69 | } | ||
| 70 | if (x > 0 && y < height - 1 && boardmap[y+1][x - 1].value === "M") { | ||
| 71 | count++; | ||
| 72 | } | ||
| 73 | if (x < width - 1 && y > 0 && boardmap[y-1][x + 1].value === "M") { | ||
| 74 | count++; | ||
| 75 | } | ||
| 76 | if (x < width - 1 && y < height - 1 && boardmap[y + 1][x + 1].value === "M") { | ||
| 77 | count++; | ||
| 78 | } | ||
| 79 | boardmap[y][x].value = count.toString(); | ||
| 35 | } | 80 | } |
| 36 | } | 81 | } |
| 37 | 82 | ||
| 83 | // Retur cell object from x and y coordinates | ||
| 38 | function get_cell (x, y) { | 84 | function get_cell (x, y) { |
| 39 | return document.getElementById( (x.toString() + "," + y.toString() ) ); | 85 | return document.getElementById( (x.toString() + "," + y.toString() ) ); |
| 40 | } | 86 | } |
| 41 | 87 | ||
| 88 | // Return x y dict from cell object | ||
| 42 | function get_cell_xy (object) { | 89 | function get_cell_xy (object) { |
| 43 | coord = {}; | 90 | coord = {}; |
| 44 | coord.x = parseInt(object.id.substring(0, object.id.indexOf(",")), 10); | 91 | coord.x = parseInt(object.id.substring(0, object.id.indexOf(",")), 10); |
| 45 | coord.y = parseInt(object.id.substring(object.id.indexOf(",")+1), 10); | 92 | coord.y = parseInt(object.id.substring(object.id.indexOf(",")+1), 10); |
| 46 | return coord; | 93 | return coord; |
| 47 | } | 94 | } |
| 48 | function reveal (object) { | 95 | |
| 49 | console.log("Editing item with id: " + object.id); | 96 | // Reveal a cell |
| 97 | function reveal (e) { | ||
| 98 | if (e instanceof HTMLTableCellElement) { | ||
| 99 | var object = e; | ||
| 100 | } else if (e instanceof MouseEvent) { | ||
| 101 | var object = e.target; | ||
| 102 | } else { | ||
| 103 | return false; | ||
| 104 | } | ||
| 105 | var coord = get_cell_xy(object); | ||
| 106 | if (boardmap[coord.y][coord.x].state === "R") { | ||
| 107 | return; | ||
| 108 | } else if (boardmap[coord.y][coord.x].state === "U" || boardmap[coord.y][coord.x].state === "F") { | ||
| 109 | boardmap[coord.y][coord.x].state = "R"; | ||
| 110 | } | ||
| 111 | object.classList.remove("flagged"); | ||
| 50 | object.classList.remove("unrevealed"); | 112 | object.classList.remove("unrevealed"); |
| 51 | object.classList.add("revealed"); | 113 | object.classList.add("revealed"); |
| 52 | object.removeEventListener("click", reveal); | 114 | object.removeEventListener("click", reveal); |
| 53 | if (object.classList.contains("n0")) { | 115 | object.removeEventListener("contextmenu", flag); |
| 116 | switch(boardmap[coord.y][coord.x].value) { | ||
| 117 | case "0": | ||
| 54 | object.innerHTML = "0"; | 118 | object.innerHTML = "0"; |
| 55 | var coord = get_cell_xy(object); | ||
| 56 | var x = coord.x; | 119 | var x = coord.x; |
| 57 | var y = coord.y; | 120 | var y = coord.y; |
| 58 | var width = dimensions["width"]; | 121 | var width = dimensions["width"]; |
| 59 | var height = dimensions["height"]; | 122 | var height = dimensions["height"]; |
| 60 | if (x < width - 1) { | 123 | if (x < width - 1) { |
| 61 | reveal(get_cell(x + 1, y)); | 124 | reveal(get_cell(x + 1, y)); |
| 62 | } | 125 | } |
| 63 | if (x > 0 && y > 0) { | 126 | if (x > 0 && y > 0) { |
| 64 | reveal(get_cell(x - 1, y - 1)); | 127 | reveal(get_cell(x - 1, y - 1)); |
| 65 | } | 128 | } |
| 66 | if (x > 0) { | 129 | if (x > 0) { |
| 67 | reveal(get_cell(x - 1, y)); | 130 | reveal(get_cell(x - 1, y)); |
| 68 | } | 131 | } |
| 69 | if (x > 0 && y < height - 1) { | 132 | if (x > 0 && y < height - 1) { |
| 70 | reveal(get_cell(x - 1, y + 1)); | 133 | reveal(get_cell(x - 1, y + 1)); |
| 71 | } | 134 | } |
| 72 | if (y < height - 1) { | 135 | if (y < height - 1) { |
| 73 | reveal(get_cell(x, y + 1)); | 136 | reveal(get_cell(x, y + 1)); |
| 74 | } | 137 | } |
| 75 | if (x < width - 1 && y > 0) { | 138 | if (x < width - 1 && y > 0) { |
| 76 | reveal(get_cell(x + 1, y - 1)); | 139 | reveal(get_cell(x + 1, y - 1)); |
| 77 | } | 140 | } |
| 78 | if (y > 0) { | 141 | if (y > 0) { |
| 79 | reveal(get_cell(x, y - 1)); | 142 | reveal(get_cell(x, y - 1)); |
| 80 | } | 143 | } |
| 81 | if (x < width - 1 && y < height - 1) { | 144 | if (x < width - 1 && y < height - 1) { |
| 82 | reveal(get_text(x + 1, y + 1)); | 145 | reveal(get_cell(x + 1, y + 1)); |
| 83 | } | 146 | } |
| 84 | } else if (object.classList.contains("n1")) { | 147 | break; |
| 85 | object.innerHTML = "1"; | 148 | case "M": |
| 86 | } else if (object.classList.contains("n2")) { | 149 | for (var y = 0, td = undefined; y < height; y++) { |
| 87 | object.innerHTML = "2"; | 150 | for (var x = 0; x < width; x++) { |
| 88 | } else if (object.classList.contains("n3")) { | 151 | reveal(get_cell(x, y)); |
| 89 | object.innerHTML = "3"; | 152 | } |
| 90 | } else if (object.classList.contains("n4")) { | 153 | } |
| 91 | object.innerHTML = "4"; | ||
| 92 | } else if (object.classList.contains("n5")) { | ||
| 93 | object.innerHTML = "5"; | ||
| 94 | } else if (object.classList.contains("mine")) { | ||
| 95 | object.innerHTML = "M"; | 154 | object.innerHTML = "M"; |
| 155 | alert("You have lost. I'm so very sorry. :("); | ||
| 156 | break; | ||
| 157 | default: | ||
| 158 | object.innerHTML = boardmap[coord.y][coord.x].value; | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | function flag (e) { | ||
| 164 | if (e instanceof HTMLTableCellElement) { | ||
| 165 | var object = e; | ||
| 166 | } else if (e instanceof MouseEvent) { | ||
| 167 | var object = e.target; | ||
| 168 | e.preventDefault(); | ||
| 169 | } else { | ||
| 170 | return false; | ||
| 171 | } | ||
| 172 | var coord = get_cell_xy(object); | ||
| 173 | if (boardmap[coord.y][coord.x].state === "F") { | ||
| 174 | boardmap[coord.y][coord.x].state = "U"; | ||
| 175 | object.classList.remove("flagged"); | ||
| 176 | object.classList.add("unrevealed"); | ||
| 177 | unflagged++; | ||
| 178 | } else if (boardmap[coord.y][coord.x].state === "U") { | ||
| 179 | boardmap[coord.y][coord.x].state = "F"; | ||
| 180 | object.classList.remove("unrevealed"); | ||
| 181 | object.classList.add("flagged"); | ||
| 182 | unflagged--; | ||
| 183 | } else if (boardmap[coord.y][coord.x].state === "R") { | ||
| 184 | } | ||
| 185 | var allgone = true; | ||
| 186 | for (var i = 0; i < dimensions["mines"]; i++) { | ||
| 187 | if (boardmap[mines[i].y][mines[i].x].state !== "F") { | ||
| 188 | allgone = false; | ||
| 189 | } | ||
| 190 | } | ||
| 191 | if (allgone) { | ||
| 192 | var stuff = document.body.getElementsByTagName("td"); | ||
| 193 | for (var i = 0; i < stuff.length; i++) { | ||
| 194 | stuff[i].onclick = null; | ||
| 195 | stuff[i].oncontextmenu = null; | ||
| 196 | } | ||
| 197 | alert("Congratulations! You win."); | ||
| 198 | } else { | ||
| 199 | document.getElementById("minecount").innerHTML = "Mines: " + unflagged.toString(); | ||
| 96 | } | 200 | } |
| 97 | } | 201 | } |
| 202 | |||
| 98 | var table = ""; | 203 | var table = ""; |
| 99 | for (var y = 0; y < dimensions["height"]; y++) { | 204 | for (var y = 0; y < dimensions["height"]; y++) { |
| 100 | table += "<tr>"; | 205 | table += "<tr>"; |
| 101 | for (x = 0; x < dimensions["width"]; x++) { | 206 | for (x = 0; x < dimensions["width"]; x++) { |
| 102 | if (boardmap[y][x] !== "M") { | 207 | if (boardmap[y][x].value !== "M") { |
| 103 | table += "<td class='unrevealed n" + boardmap[y][x] + "' id='" + x + "," + y + "' onclick='reveal(this)'></td>"; | 208 | table += "<td class='unrevealed' n" + boardmap[y][x].value + "' id='" + x + "," + y + "'></td>"; |
| 104 | } else if (boardmap[y][x] === "M") { | 209 | } else if (boardmap[y][x].value === "M") { |
| 105 | table += "<td class='unrevealed mine' onclick='reveal(this)'></td>"; | 210 | table += "<td class='unrevealed mine' id='" + x + "," + y + "'></td>"; |
| 106 | } else { | 211 | } else { |
| 107 | table += "<td class='unrevealed null' onclick='reveal(this)'></td>"; | 212 | table += "<td class='unrevealed null' id='" + x + "," + y + "'></td>"; |
| 108 | } | 213 | } |
| 109 | } | 214 | } |
| 110 | table += "</tr>"; | 215 | table += "</tr>"; |
| 111 | } | 216 | } |
| 112 | window.onload = function () {document.getElementById("board").innerHTML = table}; | 217 | |
| 218 | window.onload = function () { | ||
| 219 | document.getElementById("board").innerHTML = table; | ||
| 220 | var tds = document.getElementsByTagName("td"); | ||
| 221 | for (var i = 0; i < tds.length; i++) { | ||
| 222 | tds[i].oncontextmenu = flag; | ||
| 223 | tds[i].onclick = reveal; | ||
| 224 | } | ||
| 225 | document.getElementById("minecount").innerHTML = "Mines: " + unflagged.toString(); | ||
| 226 | }; | ||
| @@ -19,3 +19,9 @@ td.revealed { | |||
| 19 | cursor: default; | 19 | cursor: default; |
| 20 | background-color: #c6c6c6; | 20 | background-color: #c6c6c6; |
| 21 | } | 21 | } |
| 22 | |||
| 23 | td.flagged { | ||
| 24 | cursor: pointer; | ||
| 25 | background-color: #c6c6c6; | ||
| 26 | background-image: url("flag.png"); | ||
| 27 | } | ||
