Advertisement
Guest User

Untitled

a guest
Oct 24th, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.00 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="ja">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>MineSweeper</title>
  6. <style>
  7. td {
  8. width: 30px;
  9. height: 30px;
  10. text-align: center;
  11. border: 1px solid #000;
  12. cursor: pointer;
  13. }
  14.  
  15. td:hover {
  16. background-color: rgba(64, 64, 64, .1);
  17. }
  18.  
  19. input[disabled=true] {
  20. background-color: lightgray;
  21. }
  22.  
  23. .not-open {
  24. background-color: gray;
  25. }
  26.  
  27. .open {
  28. background-color: white;
  29. }
  30. </style>
  31. </head>
  32. <body>
  33. <p>
  34. <label>X: <input type="number" id="x-size" value="9" min="3" max="99"></label>
  35. <label>Y: <input type="number" id="y-size" value="9" min="3" max="99"></label>
  36. <label>Mines: <input id="mine-num" type="number" value="0" disabled></label>
  37. <button id="start-button">Start</button>
  38. <button id="reset-button">Reset</button>
  39. </p>
  40. <div>
  41. <span>Time: </span>
  42. <span id="time-hour">00</span>:<span id="time-minute">00</span>:<span id="time-second">00</span>
  43. </div>
  44. <div>
  45. <button id="change-mode" data-mode="mining">⛏</button>
  46. </div>
  47. <div id="mine-field"></div>
  48.  
  49. <script>
  50. const xSizeDom = document.getElementById('x-size');
  51. const ySizeDom = document.getElementById('y-size');
  52. const startButton = document.getElementById('start-button');
  53. const resetButton = document.getElementById('reset-button');
  54. const changeModeButton = document.getElementById('change-mode');
  55. const timeH = document.getElementById('time-hour');
  56. const timeM = document.getElementById('time-minute');
  57. const timeS = document.getElementById('time-second');
  58. const modes = {mining: '⛏', flag: '🚩', unknown: '❓'};
  59. let intervalId, started = false, gameover = false;
  60. let fieldData = [];
  61.  
  62. function init() {
  63. const x = xSizeDom.value || 9;
  64. const y = ySizeDom.value || 9;
  65. renderField(x, y);
  66. stopTick();
  67. gameover = false;
  68. started = false;
  69. xSizeDom.removeAttribute('disabled');
  70. ySizeDom.removeAttribute('disabled');
  71. startButton.removeAttribute('disabled');
  72. timeH.innerText = timeM.innerText = timeS.innerText = '00';
  73. changeModeButton.innerText = modes.mining;
  74. changeModeButton.setAttribute('data-mode', 'mining');
  75. }
  76. function start() {
  77. xSizeDom.setAttribute('disabled', true);
  78. ySizeDom.setAttribute('disabled', true);
  79. startButton.setAttribute('disabled', true);
  80. startTick();
  81. }
  82.  
  83. xSizeDom.onchange = xSizeDom.onkeyup = (e) => {
  84. init();
  85. renderField(e.target.value, ySizeDom.value);
  86. };
  87. ySizeDom.onchange = ySizeDom.onkeyup = (e) => {
  88. init();
  89. renderField(xSizeDom.value, e.target.value);
  90. };
  91. startButton.onclick = start;
  92. resetButton.onclick = init;
  93. changeModeButton.onclick = (e) => {
  94. let mode = e.target.getAttribute('data-mode');
  95. let nextMode;
  96. switch (mode) {
  97. case 'mining':
  98. nextMode = 'flag';
  99. break;
  100. case 'flag':
  101. nextMode = 'unknown';
  102. break;
  103. case 'unknown':
  104. default:
  105. nextMode = 'mining';
  106. break;
  107. }
  108. e.target.setAttribute('data-mode', nextMode);
  109. e.target.innerText = modes[nextMode];
  110. };
  111.  
  112. window.onload = () => {
  113. const x = xSizeDom.value || 9;
  114. const y = ySizeDom.value || 9;
  115. renderField(x, y);
  116. };
  117.  
  118. function renderField(x, y) {
  119. fieldData = [];
  120. const deleteTarget = document.querySelector('#mine-field table');
  121. if (deleteTarget) deleteTarget.parentElement.removeChild(deleteTarget);
  122. const table = document.createElement('table');
  123. for (let i = 1; i <= x; i++) {
  124. const tr = document.createElement('tr');
  125. let fieldRow = [];
  126. for (let j = 1; j <= y; j++) {
  127. const td = document.createElement('td');
  128. td.innerHTML = '&nbsp;';
  129. td.classList.add('not-open');
  130. td.setAttribute('data-position', `${i},${j}`);
  131. td.onclick = open;
  132. tr.appendChild(td);
  133. fieldRow.push(false);
  134. }
  135. fieldData.push(fieldRow);
  136. table.appendChild(tr);
  137. }
  138.  
  139. const mf = document.getElementById('mine-field');
  140. mf.appendChild(table);
  141.  
  142. document.getElementById('mine-num').value = generateMines(x, y);
  143. }
  144.  
  145. function generateMines(x, y) {
  146. const mineNum = Math.round((x * y) * 0.3);
  147. for (let i = 0; i < mineNum; i++) {
  148. let bombX = Math.floor(Math.random() * x);
  149. let bombY = Math.floor(Math.random() * y);
  150. fieldData[bombX][bombY] = true;
  151. }
  152. return mineNum;
  153. }
  154.  
  155. function tickTack(h, m, s) {
  156. h = h || 0;
  157. m = m || 0;
  158. s = s || 0;
  159.  
  160. if (++s >= 60) {
  161. s -= 60;
  162. if (++m >= 60) {
  163. m -= 60;
  164. h++;
  165. timeH.innerText = ('0' + h).slice(-2);
  166. }
  167. timeM.innerText = ('0' + m).slice(-2);
  168. }
  169. timeS.innerText = ('0' + s).slice(-2);
  170. }
  171.  
  172. function startTick() {
  173. if (started || gameover) return;
  174. started = true;
  175. intervalId = setInterval(function () {
  176. tickTack(timeH.innerText, timeM.innerText, timeS.innerText);
  177. }, 1000);
  178. }
  179. function stopTick() {
  180. clearInterval(intervalId);
  181. }
  182.  
  183. function open(e) {
  184. if (!started) {
  185. start();
  186. }
  187.  
  188. const target = e.target;
  189. const mode = changeModeButton.getAttribute('data-mode');
  190.  
  191. if (mode === 'mining') {
  192. let flagged = target.getAttribute('data-flagged');
  193. if (flagged === 'flag') {
  194. // ζ——γŒη«‹γ£γ¦γŸγ‚‰ι–‹γ‹γͺい
  195. return;
  196. }
  197.  
  198. target.classList.remove('not-open');
  199.  
  200. const position = target.getAttribute('data-position').split(','),
  201. x = +position[0] - 1, y = +position[1] - 1;
  202. if (!fieldData[x][y]) {
  203. target.classList.add('open');
  204. let num = checkBombNum(x, y);
  205. if (num === 0) {
  206. target.innerText = '';
  207. } else {
  208. target.innerText = num;
  209. }
  210. } else {
  211. // GameOver
  212. target.innerText = 'πŸ’₯';
  213. stopTick();
  214. gameover = true;
  215. xSizeDom.removeAttribute('disabled');
  216. ySizeDom.removeAttribute('disabled');
  217. }
  218. } else if (mode === 'flag') {
  219. if (target.classList.contains('open')) {
  220. // ι–‹γ„γŸγ¨γ“γ‚γ―δ½•γ‚‚γ—γͺい
  221. return;
  222. }
  223.  
  224. let flag = target.getAttribute('data-flagged');
  225. if (flag === 'flag') {
  226. target.innerText = '';
  227. target.setAttribute('data-flagged', '');
  228. } else {
  229. target.innerText = modes.flag;
  230. target.setAttribute('data-flagged', 'flag');
  231. }
  232. } else {
  233. if (target.classList.contains('open')) {
  234. // ι–‹γ„γŸγ¨γ“γ‚γ―δ½•γ‚‚γ—γͺい
  235. return;
  236. }
  237.  
  238. let flag = target.getAttribute('data-flagged');
  239. if (flag === 'unknown') {
  240. target.innerText = '';
  241. target.setAttribute('data-flagged', '');
  242. } else {
  243. target.innerText = modes.unknown;
  244. target.setAttribute('data-flagged', 'unknown');
  245. }
  246. }
  247. }
  248.  
  249. function checkBombNum(x, y) {
  250. let bombNum = 0;
  251. for (let i = x - 1; i <= x + 1; i++) {
  252. if (i < 0 || i >= xSizeDom.value) continue;
  253.  
  254. for (let j = y - 1; j <= y + 1; j++) {
  255. if (j < 0 || j >= xSizeDom.value) continue;
  256. if (i === x && j === y) continue;
  257.  
  258. if (fieldData[i][j]) bombNum++;
  259. }
  260. }
  261. return bombNum;
  262. }
  263. </script>
  264. </body>
  265. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement