From a327c0ed5e436c7a944f04331e14801ac51c94d2 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 11 Dec 2025 00:35:06 -0800 Subject: [PATCH 01/15] chore(curriculum): Add workshop-escape-room js-project prototype --- fullstack-cert/js-projects/workshop-escape-room/script.js | 0 fullstack-cert/js-projects/workshop-escape-room/user-stories.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 fullstack-cert/js-projects/workshop-escape-room/script.js create mode 100644 fullstack-cert/js-projects/workshop-escape-room/user-stories.md diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js new file mode 100644 index 000000000..e69de29bb diff --git a/fullstack-cert/js-projects/workshop-escape-room/user-stories.md b/fullstack-cert/js-projects/workshop-escape-room/user-stories.md new file mode 100644 index 000000000..e69de29bb From f64bad591e672616389cc449429035a77f44d3e4 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:17:37 -0800 Subject: [PATCH 02/15] feat(curriculum): Add patternMatch solution --- .../js-projects/workshop-escape-room/script.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index e69de29bb..0b7dbc074 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -0,0 +1,14 @@ +const patternMatch = (text, pattern) => { + let left = 0; + let right = text.length; + const patternOffset = pattern.length; + while (left < right) { + if (text.slice(left, left + patternOffset) === pattern || + text.slice(right, right - patternOffset) === pattern) { + return true; + } + left++; + right--; + } + return false; +} \ No newline at end of file From 7f9cc8afaa7183b959fa196fca50420beac2cb32 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:25:59 -0800 Subject: [PATCH 03/15] feat(curriculum): Add countdown solution --- .../js-projects/workshop-escape-room/script.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 0b7dbc074..9ae25d7f3 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -1,3 +1,13 @@ +const countdown = () => { + const answerToLifeMeaningUniverse = 42; + for (let i = 120; i > 0; i--) { + if (i === answerToLifeMeaningUniverse) { + return true; + } + } + return false; +} + const patternMatch = (text, pattern) => { let left = 0; let right = text.length; From 2e6ea1e2f7b1e7496ddf0d590cff81ba11d9b7e5 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Wed, 17 Dec 2025 22:42:55 -0800 Subject: [PATCH 04/15] feat(curriculum): Add inputValidator solution --- fullstack-cert/js-projects/workshop-escape-room/script.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 9ae25d7f3..8c693fbb9 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -21,4 +21,12 @@ const patternMatch = (text, pattern) => { right--; } return false; +} + +const inputValidator = () => { + const minUsernameSize = 3; + let username; + do { + username = prompt('Please enter a valid username'); + } while (username.trim() === '' || username.length < minUsernameSize); } \ No newline at end of file From e0e81b673f1c4cc2e2bd0797cedb0d6ded1b2e9f Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 00:07:22 -0800 Subject: [PATCH 05/15] feat(curriculum): Return username in inputValidator --- fullstack-cert/js-projects/workshop-escape-room/script.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 8c693fbb9..d62c1eb99 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -29,4 +29,6 @@ const inputValidator = () => { do { username = prompt('Please enter a valid username'); } while (username.trim() === '' || username.length < minUsernameSize); + + return username; } \ No newline at end of file From 455a59c552adfc62de865229ccc2c45a7e6d8021 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:02:58 -0800 Subject: [PATCH 06/15] feat(curriculum): Add progressState object --- .../js-projects/workshop-escape-room/script.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index d62c1eb99..7cefd59f9 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -1,3 +1,15 @@ +const progressState = { + 1: { + isSolved: false + }, + 2: { + isSolved: false + }, + 3: { + isSolved: false + }, +}; + const countdown = () => { const answerToLifeMeaningUniverse = 42; for (let i = 120; i > 0; i--) { From b16202ace6b2381d6394c241bf58ba309c086b16 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 12:19:52 -0800 Subject: [PATCH 07/15] feat(curriculum): Add keypad object --- .../js-projects/workshop-escape-room/script.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 7cefd59f9..4d92a70fe 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -43,4 +43,16 @@ const inputValidator = () => { } while (username.trim() === '' || username.length < minUsernameSize); return username; -} \ No newline at end of file +} + +const keypad = { + 1: { + isLocked: true, + }, + 2: { + isLocked: true, + }, + 3: { + isLocked: true, + } +}; \ No newline at end of file From 6f9c57f78f3546be1fa8faaf9cb2be0a70416328 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:22:26 -0800 Subject: [PATCH 08/15] fix(curriculum): Remove prompt usage from inputValidator --- .../workshop-escape-room/script.js | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 4d92a70fe..ef2254c9f 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -35,14 +35,22 @@ const patternMatch = (text, pattern) => { return false; } -const inputValidator = () => { - const minUsernameSize = 3; - let username; +const inputValidator = username => { + const minLength = 3; + const maxLength = 17; + const isValidInput = username => + username.length >= minLength && username.length <= maxLength; + do { - username = prompt('Please enter a valid username'); - } while (username.trim() === '' || username.length < minUsernameSize); + if (isValidInput(username)) { + console.log('Valid username entered...proceed'); + return true; + } + } while(username.trim() === ''); - return username; + console.log('Invalid username. It should be between 3 and 17 characters'); + + return false; } const keypad = { From 2c6e2efd90d9cd738ef4cbb35e7a37da103c9537 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:30:07 -0800 Subject: [PATCH 09/15] feat(curriculum): Add openDoor object --- .../workshop-escape-room/script.js | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index ef2254c9f..27ed7a3d8 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -63,4 +63,27 @@ const keypad = { 3: { isLocked: true, } -}; \ No newline at end of file +}; + +const openDoor = keypad => { + if (countdown()) { + keypad[1].isLocked = false; + console.log('Clue 1 solved: keypad 1 unlocked'); + } + + if (patternMatch('freecodecampfccFREECODECAMP', 'fcc')) { + keypad[2].isLocked = false; + console.log('Clue 2 solved: keypad 2 unlocked'); + } + + if (inputValidator('fcc102014')) { + keypad[3].isLocked = false; + console.log('Clue 3 solved: keypad 3 unlocked'); + } + + if (Object.values(keypad).every(lock => lock.isLocked === false)) { + console.log('Congratulations! You have solved all the puzzles and can now exit!'); + } else { + console.log('Access denied. One or more of the locks are still locked. Please check the progressState'); + } +} \ No newline at end of file From d308f575771c823207e667a678e176577575ed67 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:32:08 -0800 Subject: [PATCH 10/15] feat(curriculum): Call openDoor function to escape room --- fullstack-cert/js-projects/workshop-escape-room/script.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 27ed7a3d8..17dc33dc8 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -86,4 +86,6 @@ const openDoor = keypad => { } else { console.log('Access denied. One or more of the locks are still locked. Please check the progressState'); } -} \ No newline at end of file +} + +openDoor(keypad); \ No newline at end of file From 354f934fa647994b4eab5e28ba42ba7be7525ad3 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Thu, 29 Jan 2026 10:56:32 -0800 Subject: [PATCH 11/15] fix: Add html file for `prompt` support --- .../js-projects/workshop-escape-room/script.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 17dc33dc8..9ad17f9e6 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -35,22 +35,16 @@ const patternMatch = (text, pattern) => { return false; } -const inputValidator = username => { +const inputValidator = () => { + let username; const minLength = 3; const maxLength = 17; - const isValidInput = username => + const isValidLength = username => username.length >= minLength && username.length <= maxLength; do { - if (isValidInput(username)) { - console.log('Valid username entered...proceed'); - return true; - } - } while(username.trim() === ''); - - console.log('Invalid username. It should be between 3 and 17 characters'); - - return false; + username = prompt('Please enter a valid username:'); + } while(username === '' && !isValidLength); } const keypad = { @@ -76,7 +70,7 @@ const openDoor = keypad => { console.log('Clue 2 solved: keypad 2 unlocked'); } - if (inputValidator('fcc102014')) { + if (inputValidator()) { keypad[3].isLocked = false; console.log('Clue 3 solved: keypad 3 unlocked'); } From 8d812d056c87448732c16147c5ab05e4a19dea55 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Fri, 30 Jan 2026 00:44:08 -0800 Subject: [PATCH 12/15] refactor: inputValidator returns a boolean value --- fullstack-cert/js-projects/workshop-escape-room/script.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 9ad17f9e6..dc08820e9 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -40,11 +40,13 @@ const inputValidator = () => { const minLength = 3; const maxLength = 17; const isValidLength = username => - username.length >= minLength && username.length <= maxLength; + username.length >= minLength && username.length <= maxLength; do { username = prompt('Please enter a valid username:'); - } while(username === '' && !isValidLength); + } while(username === '' || username === null); + + return isValidLength(username); } const keypad = { From 00885aab87769fc6f96444ca1c63b03ae0922e66 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Fri, 30 Jan 2026 11:37:27 -0800 Subject: [PATCH 13/15] refactor: Remove `Object.values` usage and use `for..in` loop --- .../js-projects/workshop-escape-room/script.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index dc08820e9..73b7715d7 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -62,6 +62,8 @@ const keypad = { }; const openDoor = keypad => { + let isOpen = true; + if (countdown()) { keypad[1].isLocked = false; console.log('Clue 1 solved: keypad 1 unlocked'); @@ -76,8 +78,17 @@ const openDoor = keypad => { keypad[3].isLocked = false; console.log('Clue 3 solved: keypad 3 unlocked'); } - - if (Object.values(keypad).every(lock => lock.isLocked === false)) { + + checkKeypad: { + for (const lockNumber in keypad) { + if (keypad[lockNumber].isLocked) { + isOpen = false; + break checkKeypad; + } + } + } + + if (isOpen) { console.log('Congratulations! You have solved all the puzzles and can now exit!'); } else { console.log('Access denied. One or more of the locks are still locked. Please check the progressState'); From 676be6c563276415762be29fb6500ea79e6b0b8c Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Fri, 30 Jan 2026 11:56:55 -0800 Subject: [PATCH 14/15] refactor: Remove deprecated progressState object --- .../js-projects/workshop-escape-room/script.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/fullstack-cert/js-projects/workshop-escape-room/script.js b/fullstack-cert/js-projects/workshop-escape-room/script.js index 73b7715d7..d224ea5f0 100644 --- a/fullstack-cert/js-projects/workshop-escape-room/script.js +++ b/fullstack-cert/js-projects/workshop-escape-room/script.js @@ -1,15 +1,3 @@ -const progressState = { - 1: { - isSolved: false - }, - 2: { - isSolved: false - }, - 3: { - isSolved: false - }, -}; - const countdown = () => { const answerToLifeMeaningUniverse = 42; for (let i = 120; i > 0; i--) { From 7bbec3fcd5dc2ea119f0880a1f5152c39c029b19 Mon Sep 17 00:00:00 2001 From: Miguel T Rivera <10368105+mtrivera@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:19:53 -0800 Subject: [PATCH 15/15] chore: Add index.html file --- .../js-projects/workshop-escape-room/index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 fullstack-cert/js-projects/workshop-escape-room/index.html diff --git a/fullstack-cert/js-projects/workshop-escape-room/index.html b/fullstack-cert/js-projects/workshop-escape-room/index.html new file mode 100644 index 000000000..d3bb7c5f7 --- /dev/null +++ b/fullstack-cert/js-projects/workshop-escape-room/index.html @@ -0,0 +1,14 @@ + + + +
+ + +