Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
<!DOCTYPE html>
<html>
<head lang="uk">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Miner on WebDataRocks</title>
<link href ="https://cdn.webdatarocks.com/latest/webdatarocks.min.css" rel="stylesheet">
<link href ="style.css" rel="stylesheet">
<script src = "https://cdn.webdatarocks.com/latest/webdatarocks.toolbar.min.js"></script>
<script src = "https://cdn.webdatarocks.com/latest/webdatarocks.js"></script>


<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<span class="product-item">
Apple
<span class="amount">4</span>
</span>
<div class="main-panel">
<button id="chng-btn" class="btn">Mode: demine </button>
<span id="status" class="status-text">Game is ongoing... </span>

</div>


<div id = "pivotContainer"></div>



<script src = "script.js"></script>

</body>
</html>
17 changes: 0 additions & 17 deletions main.css

This file was deleted.

216 changes: 216 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
const ROWS = 9;
const COLUMNS = 9;
const MINA = 10;

function generateGrid(rowsCount, colsCount, minesCount) {
let data = [
{ "Row": { type: "string" }, "Column": { type: "string" }, "Value": { type: "number" } }
];
let table = [];


for (let r = 0; r < rowsCount; r++) {
table[r] = [];
for (let c = 0; c < colsCount; c++) {
table[r][c] = 0;
}
}


let minePlaced = 0;
while(minePlaced < minesCount){
let rRow = Math.floor(Math.random() * rowsCount);
let rColumn = Math.floor(Math.random() * colsCount);

if(table[rRow][rColumn] !== -1){
table[rRow][rColumn] = -1;
minePlaced++;
}
}

for (let r = 0; r < rowsCount; r++){
for (let c = 0; c < colsCount; c++){
if (table[r][c] === -1){
continue;
}

let count = 0;

for (let ni = -1; ni <= 1; ni++){
for (let nj = -1; nj <= 1; nj++){
let nbi = ni + r;
let nbj = nj + c;

if (nbi >= 0 && nbi < rowsCount && nbj >= 0 && nbj < colsCount){
if (table[nbi][nbj] === -1){
++count;
}
}
}
}
table[r][c] = count;
}
}


for (let r = 0; r < rowsCount; r++){
for (let c = 0; c < colsCount; c++){
data.push({
"Row": `R${r}`,
"Column": `C${c}`,
"Value": table[r][c]
});
}
}

return data;
}

let sizes = [];

for (let i = 0; i <= 10; i++) {
sizes.push({idx: i, width:45, height: 45});
}


let openedCells = new Set();
let flaggedCells = new Set();
let gameOver = false;
let isFlagMode = false;
const statusText = document.querySelector(".status-text");


const modeBtn = document.querySelector(".btn");
modeBtn.addEventListener("click", function() {
if (gameOver) return;
isFlagMode = !isFlagMode;


if (isFlagMode) {
modeBtn.innerText = "Mode: flag 🚩";
modeBtn.style.backgroundColor = "darkred";
} else {
modeBtn.innerText = "Mode: demine 💣";
modeBtn.style.backgroundColor = "black";
}
});


const pivot = new WebDataRocks({
container: "#pivotContainer",
toolbar: false,
report: {
dataSource: { data: generateGrid(ROWS, COLUMNS, MINA) },
slice: {
rows: [{ uniqueName: "Row" }],
columns: [{ uniqueName: "Column" }],
measures: [{ uniqueName: "Value" }]
},
tableSizes: { columns: sizes, rows: sizes },
options: {
grid: { showTotals: "off", showGrandTotals: "off", showHeaders: false },
configuratorButton: false,
drillThrough: false
}
},


customizeCell: function(cell, data) {
if (data.type !== "value") return;
let cellId = `${data.rowIndex}-${data.columnIndex}`;
let val = data.value;


let secretData = `<span class="secret-data" data-val="${val}" data-id="${cellId}" style="display:none;"></span>`;

if (openedCells.has(cellId)) {
cell.addClass("cell-openned");
if (val === -1) cell.text = "💥";
else if (val === 0) cell.text = "";
else {
let color = "black";
switch(val) {
case 1: color = "blue"; break; case 2: color = "green"; break;
case 3: color = "red"; break; case 4: color = "darkblue"; break;
case 5: color = "brown"; break; case 6: color = "cyan"; break;
}
cell.text = `<span style="color: ${color}; font-weight: bold;">${val}</span>`;
}
} else if (flaggedCells.has(cellId)) {
cell.addClass("cell-hidden");
cell.text = `🚩` + secretData;
} else {
cell.addClass("cell-hidden");
cell.text = secretData;
}
}
});
const doc = document.querySelector("#pivotContainer");

doc.addEventListener("mousedown", function(event) {
if (gameOver) return;

let cell = event.target.closest(".wdr-cell");
if (!cell || cell.classList.contains("cell-openned")) return;


event.stopPropagation();


let secretSpan = cell.querySelector(".secret-data");
if (!secretSpan) return;

let val = secretSpan.getAttribute("data-val");
let cellId = secretSpan.getAttribute("data-id");
let secretHTML = `<span class="secret-data" data-val="${val}" data-id="${cellId}" style="display:none;"></span>`;


if (isFlagMode) {
if (flaggedCells.has(cellId)) {
flaggedCells.delete(cellId);
cell.innerHTML = secretHTML;
} else {

flaggedCells.add(cellId);
cell.innerHTML = `🚩` + secretHTML;
}
return;
}


if (flaggedCells.has(cellId)) return;


openedCells.add(cellId);
cell.classList.remove("cell-hidden");
cell.classList.add("cell-openned");

if (val === "-1") {
cell.innerText = "💥";
gameOver = true;


statusText.innerText = "Game Over 💥";
statusText.style.color = "red";


return;
}

if (val === "0") {
cell.innerText = "";
return;
}


let color = "black";
switch(val) {
case "1": color = "blue"; break; case "2": color = "green"; break;
case "3": color = "red"; break; case "4": color = "darkblue"; break;
case "5": color = "brown"; break; case "6": color = "cyan"; break;
case "7": color = "black"; break; case "8": color = "gray"; break;
}
cell.innerHTML = `<span style="color: ${color}; font-weight: bold;">${val}</span>`;
});


123 changes: 123 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
*{
box-sizing: border-box;
margin:0;
padding:0;
}


body {
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
font-size: 16px;
font-style: italic;
background-color: burlywood;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 30px;
}

.main-panel {
display: flex;
align-items: center;
gap: 20px;
background-color: whitesmoke;
border-radius: 10px;
padding: 15px 25px;
margin-bottom: 20px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}

.btn {
padding: 10px 15px;
font-size: 16px;
font-weight: bold;
border-radius: 5px;
background-color: black;
color: #a88a8a;
cursor: pointer;
border: none;
transition: all 0.2s ease;
}


.btn:hover {
background-color: #a88a8a;
color: black;
}


.btn.btn-flag {
background-color: darkred;
color: white;
}


.btn.btn-flag:hover {
background-color: red;
color: white;
}

.btn:active {
transform: scale(0.95);
}

.status-text {
font-weight: bold;
font-size: 20px;
color: black;
min-width: 100px;
text-align: center;
font-style: normal;
}

#pivotContainer {
width: 500px !important;
height: 500px !important;
overflow: hidden !important;
border-radius: 6px;
margin: 0 auto;
background-color: white;
box-shadow: 0 8px 16px rgba(0,0,0,0.5);
}

#pivotContainer > div {
margin-top: -90px !important;
margin-left: -45px !important;
}

#pivotContainer .wdr-cell {
cursor: pointer !important;
font-size: 18px !important;
font-weight: bold !important;
border-width: 1px !important;
border-style: dashed !important;
border-color: rgb(202, 228, 164) !important;
display: flex !important;
justify-content: center !important;
align-items: center !important;
}

#pivotContainer .wdr-cell.wdr-active, #pivotContainer .wdr-cell.wdr-selected {
background-color: transparent !important;
outline: none !important;
box-shadow: none !important;
}

.cell-hidden{
background-color: grey !important;

border: none !important;
box-shadow: inset -3px -3px 0 #696969, inset 3px 3px 0 white !important;

}

.cell-openned{
background-color: #e0e0e0 !important;

box-shadow: inset 2px 2px 0 #6d6d6d !important;

border-width: 1px !important;
border-style: solid !important;
border-color: #808080 !important;
}