Minesweeper/client.js
2022-05-15 16:55:34 +02:00

268 lines
6.2 KiB
JavaScript

let totalMines = 15;
let gridWidth = 10;
let gridHeight = 10;
let grid, hasLost = false, hasWon = false;
function resetGame() {
totalMines = parseInt(document.getElementById("tMines").value);
gridWidth = parseInt(document.getElementById("gWidth").value);
gridHeight = parseInt(document.getElementById("gHeight").value);
hasWon = false;
hasLost = false;
grid = startGame();
}
function revealRest() {
while (!hasWon) {
let hasClickedOnce = false;
for (let i = 0; i < gridHeight; i++) {
for (let j = 0; j < gridWidth; j++) {
if (!grid[i][j].isRevealed) {
let current = grid[i][j].element;
if (!grid[i][j].isFlagged && grid[i][j].isMine) {
rightClickFunc(current);
hasClickedOnce = true;
break;
} else if (!grid[i][j].isMine) {
reveal(current);
hasClickedOnce = true;
break;
}
}
}
if (hasClickedOnce) {
break;
}
}
checkWin();
}
}
function checkWin() {
for (let i = 0; i < gridHeight; i++) {
for (let j = 0; j < gridWidth; j++) {
if (!grid[i][j].isRevealed && !grid[i][j].isFlagged) {
return;
}
}
}
setTimeout(function(){
alert("Du hast gewonnen!!!");
}, 500);
hasWon = true;
}
function endGame() {
for (let i = 0; i < gridHeight; i++) {
for (let j = 0; j < gridWidth; j++) {
if (!grid[i][j].isFlagged) {
grid[i][j].isRevealed = true;
if (grid[i][j].isMine) {
grid[i][j].element.src = "MINE.png";
}
}
}
}
setTimeout(function(){
alert("Du hast verloren!!!");
}, 500);
hasLost = true;
}
function reveal(eventTarget) {
let et = eventTarget.parentElement;
if (et && et.value) {
let coords = et.value.split(' ');
let clickY = parseInt(coords[0]);
let clickX = parseInt(coords[1]);
if (!grid[clickY][clickX].isFlagged) {
let number, pDiv = document.createElement("div");
let image = document.createElement("img");
grid[clickY][clickX].isRevealed = true;
if (grid[clickY][clickX].isMine) {
image.src = "MINE.png";
endGame();
} else {
image.src = "BLANK.png";
let toBeRevealed = Array(), bombsNearby = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
if (!(i == 0 && j == 0)) {
const nY = clickY + i;
const nX = clickX + j;
if ((nX >= 0 && nX < gridWidth) && (nY >= 0 && nY < gridHeight)) {
let nE = grid[nY][nX];
if (!nE.isMine) {
if (!nE.isRevealed) {
toBeRevealed.push(nE.element);
}
} else {
bombsNearby++;
grid[clickY][clickX].isNumber = true;
}
}
}
}
}
if (bombsNearby == 0) {
toBeRevealed.forEach(e=>{
reveal(e);
});
} else {
number = document.createElement("a");
number.innerText = bombsNearby;
}
pDiv.appendChild(image);
if (number) {
pDiv.appendChild(number);
}
pDiv.ondblclick = doubleClickFunc;
et.replaceChildren(pDiv);
grid[clickY][clickX].element = image;
}
if (!hasLost) {
checkWin();
}
}
}
}
function doubleClickFunc(event) {
if (!hasLost) {
let et = event.target.parentElement.parentElement;
if (et && et.value) {
let coords = et.value.split(' ');
let clickY = parseInt(coords[0]);
let clickX = parseInt(coords[1]);
if (grid[clickY][clickX].isNumber) {
let toBeRevealed = Array();
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
if (!(i == 0 && j == 0)) {
const nY = clickY + i;
const nX = clickX + j;
if ((nX >= 0 && nX < gridWidth) && (nY >= 0 && nY < gridHeight)) {
let nE = grid[nY][nX];
if (nE.isMine && !nE.isFlagged) {
endGame();
break;
} else {
if (!nE.isRevealed) {
toBeRevealed.push(nE.element);
}
}
}
}
}
if (hasLost) {
break;
}
}
if (!hasLost) {
if (!checkWin()) {
toBeRevealed.forEach(e=>{
reveal(e);
});
}
}
}
}
}
}
function setFlag(eventTarget) {
let et = eventTarget.parentElement;
if (et && et.value) {
let coords = et.value.split(' ');
let clickY = parseInt(coords[0]);
let clickX = parseInt(coords[1]);
if (!grid[clickY][clickX].isRevealed) {
let image = grid[clickY][clickX].element;
if (!grid[clickY][clickX].isFlagged) {
image.src = "FLAG.png";
et.replaceChildren(image);
} else {
image.src = "PLATZHALTER.png";
et.replaceChildren(image);
}
grid[clickY][clickX].isFlagged = !grid[clickY][clickX].isFlagged;
}
}
}
function rightClickFunc(event) {
if (event.target) {
event.preventDefault();
if (!hasLost) {
setFlag(event.target);
}
} else {
setFlag(event);
}
}
function onClickFunc(event) {
if (!hasLost) {
reveal(event.target);
}
}
function startGame() {
let g = Array();
for (let i = 0; i < gridHeight; i++) {
g.push(Array(gridWidth));
}
let t = document.getElementById("Game");
t.innerHTML = "";
for (let i = 0; i < gridHeight; i++) {
let r = document.createElement("tr");
for (let j = 0; j < gridWidth; j++) {
let d = document.createElement("td");
let image = document.createElement("img");
image.src = "PLATZHALTER.png";
image.onclick = onClickFunc;
image.oncontextmenu = rightClickFunc;
d.appendChild(image);
d.value = i + " " + j;
r.appendChild(d);
g[i][j] = new Block(image);
}
t.appendChild(r);
}
let mC = 0;
while (mC < totalMines) {
let mX = Math.floor(Math.random()*gridWidth);
let mY = Math.floor(Math.random()*gridHeight);
if (!g[mY][mX].isMine) {
g[mY][mX].isMine=true;
mC++;
}
}
return g;
}
function init() {
grid = startGame();
document.getElementById("gWidth").oninput = function() {
let gHValue = document.getElementById("gHeight").value;
let value = Math.floor(parseInt(this.value) * parseInt(gHValue) * 0.1);
document.getElementById("tMines").max = value;
};
document.getElementById("gHeight").oninput = function() {
let gWValue = document.getElementById("gWidth").value;
let value = Math.floor(parseInt(this.value) * parseInt(gWValue) * 0.1) ;
document.getElementById("tMines").max = value+"";
};
}
class Block {
constructor(e_) {
this.element = e_;
this.isMine = false;
this.isRevealed = false;
this.isFlagged = false;
this.isNumber = false;
}
}