- 00 + : - 00 + : - 00 +
- 0 + /
diff --git a/src/css/style.css b/src/css/style.css index e16e84a..636a5f7 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -49,116 +49,54 @@ button { } .game-canvas { + display: flex; + flex-direction: column; margin: 20px auto; padding: 5px 0 0 5px; background-color: #55b4ff; - justify-content: center; + width: 500px; + height: 500px; } .row { display: flex; + flex: auto; flex-wrap: nowrap; } [class^="cell"] { background-color: rgba(255, 255, 255, 0.6); text-align: center; -} - -[class^="cell"]:hover { - background-color: rgba(255, 255, 255, 0.8);; -} - -.cell-8 { margin-right: 5px; margin-bottom: 5px; - height: 60px; - width: 60px; + flex: auto; } -.cell-10 { - margin-right: 5px; - margin-bottom: 5px; - height: 60px; - width: 60px; -} - -.cell-12 { - margin-right: 5px; - margin-bottom: 5px; - height: 60px; - width: 60px; -} - -@media screen and (max-width: 1200px) { - .cell-12 { - height: 50px; - width: 50px; - } -} - -@media screen and (max-width: 992px) { - .cell-10 { - height: 50px; - width: 50px; - } - - .cell-12 { - height: 40px; - width: 40px; - } +[class^="cell"]:hover { + background-color: rgba(255, 255, 255, 0.8); } @media screen and (max-width: 768px) { - .cell-8 { - height: 50px; - width: 50px; - margin-right: 2px; - margin-bottom: 2px; - } + .game-canvas { + padding: 2px 0 0 2px; + width: 450px; + height: 450px; - .cell-10 { - height: 40px; - width: 40px; - margin-right: 2px; - margin-bottom: 2px; } - - .cell-12 { - height: 35px; - width: 35px; + [class^="cell"] { margin-right: 2px; margin-bottom: 2px; } - - .game-canvas { - padding: 2px 0 0 2px; - } } @media screen and (max-width: 567px) { - .cell-8 { - height: 40px; - width: 40px; - margin-right: 1px; - margin-bottom: 1px; + .game-canvas { + padding: 1px 0 0 1px; + width: 400px; + height: 400px; } - - .cell-10 { - height: 35px; - width: 35px; + [class^="cell"] { margin-right: 1px; margin-bottom: 1px; } - - .cell-12 { - height: 30px; - width: 30px; - margin-right: 1px; - margin-bottom: 1px; - } - - .game-canvas { - padding: 1px 0 0 1px; - } } \ No newline at end of file diff --git a/src/js/actions.js b/src/js/actions.js index e67574b..3bbecd4 100644 --- a/src/js/actions.js +++ b/src/js/actions.js @@ -7,25 +7,28 @@ import { table } from "./app.js"; //// Left click -export function clickOnCell(event){ +export function clickOnCell(e){ - if (!table.timeCounterIsStart){startTimer()} + if (table.won === undefined && !table.timeCounterIsStart){startTimer()} - let cellId = event.target.id; + let cellId = e.target.id; let cellElement = document.getElementById(cellId); + let cell = table.tableCells[cellId]; + + if (!cell || cell.haveFlag || table.won !== undefined) return; if (!table.firstClick) { firstClick(table, cellElement, cellId) } else { - let haveMine = table.tableCells[cellId].haveMine; - let amountNeighborsWithMine = table.tableCells[cellId].amountNeighborsWithMine; + let haveMine = cell.haveMine; + let amountNeighborsWithMine = cell.amountNeighborsWithMine; if (haveMine){ openCellWithMine(cellElement, cellId, table); gameOver(); } else if(!haveMine && amountNeighborsWithMine > 0){ getNumberToCell(amountNeighborsWithMine, cellElement); - table.tableCells[cellId].isOpen = true; + cell.isOpen = true; } else { openEmptyCell(cellElement, cellId, table); } @@ -43,9 +46,11 @@ export function clickOnCell(event){ export function rightClickOnCell(e) { e.preventDefault(); - let cellId = event.target.id; + let cellId = e.target.id; let cellElement = document.getElementById(cellId); + if (!table.tableCells[cellId] || table.won !== undefined) return; + let haveFlag = table.tableCells[cellId].haveFlag; if (!table.timeCounterIsStart){startTimer()} @@ -89,9 +94,6 @@ function firstClick(table, cellElement, cellId){ table.tableCells[cellId].firstClickOpen = true; table.tableCells[cellId].haveFlag = false; cellElement.style.backgroundImage = ''; - cellElement.removeEventListener("contextmenu", rightClickOnCell, false); - cellElement.removeEventListener('touchstart', onTouchStart,false); - cellElement.removeEventListener('touchend', onTouchEnd,false); let neighbors = table.tableCells[cellId].neighbors; for (const neighbor in neighbors){ @@ -173,9 +175,6 @@ function getNumberToCell(amountNeighborsWithMine, cellElement){ cellElement.style.backgroundSize = "cover"; cellElement.style.backgroundColor = "rgba(255, 255, 255, 0.3)"; cellElement.style.backgroundImage = urlImg; - cellElement.removeEventListener("contextmenu", rightClickOnCell, false); - cellElement.removeEventListener('touchstart', onTouchStart,false); - cellElement.removeEventListener('touchend', onTouchEnd,false); } function openEmptyCell(cellElement, cellId, table){ @@ -183,9 +182,6 @@ function openEmptyCell(cellElement, cellId, table){ table.tableCells[cellId].isOpen = true; table.tableCells[cellId].haveFlag = false; cellElement.style.backgroundImage = ''; - cellElement.removeEventListener("contextmenu", rightClickOnCell, false); - cellElement.removeEventListener('touchstart', onTouchStart,false); - cellElement.removeEventListener('touchend', onTouchEnd,false); checkNeighborsWithNeighborsWithMine(table, cellId); } @@ -232,14 +228,12 @@ function checkAndAddNumberCellsWithFlag() { } function getFlagToCell(cellElement, table, cellId){ - cellElement.removeEventListener("click", clickOnCell); cellElement.style.backgroundSize = "cover"; cellElement.style.backgroundImage = "url('./src/img/flag.png')"; table.tableCells[cellId].haveFlag = true; } function removeFlagFromCell(cellElement, table, cellId){ - cellElement.addEventListener("click", clickOnCell); cellElement.style.backgroundSize = ""; cellElement.style.backgroundImage = ""; table.tableCells[cellId].haveFlag = false; diff --git a/src/js/app.js b/src/js/app.js index a4a9593..b312db3 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -1,52 +1,18 @@ -import { - buildGameTable -} from "./gameBuilder.js"; -import { removeGameTable } from "./gameState"; +import { buildGameTable } from "./gameBuilder.js"; import { stopTimer, resetTimeCounter } from "./timer"; -var level; -setLevel(); +const restartElement = document.getElementById("restart"); +const levelElement = document.getElementById('level'); -export var table = buildGameTable(level); +export let table = {}; -document.getElementById("restart").addEventListener("click", restartGame); +restartElement.addEventListener("click", restartGame); +levelElement.addEventListener("change", restartGame); +restartGame(); function restartGame() { - setLevel(); - removeGameTable(); - table = buildGameTable(level); + table = buildGameTable(levelElement.value.split(',').map(item => +item)); stopTimer(); resetTimeCounter(); } - -function setLevel() { - level = document.getElementById('level').value; - - switch (level) { - case "easy": - level = { - rows: 8, - cols: 8, - maxMines:10 - } - break; - case "normal": - level = { - rows: 10, - cols: 10, - maxMines: 14 - } - break; - case "hard": - level = { - rows: 12, - cols: 12, - maxMines: 20 - } - break; - default: - break; - } - -} \ No newline at end of file diff --git a/src/js/gameBuilder.js b/src/js/gameBuilder.js index cc0d6b0..d8ad7ab 100644 --- a/src/js/gameBuilder.js +++ b/src/js/gameBuilder.js @@ -4,38 +4,34 @@ import { onTouchStart, onTouchEnd } from "./actions.js"; +import { removeGameTable } from "./gameState"; -export function buildGameTable(level) { - let rows = level.rows; - let cols = level.cols; - let maxMines = level.maxMines; - let tableCells = {}; - let table = { +const fragment = document.createDocumentFragment(); +const gameTableElement = document.getElementById("gameTable"); + +gameTableElement.addEventListener("click", clickOnCell); +gameTableElement.addEventListener("contextmenu", rightClickOnCell, false); +gameTableElement.addEventListener('touchstart', onTouchStart,false); +gameTableElement.addEventListener('touchend', onTouchEnd,false); + +export function buildGameTable([rows, cols, maxMines]) { + let tableCells = Object.create(null); + let table = Object.create(null); + let cellClass = 'cell-' + rows; + + Object.assign(table, { counterMines:0, maxMines: maxMines, counterFlags:0, amountCells: rows * cols, timeCounterIsStart: false, - firstClick: false - }; - let gameTableElement = document.getElementById("gameTable"); - document.getElementById("amount-mines").innerHTML = maxMines; + firstClick: false, + won: undefined + }); - let cellClass; - switch (rows) { - case 8: - cellClass = "cell-8" - break; - case 10: - cellClass = "cell-10" - break; - case 12: - cellClass = "cell-12" - break; - default: - break; - } - + removeGameTable(); + + document.getElementById("amount-mines").innerHTML = maxMines; // create rows for (let i = 0; i < rows; i++) { @@ -44,144 +40,48 @@ export function buildGameTable(level) { let rowId = "row-" + i; divRow.setAttribute("id", rowId); - - gameTableElement.appendChild(divRow); + fragment.appendChild(divRow); // create row's cols for (let n = 0; n < cols; n++) { let divCell = document.createElement("div"); - divCell.setAttribute("class", cellClass); - divCell.addEventListener("click", clickOnCell); - divCell.addEventListener("contextmenu", rightClickOnCell, false); - divCell.addEventListener('touchstart', onTouchStart,false); - divCell.addEventListener('touchend', onTouchEnd,false); let cellId = "cell-" + i + "-" + n; + + divCell.setAttribute("class", cellClass); divCell.setAttribute("id", cellId); divRow.appendChild(divCell); // adding col with properties to table object - Object.assign(tableCells, {[cellId]: { - row: i, - col: n, - neighbors: setNeighbors(rows, cols, i, n), - amountNeighborsWithMine: 0, - haveMine: false, - isOpen: false, - firstClickOpen: false, - haveFlag: false, - writable: false - }}); - } + Object.assign(tableCells, {[cellId]: Object.assign(Object.create(null), { + row: i, + col: n, + neighbors: setNeighbors(rows, cols, i, n), + amountNeighborsWithMine: 0, + haveMine: false, + isOpen: false, + firstClickOpen: false, + haveFlag: false, + writable: false + })}); + } } table.tableCells = tableCells; + gameTableElement.appendChild(fragment); return table } function setNeighbors(rows, cols, i, n) { - const lastNeighborY = rows - 1; - const lastNeighborX = cols - 1; - if (i > 0 && n > 0 && i < lastNeighborY && n < lastNeighborX){ - return { - neighbor_1: {row: i - 1, col: n - 1}, - neighbor_2: {row: i - 1, col: n}, - neighbor_3: {row: i - 1, col: n + 1}, - neighbor_4: {row: i, col: n - 1}, - neighbor_5: {row: i, col: n + 1}, - neighbor_6: {row: i + 1, col: n - 1}, - neighbor_7: {row: i + 1, col: n}, - neighbor_8: {row: i + 1, col: n + 1} - } - } else if (i == 0 && n == 0 && i < lastNeighborY && n < lastNeighborX) { - return { - neighbor_1: "", - neighbor_2: "", - neighbor_3: "", - neighbor_4: "", - neighbor_5: {row: i, col: n + 1}, - neighbor_6: "", - neighbor_7: {row: i + 1, col: n}, - neighbor_8: {row: i + 1, col: n + 1} - } - } else if (i == 0 && n > 0 && i < lastNeighborY && n < lastNeighborX) { - return { - neighbor_1: "", - neighbor_2: "", - neighbor_3: "", - neighbor_4: {row: i, col: n - 1}, - neighbor_5: {row: i, col: n + 1}, - neighbor_6: {row: i + 1, col: n - 1}, - neighbor_7: {row: i + 1, col: n}, - neighbor_8: {row: i + 1, col: n + 1} - } - } else if (i == 0 && n > 0 && i < lastNeighborY && n == lastNeighborX){ - return { - neighbor_1: "", - neighbor_2: "", - neighbor_3: "", - neighbor_4: {row: i, col: n - 1}, - neighbor_5: "", - neighbor_6: {row: i + 1, col: n - 1}, - neighbor_7: {row: i + 1, col: n}, - neighbor_8: "" - } - } else if (i > 0 && n == 0 && i < lastNeighborY && n < lastNeighborX) { - return { - neighbor_1: "", - neighbor_2: {row: i - 1, col: n}, - neighbor_3: {row: i - 1, col: n + 1}, - neighbor_4: "", - neighbor_5: {row: i, col: n + 1}, - neighbor_6: "", - neighbor_7: {row: i + 1, col: n}, - neighbor_8: {row: i + 1, col: n + 1} - } - } else if (i > 0 && n == 0 && i == lastNeighborY && n < lastNeighborX) { - return { - neighbor_1: "", - neighbor_2: {row: i - 1, col: n}, - neighbor_3: {row: i - 1, col: n + 1}, - neighbor_4: "", - neighbor_5: {row: i, col: n + 1}, - neighbor_6: "", - neighbor_7: "", - neighbor_8: "" - } - } else if (i > 0 && n > 0 && i < lastNeighborY && n == lastNeighborX) { - return { - neighbor_1: {row: i - 1, col: n - 1}, - neighbor_2: {row: i - 1, col: n}, - neighbor_3: "", - neighbor_4: {row: i, col: n - 1}, - neighbor_5: "", - neighbor_6: {row: i + 1, col: n - 1}, - neighbor_7: {row: i + 1, col: n}, - neighbor_8: "" - } - } else if (i > 0 && n > 0 && i == lastNeighborY && n < lastNeighborX) { - return { - neighbor_1: {row: i - 1, col: n - 1}, - neighbor_2: {row: i - 1, col: n}, - neighbor_3: {row: i - 1, col: n + 1}, - neighbor_4: {row: i, col: n - 1}, - neighbor_5: {row: i, col: n + 1}, - neighbor_6: "", - neighbor_7: "", - neighbor_8: "" - } - } else if (i > 0 && n > 0 && i == lastNeighborY && n == lastNeighborX) { - return { - neighbor_1: {row: i - 1, col: n - 1}, - neighbor_2: {row: i - 1, col: n}, - neighbor_3: "", - neighbor_4: {row: i, col: n - 1}, - neighbor_5: "", - neighbor_6: "", - neighbor_7: "", - neighbor_8: "" - } + const out = Object.create(null); + let num = 1; + + for (let x = i - 1; x <= i + 1; x++) { + for (let y = n - 1; y <= n + 1; y++ ) { + if (x === i && y === n) continue; + else if (x >= rows || x < 0) out['neighbor_' + num++] = ''; + else if (y >= cols || y < 0) out['neighbor_' + num++] = ''; + else out['neighbor_' + num++] = { row: x, col: y }; + } } + return out; } - - - diff --git a/src/js/gameState.js b/src/js/gameState.js index 89d970c..5fb951d 100644 --- a/src/js/gameState.js +++ b/src/js/gameState.js @@ -1,21 +1,12 @@ -import { - stopTimer - } from "./timer.js"; -import { - clickOnCell, - rightClickOnCell, - onTouchStart, - onTouchEnd - } from "./actions.js"; -import { - table - } from "./app.js"; +import { stopTimer } from "./timer.js"; +import { table } from "./app.js"; export function won() { let gameTable = document.getElementById('gameTable'); gameTable.style.webkitFilter = "blur(.05em)"; openAllCells(); stopTimer(); + table.won = true; } export function gameOver() { @@ -23,17 +14,14 @@ export function gameOver() { gameTable.style.webkitFilter = "blur(.05em)"; openAllCells(); stopTimer(); + table.won = false; } function openAllCells() { - for (const cell in table.tableCells){ + for (const cell in table.tableCells) { let haveMine = table.tableCells[cell].haveMine; let isOpen = table.tableCells[cell].isOpen; let cellElement = document.getElementById(cell); - cellElement.removeEventListener("click", clickOnCell); - cellElement.removeEventListener("contextmenu", rightClickOnCell, false); - cellElement.removeEventListener('touchstart', onTouchStart,false); - cellElement.removeEventListener('touchend', onTouchEnd,false); if (haveMine && !isOpen){ cellElement.style.backgroundImage = "url('./src/img/bomb.svg')"; cellElement.style.backgroundColor = "rgba(255, 255, 255, 0.8)"; @@ -46,8 +34,7 @@ function openAllCells() { export function removeGameTable() { let gameTable = document.getElementById('gameTable'); let elementCounterFlags = document.getElementById('counter-flags'); - elementCounterFlags.innerHTML = 0; + elementCounterFlags.textContent = 0; gameTable.innerHTML = ""; gameTable.style.webkitFilter = "blur(.0em)"; - }