aboutsummaryrefslogtreecommitdiff
path: root/utils/minesweeper
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2020-10-31 17:25:22 +0100
committerCharles Cabergs <me@cacharle.xyz>2020-10-31 17:26:22 +0100
commitb4ef14a7e010c1b468928d29a981fdf6ba700563 (patch)
tree0612dc0b8c40a98baf149bbcde787fa411592baa /utils/minesweeper
parenta3103caf417899b60519ffde44bc07a15c71b75a (diff)
downloadcacharle.xyz-b4ef14a7e010c1b468928d29a981fdf6ba700563.tar.gz
cacharle.xyz-b4ef14a7e010c1b468928d29a981fdf6ba700563.tar.bz2
cacharle.xyz-b4ef14a7e010c1b468928d29a981fdf6ba700563.zip
Added minesweeper logic, style, settings
Diffstat (limited to 'utils/minesweeper')
-rw-r--r--utils/minesweeper/index.html105
-rw-r--r--utils/minesweeper/script.js130
2 files changed, 200 insertions, 35 deletions
diff --git a/utils/minesweeper/index.html b/utils/minesweeper/index.html
index 16ab664..546d0f8 100644
--- a/utils/minesweeper/index.html
+++ b/utils/minesweeper/index.html
@@ -5,28 +5,105 @@
<title>cacharle - minesweeper</title>
<link rel="stylesheet" type="text/css" href="../../style.css"/>
<meta charset="utf-8"/>
- <link rel="icon" type="image/png" href="../../favicon.png" />
+ <link rel="icon" type="image/png" href="../../favicon.png" />
+ <style>
+ h1 {
+ text-align: center;
+ }
+ td {
+ padding: 0px;
+ }
+ table {
+ margin: auto;
+ margin-top: 0%;
+ margin-bottom: 5%;
+ border-collapse: collapse;
+ border-spacing: 0px;
+ }
+ table td {
+ width: 2.5em;
+ height: 2.5em;
+ }
+ table button {
+ display: block;
+ background: lightgrey;
+ margin: 0px;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ font-size: 1.6em;
+ border-width: 6px;
+ border-style: outset;
+ border-radius: 0px;
+ border-color: grey;
+ }
+ table button:hover {
+ background: forestgreen;
+ }
+ table button.visited {
+ background: lightgrey;
+ border-style: solid;
+ border-width: 1px;
+ }
+ button {
+ font-weight: bold;
+ }
+
+ label,
+ input {
+ display: inline-block;
+ }
+ label {
+ width: 13%;
+ text-align: right;
+ }
+ input {
+ width: 40%;
+ margin: 0px;
+ }
+ button.game-state {
+ float: right;
+ margin-right: 20%;
+ font-size: 2em;
+ text-transform: uppercase;
+ }
+ #minesweeper-timer {
+ display: block;
+ font-weight: bolder;
+ text-align: center;
+
+ }
+
+ </style>
</head>
<body><div id="page-wrapper">
<h1>minesweeper</h1>
- <div>
- before start
- size:
- <input type="range"/>
- mine rate:
- <input type="range"/>
- <button>start</button>
- </div>
- <div>
- during
- <div>timer</div>
- <button>start</button>
+ <table id="minesweeper-table">
+ </table>
+
+ <div id="minesweeper-settings">
+ <button id="minesweeper-start" class="game-state">start</button>
+ <div>
+ <label for="width">width</label>
+ <input id="minesweeper-width" name="width" type="range" min="3" max="20" value="10"/>
+ </div>
+ <div>
+ <label for="height">height</label>
+ <input id="minesweeper-height" name="height" type="range" min="3" max="20" value="10"/>
+ </div>
+ <div>
+ <label for="mine-rate">mine rate</label>
+ <input id="minesweeper-mine-rate" name="mine-rate" type="range" min="0" max="100" value="20"/>
+ </div>
+ </div>
+ <div id="minesweeper-game-info" hidden>
+ <button id="minesweeper-stop" class="game-state">stop</button>
+ <div id="minesweeper-timer">timer</div>
</div>
- <canvas id="minesweeper-canvas"></canvas>
</div></body>
<script src="script.js" type="text/javascript"></script>
diff --git a/utils/minesweeper/script.js b/utils/minesweeper/script.js
index 5679d75..059efdf 100644
--- a/utils/minesweeper/script.js
+++ b/utils/minesweeper/script.js
@@ -1,31 +1,119 @@
-const height = 10
-const width = 10
-const mine_rate = 0.30
+let height = 10
+let width = 10
+let mine_rate = 0.10
+let timer = undefined
let mines = []
let visited = []
-for (i = 0; i < height; i++) {
- mines.push(new Array(width))
- visited.push(new Array(width))
- for (j = 0; j < width; j++) {
- mines[i][j] = Math.random() < mine_rate ? -1 : 0;
- visited[i][j] = false;
- }
+let running = false
+
+function isValidPos(y, x) {
+ return y >= 0 && y < height && x >= 0 && x < width
+}
+
+function* neighboursGenerator(y, x) {
+ for (let i = -1; i <= 1; i++) {
+ for (let j = -1; j <= 1; j++) {
+ if (i === 0 && j === 0)
+ continue
+ let ret = [y + i, x + j]
+ if (!isValidPos(...ret))
+ continue
+ yield ret
+ }
+ }
}
-canvas = document.getElementById("minesweeper-canvas")
-context = canvas.getContext("2d")
-console.log(context)
+let cells = []
+
+function floodFill(y, x) {
+ visited[y][x] = true
+ let cell = cells[y][x]
+ cell.classList.add("visited")
+ if (mines[y][x] !== 0)
+ cell.textContent = mines[y][x]
+ switch (mines[y][x]) {
+ case 1: cell.style.color = "blue"; break
+ case 2: cell.style.color = "green"; break
+ case 3: cell.style.color = "red"; break
+ case 4: cell.style.color = "darkblue"; break
+ case 5: cell.style.color = "brown"; break
+ case 6: cell.style.color = "cyan"; break
+ case 7: cell.style.color = "black"; break
+ case 8: cell.style.color = "grey"; break
+ }
+ if (mines[y][x] !== 0)
+ return
+ for (let [ny, nx] of neighboursGenerator(y, x))
+ if (!visited[ny][nx])
+ floodFill(ny, nx)
+}
+
+function initGrid() {
+ let table = document.getElementById("minesweeper-table")
+ table.innerHTML = ""
+
+ width = document.getElementById("minesweeper-width").value
+ height = document.getElementById("minesweeper-height").value
+ mine_rate = document.getElementById("minesweeper-mine-rate").value / 100
-const cell_width = canvas.width / width
-const cell_height = canvas.height / height
-const cell_size = Math.min(cell_width, cell_height)
+ mines = []
+ visited = []
+ cells = []
-for (i = 0; i < height; i++) {
- for (j = 0; j < width; j++) {
- context.strokeRect(cell_size * j, cell_size * i, cell_size, cell_size);
- }
+ for (let i = 0; i < height; i++) {
+ mines.push(new Array(width))
+ visited.push(new Array(width))
+ for (let j = 0; j < width; j++) {
+ mines[i][j] = Math.random() < mine_rate ? -1 : 0;
+ visited[i][j] = false;
+ }
+ }
+
+ // count neighbour mines
+ for (let i = 0; i < height; i++) {
+ for (let j = 0; j < width; j++) {
+ if (mines[i][j] === -1)
+ continue
+ mines[i][j] =
+ [...neighboursGenerator(i, j)]
+ .filter(([y, x]) => mines[y][x] === -1)
+ .length
+ }
+ }
+
+ for (let i = 0; i < height; i++) {
+ cells.push([])
+ let table_row = document.createElement("tr")
+ for (let j = 0; j < width; j++) {
+ let table_cell = document.createElement("td")
+ let cell = document.createElement("button")
+ cell.textContent = ""
+ cell.addEventListener("click", () => floodFill(i, j))
+ cells[i].push(cell)
+ table_cell.appendChild(cell)
+ table_row.appendChild(table_cell)
+ }
+ table.appendChild(table_row)
+ }
+}
+
+for (input of document.querySelectorAll("#minesweeper-settings input")) {
+ input.addEventListener("input", () => initGrid())
}
-// canvas.addEventListener("click", () => {})
+function toggleRunning() {
+ running = !running
+ settings = document.getElementById("minesweeper-settings")
+ info = document.getElementById("minesweeper-game-info")
+ settings.hidden = !settings.hidden
+ info.hidden = !info.hidden
+ // if (timer === undefined) {
+ // }
+}
+
+document.getElementById("minesweeper-start").addEventListener("click", toggleRunning)
+document.getElementById("minesweeper-stop") .addEventListener("click", toggleRunning)
+
+initGrid()