Skip to content

Commit

Permalink
Merge pull request #31 from BobDotCom/main
Browse files Browse the repository at this point in the history
RoofRunning Improvements
  • Loading branch information
MaximilianAdF authored Feb 19, 2024
2 parents 4da1028 + 745ca17 commit 899ffd2
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<p align="center">↑ Click to play ↑</p>

### Description
The new Roof Running job that recently popped up on NoPixel 4.0 is built around stealing AC units from the roof's of buildings. Stealing the AC units require a screwdriver which through the above minigame loosens the AC unit and lets the player pick it up. The game consists of a 11x8 grid with 88 differently colored cubes (Red, Green Blue). Cubes of the same color that are connected (Meaning more than 2 cubes are next to one another) can be removed by clicking on them. The remaining cubes fall downwards and align to the left of the screen. Singular cubes of a specific color can not be removed since they're not a pair of more than 2. The game is completed succesfully if all 25 cubes have been removed within the 15 second time constraint
The new Roof Running job that recently popped up on NoPixel 4.0 is built around stealing AC units from the roof's of buildings. Stealing the AC units require a screwdriver which through the above minigame loosens the AC unit and lets the player pick it up. The game consists of a 11x8 grid with 88 differently colored cubes (Red, Green Blue). Cubes of the same color that are connected (Meaning more than 2 cubes are next to one another) can be removed by clicking on them. The remaining cubes fall downwards and align to the left of the screen. Singular cubes of a specific color can not be removed since they're not a pair of more than 2. The game is completed succesfully if all cubes have been removed within the time constraint.

### Thoughts
There are still some stuff that could be nice to add
Expand Down
53 changes: 40 additions & 13 deletions RoofRunning/RoofRunning.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var timerTimeout;
var timerProgressBar;
var totalSeconds = 25;
var gridCols = 11;
var gridRows = 8;
Expand Down Expand Up @@ -124,9 +125,9 @@ var Cube = /** @class */ (function () {
if (divsInsideContainer.length === gridRows * gridCols) {
endGame("win");
}
//if (!checkSolvable()) {
//endGame("lose");
//}
else if (shouldFail()) {
endGame("lose");
}
};
Cube.prototype.squareClick = function () {
this.removeConnectedCubes();
Expand Down Expand Up @@ -236,6 +237,33 @@ function checkSolvable() {
var queue = updateQueue(containerCopy);
return helpFunct(containerCopy, queue);
}
function shouldFail() {
// This method does 2 things:
// 1. Fail if exactly one of any color is left
// 2. Fail if there are no groups of connected colors
//
// In case of a failure, return true
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
// No need to check if the board is empty. This method won't be called if we won.
if (getColorCount(containerCopy).includes(1)) {
console.log("FAIL: Single cube of a color remaining");
return true;
}
// If we find a connected group, return true
for (var i = 0; i < containerCopy.length; i++) {
var cube = containerCopy[i];
if (!cube.classList.contains("empty")) {
var connectedCubes = getConnectedCubes(containerCopy, cube);
if (connectedCubes.size > 1) {
return false;
}
}
}
// If we made it here, no connected groups were found. Fail.
console.log("FAIL: No connected groups found");
return true;
}
function getConnectedCubes(container, cube) {
var connectedCubes = new Set();
var queue = [cube];
Expand Down Expand Up @@ -340,19 +368,18 @@ function resetGame() {
runTimer();
}
function generateCubes() {
console.log("RESET");
do {
var container = document.getElementById("container");
container.innerHTML = "";
for (var i = 0; i < gridRows * gridCols; 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
console.log("generating cubes...");
var container = document.getElementById("container");
container.innerHTML = "";
for (var i = 0; i < gridRows * gridCols; i++) {
var cube = new Cube();
container === null || container === void 0 ? void 0 : container.appendChild(cube.element);
}
}
function runTimer() {
var timerProgress = document.querySelector(".timer-progress-bar");
setTimeout(function () {
clearTimeout(timerProgressBar); // We need to clear to prevent memory leak after multiple games are played.
timerProgressBar = setTimeout(function () {
timerProgress.style.width = "0%";
}, 100);
clearTimeout(timerTimeout); // Clear any existing timer to prevent problems with endGame("reset")
Expand Down
65 changes: 48 additions & 17 deletions RoofRunning/RoofRunning.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let timerTimeout: NodeJS.Timeout;
let timerProgressBar: NodeJS.Timeout;
let totalSeconds = 25;
let gridCols = 11;
let gridRows = 8;
Expand Down Expand Up @@ -135,10 +136,9 @@ class Cube {
const divsInsideContainer = container.querySelectorAll('.empty');
if (divsInsideContainer.length === gridRows * gridCols) {
endGame("win");
} else if (shouldFail()) {
endGame("lose");
}
//if (!checkSolvable()) {
//endGame("lose");
//}
}

squareClick() {
Expand Down Expand Up @@ -256,6 +256,37 @@ function checkSolvable(): boolean {
return helpFunct(containerCopy, queue);
}

function shouldFail(): boolean {
// This method does 2 things:
// 1. Fail if exactly one of any color is left
// 2. Fail if there are no groups of connected colors
//
// In case of a failure, return true

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

// No need to check if the board is empty. This method won't be called if we won.

if (getColorCount(containerCopy).includes(1)) {
console.log("FAIL: Single cube of a color remaining")
return true;
}
// If we find a connected group, return true
for (let i = 0; i < containerCopy.length; i++) {
const cube = containerCopy[i];
if (!(cube as HTMLElement).classList.contains("empty")) {
const connectedCubes = getConnectedCubes(containerCopy, cube as HTMLDivElement)
if (connectedCubes.size > 1) {
return false;
}
}
}
// If we made it here, no connected groups were found. Fail.
console.log("FAIL: No connected groups found")
return true;
}

function getConnectedCubes(container, cube) {
const connectedCubes = new Set();
const queue = [cube];
Expand Down Expand Up @@ -326,7 +357,7 @@ function endGame(outcome: string): void {
winMsg.style.display = 'none';
timerProgress.style.display = "block";
overlay.style.display = 'none';
resetGame();
resetGame();
}, 2000);
} else if (outcome === "lose") {
const loseMsg = document.querySelector(".lose-message") as HTMLElement;
Expand All @@ -335,9 +366,9 @@ function endGame(outcome: string): void {
loseMsg.style.display = 'none';
timerProgress.style.display = "block";
overlay.style.display = 'none';
resetGame();
resetGame();
}, 2000);

} else if (outcome === "reset") {
const resetMsg = document.querySelector(".reset-message") as HTMLElement;
resetMsg.style.display = "flex";
Expand All @@ -355,7 +386,7 @@ function resetGame(): void {
"--grid-columns": gridCols,
"--grid-rows": gridRows
};

// Set the CSS variables
for (const [key, value] of Object.entries(cssVariables)) {
document.documentElement.style.setProperty(key, String(value));
Expand All @@ -369,21 +400,21 @@ function resetGame(): void {

function generateCubes(): void {
console.log("generating cubes...")
do {
const container: HTMLDivElement = document.getElementById("container") as HTMLDivElement;
container.innerHTML = "";

for (let i = 0; i < gridRows * gridCols; i++) {
const cube = new Cube();
container?.appendChild(cube.element);
}
} while (!checkSolvable()); // Regenerate the cubes if the board is not solvable
const container: HTMLDivElement = document.getElementById("container") as HTMLDivElement;
container.innerHTML = "";

for (let i = 0; i < gridRows * gridCols; i++) {
const cube = new Cube();
container?.appendChild(cube.element);
}
}


function runTimer() {
const timerProgress = document.querySelector(".timer-progress-bar") as HTMLElement;
setTimeout(function () {
clearTimeout(timerProgressBar); // We need to clear to prevent memory leak after multiple games are played.
timerProgressBar = setTimeout(function () {
timerProgress.style.width = "0%";
}, 100);

Expand Down Expand Up @@ -425,7 +456,7 @@ function resetSettings() {
const timingSliderInput = document.querySelector(".timing-container input[type='range']") as HTMLInputElement;
const rowsSliderInput = document.querySelector(".rows-container input[type='range']") as HTMLInputElement;
const colsSliderInput = document.querySelector(".columns-container input[type='range']") as HTMLInputElement;

timingSliderInput.value = "25";
rowsSliderInput.value = "8";
colsSliderInput.value = "11";
Expand Down

0 comments on commit 899ffd2

Please sign in to comment.