diff --git a/Laundromat/Laundromat.css b/Laundromat/Laundromat.css index efbc7a8..57ceb89 100644 --- a/Laundromat/Laundromat.css +++ b/Laundromat/Laundromat.css @@ -294,7 +294,6 @@ body { color: green; cursor: pointer; display: inline-block; - font-family: CerebriSans-Regular,-apple-system,system-ui,Roboto,sans-serif; padding: 7px 20px; text-align: center; text-decoration: none; diff --git a/LockPick/LockPick.css b/LockPick/LockPick.css index 7748085..14da82f 100644 --- a/LockPick/LockPick.css +++ b/LockPick/LockPick.css @@ -20,7 +20,7 @@ body { flex-direction: column; align-items: center; justify-content: center; - margin: 2% auto; + margin: 0% auto; width: 600px; height: 800px; } diff --git a/RoofRunning/RoofRunning.css b/RoofRunning/RoofRunning.css index 329e00a..934c996 100644 --- a/RoofRunning/RoofRunning.css +++ b/RoofRunning/RoofRunning.css @@ -22,7 +22,7 @@ body { flex-direction: column; align-items: center; justify-content: center; - margin: 2% auto; + margin: 0 auto; width: 600px; height: 670px; } @@ -113,7 +113,7 @@ body { gap: 10px; margin-top: -50px; margin-bottom: 15px; - margin-left: 440px; + margin-left: 475px; display: none; color: white; padding: 0px 18px; @@ -127,7 +127,7 @@ body { gap: 10px; margin-top: -50px; margin-bottom: 15px; - margin-left: 440px; + margin-left: 475px; display: none; color: white; padding: 0px 10px; diff --git a/RoofRunning/RoofRunning.js b/RoofRunning/RoofRunning.js index 5b17b99..809caf5 100644 --- a/RoofRunning/RoofRunning.js +++ b/RoofRunning/RoofRunning.js @@ -77,6 +77,11 @@ var Cube = /** @class */ (function () { this.cubeLeftShift(); } }; + Cube.prototype.getRandomColorClass = function () { + var colors = ["cuber", "cubeg", "cubeb"]; + var randomIndex = Math.floor(Math.random() * colors.length); + return colors[randomIndex]; + }; Cube.prototype.getConnectedCubes = function () { var _this = this; var connectedCubes = new Set(); @@ -94,17 +99,15 @@ var Cube = /** @class */ (function () { } return connectedCubes; }; - Cube.prototype.getRandomColorClass = function () { - var colors = ["cuber", "cubeg", "cubeb"]; - var randomIndex = Math.floor(Math.random() * colors.length); - return colors[randomIndex]; - }; Cube.prototype.checkwin = function () { var container = document.getElementById("container"); var divsInsideContainer = container.querySelectorAll('.empty'); if (divsInsideContainer.length === 25) { endGame("win"); } + if (!checkSolvable()) { + endGame("lose"); + } }; Cube.prototype.squareClick = function () { this.removeConnectedCubes(); @@ -112,7 +115,123 @@ var Cube = /** @class */ (function () { }; return Cube; }()); -//Make function that checks solvability of the board +//The functions below together checks solvability of the board +function helpFunct(container, queue) { + if (getColorCount().includes(1)) { + return false; + } + var c = 0; + container.forEach(function (cube) { + if (cube.classList.contains("empty")) { + c++; + } + }); + if (c === 25) { + return true; + } + while (queue.length > 0) { + var connectedCubes = queue.shift(); + if (helpFunct(cubesUpdate(container, connectedCubes), updateQueue(container))) { + return true; + } + } + return false; +} +function cubesUpdate(container, connectedCubes) { + connectedCubes.forEach(function (cube) { + var _a; + var idx = container.indexOf(cube); + cube.classList.remove(cube.classList.item(1)); + cube.classList.add("empty"); + var row = Math.floor(idx / 5); + for (var i = 0; i < row; i++) { + _a = [container[idx - 5 * (i + 1)], container[idx - 5 * i]], container[idx - 5 * i] = _a[0], container[idx - 5 * (i + 1)] = _a[1]; + } + }); + for (var i = 24; i >= 0; i--) { + var currCube = container[i]; + var col = i % 5; + if (currCube.classList.contains("empty") && col < 4) { + for (var j = col; j < 4; j++) { + var tempCube = container[i + (j - col)]; + container[i + (j - col)] = container[i + 1 + (j - col)]; + container[i + 1 + (j - col)] = tempCube; + } + } + } + return container; +} +function updateQueue(container) { + var queue = []; + var visited = new Set(); + container.forEach(function (cube) { + if (!cube.classList.contains("empty")) { + var connectedCubes = getConnectedCubes(container, cube); + for (var i = 0; i < connectedCubes.size; i++) { + var connectedCube = connectedCubes[i]; + if (!visited.has(connectedCube)) { + visited.add(connectedCube); + } + else { + queue.push(connectedCubes); + break; + } + } + } + }); + return queue; +} +function checkSolvable() { + var container = document.getElementById("container"); + var containerCopy = Array.from(container.childNodes).map(function (node) { return node.cloneNode(true); }); //Deep copy of the container so modification of the DOM cubes does not affect the original container + var queue = updateQueue(containerCopy); + return helpFunct(containerCopy, queue); +} +function getConnectedCubes(container, cube) { + var connectedCubes = new Set(); + var queue = [cube]; + while (queue.length > 0) { + var currentCube = queue.shift(); + connectedCubes.add(currentCube); + var neighbors = getAdjacentCubes(container, currentCube); + neighbors.forEach(function (neighbor) { + if (!connectedCubes.has(neighbor) && neighbor.classList.contains(cube.classList.item(1))) { + connectedCubes.add(neighbor); + queue.push(neighbor); + } + }); + } + if (connectedCubes.size === 1) { + connectedCubes.clear(); + } + return connectedCubes; +} +function getAdjacentCubes(container, cube) { + var idx = container.indexOf(cube); + var adjacentCubes = []; + var row = Math.floor(idx / 5); + var col = idx % 5; + if (col - 1 >= 0) + adjacentCubes.push(container[idx - 1]); + if (col + 1 < 5) + adjacentCubes.push(container[idx + 1]); + if (row - 1 >= 0) + adjacentCubes.push(container[idx - 5]); + if (row + 1 < 5) + adjacentCubes.push(container[idx + 5]); + return adjacentCubes; +} +function getColorCount() { + var container = document.getElementById("container"); + var colors = ["cuber", "cubeg", "cubeb"]; + var colorCount = [0, 0, 0]; + colors.forEach(function (color, idx) { + var count = container.querySelectorAll(".".concat(color)).length; + colorCount[idx] = count; + }); + return colorCount; +} +// ------------------------------------------------------------^ function endGame(outcome) { var timerProgress = document.querySelector(".timer-progress-bar"); var overlay = document.querySelector(".overlay"); @@ -137,18 +256,21 @@ function endGame(outcome) { }, 2000); } function resetGame() { - var container = document.getElementById("container"); - container.innerHTML = ""; + clearInterval(timerInterval); secondsRemaining = 15; generateCubes(); runTimer(); } function generateCubes() { - var container = document.getElementById("container"); - for (var i = 0; i < 25; i++) { - var cube = new Cube(); - container === null || container === void 0 ? void 0 : container.appendChild(cube.element); - } + do { + console.log(1); + var container = document.getElementById("container"); + container.innerHTML = ""; + for (var i = 0; i < 25; i++) { + var cube = new Cube(); + container === null || container === void 0 ? void 0 : container.appendChild(cube.element); + } + } while (!checkSolvable()); // Regenerate the cubes if the board is not solvable } function updateTimerDisplay() { var timerProgress = document.querySelector(".timer-progress-bar"); diff --git a/RoofRunning/RoofRunning.ts b/RoofRunning/RoofRunning.ts index 7d1d9b2..c00083c 100644 --- a/RoofRunning/RoofRunning.ts +++ b/RoofRunning/RoofRunning.ts @@ -54,7 +54,6 @@ class Cube { }); } - getAdjacentCubes(cube) { const idx = Array.from(this.container.childNodes).indexOf(cube); const adjacentCubes: HTMLDivElement[] = []; @@ -86,6 +85,12 @@ class Cube { } } + getRandomColorClass() { + const colors = ["cuber", "cubeg", "cubeb"]; + const randomIndex = Math.floor(Math.random() * colors.length); + return colors[randomIndex]; + } + getConnectedCubes() { const connectedCubes = new Set(); const queue = [this.element]; @@ -105,18 +110,15 @@ class Cube { return connectedCubes; } - getRandomColorClass() { - const colors = ["cuber", "cubeg", "cubeb"]; - const randomIndex = Math.floor(Math.random() * colors.length); - return colors[randomIndex]; - } - checkwin() { const container = document.getElementById("container") as HTMLElement; const divsInsideContainer = container.querySelectorAll('.empty'); if (divsInsideContainer.length === 25) { endGame("win"); } + if (!checkSolvable()) { + endGame("lose"); + } } squareClick() { @@ -125,7 +127,135 @@ class Cube { } } -//Make function that checks solvability of the board +//The functions below together checks solvability of the board +function helpFunct(container, queue): boolean { + if (getColorCount().includes(1)) { + return false; + } + + let c = 0; + container.forEach(cube => { + if ((cube as HTMLElement).classList.contains("empty")) { + c++; + } + }); + if (c === 25) { + return true; + } + + while (queue.length > 0) { + let connectedCubes = queue.shift(); + if (helpFunct(cubesUpdate(container, connectedCubes), updateQueue(container))) { + return true; + } + } + return false; +} + +function cubesUpdate(container, connectedCubes) { + connectedCubes.forEach(cube => { + const idx = container.indexOf(cube as HTMLDivElement); + (cube as HTMLDivElement).classList.remove((cube as HTMLDivElement).classList.item(1) as string); + (cube as HTMLDivElement).classList.add("empty"); + + const row = Math.floor(idx / 5); + for (let i = 0; i < row; i++) { + [container[idx - 5 * i], container[idx - 5 * (i + 1)]] = [container[idx - 5 * (i + 1)], container[idx - 5 * i]]; + } + }); + for (let i = 24; i >= 0; i--) { + const currCube = container[i] as HTMLDivElement; + const col = i % 5; + if (currCube.classList.contains("empty") && col < 4) { + for (let j = col; j < 4; j++) { + const tempCube = container[i+(j-col)]; + container[i+(j-col)] = container[i + 1 + (j-col)]; + container[i + 1 + (j-col)] = tempCube; + } + } + } + return container; +} + +function updateQueue(container): Set[] { + let queue: Set[] = []; + let visited = new Set(); + + container.forEach(cube => { + if (!(cube as HTMLElement).classList.contains("empty")) { + const connectedCubes = getConnectedCubes(container, cube as HTMLDivElement) + for (let i = 0; i < connectedCubes.size; i++) { + const connectedCube = connectedCubes[i]; + if (!visited.has(connectedCube)) { + visited.add(connectedCube); + } else { + queue.push(connectedCubes); + break; + } + } + } + }); + return queue; +} + +function checkSolvable(): boolean { + const container = document.getElementById("container") as HTMLElement; + const containerCopy = Array.from(container.childNodes).map(node => node.cloneNode(true)); //Deep copy of the container so modification of the DOM cubes does not affect the original container + + let queue = updateQueue(containerCopy); + return helpFunct(containerCopy, queue); +} + +function getConnectedCubes(container, cube) { + const connectedCubes = new Set(); + const queue = [cube]; + + while (queue.length > 0) { + const currentCube = queue.shift(); + connectedCubes.add(currentCube); + + const neighbors = getAdjacentCubes(container, currentCube); + neighbors.forEach(neighbor => { + if (!connectedCubes.has(neighbor) && neighbor.classList.contains((cube as HTMLDivElement).classList.item(1) as string)) { + connectedCubes.add(neighbor) + queue.push(neighbor); + } + }); + } + if (connectedCubes.size === 1) { + connectedCubes.clear(); + } + return connectedCubes; +} + +function getAdjacentCubes(container, cube) { + const idx = container.indexOf(cube); + const adjacentCubes: HTMLDivElement[] = []; + + const row = Math.floor(idx/5); + const col = idx%5; + + if (col - 1 >= 0) adjacentCubes.push(container[idx-1] as HTMLDivElement); + if (col + 1 < 5) adjacentCubes.push(container[idx+1] as HTMLDivElement); + if (row - 1 >= 0) adjacentCubes.push(container[idx-5] as HTMLDivElement); + if (row + 1 < 5) adjacentCubes.push(container[idx+5] as HTMLDivElement); + + return adjacentCubes; +} + +function getColorCount(): number[] { + const container = document.getElementById("container") as HTMLElement; + const colors = ["cuber", "cubeg", "cubeb"]; + const colorCount = [0, 0, 0]; + + colors.forEach((color, idx) => { + const count = container.querySelectorAll(`.${color}`).length; + colorCount[idx] = count; + }); + return colorCount; +} +// ------------------------------------------------------------^ + function endGame(outcome: string): void { const timerProgress = document.querySelector(".timer-progress-bar") as HTMLElement; @@ -153,19 +283,23 @@ function endGame(outcome: string): void { } function resetGame(): void { - const container = document.getElementById("container") as HTMLElement; - container.innerHTML = ""; + clearInterval(timerInterval as NodeJS.Timeout); secondsRemaining = 15; generateCubes(); runTimer(); } function generateCubes(): void { - const container: HTMLDivElement = document.getElementById("container") as HTMLDivElement; - for (let i = 0; i < 25; i++) { - const cube = new Cube(); - container?.appendChild(cube.element); - } + do { + console.log(1); + const container: HTMLDivElement = document.getElementById("container") as HTMLDivElement; + container.innerHTML = ""; + + for (let i = 0; i < 25; i++) { + const cube = new Cube(); + container?.appendChild(cube.element); + } + } while (!checkSolvable()); // Regenerate the cubes if the board is not solvable } function updateTimerDisplay() { @@ -188,9 +322,10 @@ function runTimer() { document.addEventListener("DOMContentLoaded", function () { resetGame(); + const instructionsToggle = document.getElementById('instructions-toggle') as HTMLElement; const instructionsContent = document.getElementById('instructions-content') as HTMLElement; - + if (instructionsToggle) { instructionsToggle.addEventListener('click', function() { instructionsContent.classList.toggle('active');