commit b5fb570df48d3183de7c1dca08430f5a21473c5f Author: Andrew Haynes Date: Sun Sep 6 15:46:06 2026 -0400 Batman: I forgot to commit the new website branch so I guess here it is with bun and a cool game page diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a14702c --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..91085ae --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# escape + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.4.0. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime. diff --git a/assets/boat.jpg b/assets/boat.jpg new file mode 100644 index 0000000..2868d1d Binary files /dev/null and b/assets/boat.jpg differ diff --git a/assets/boat.png b/assets/boat.png new file mode 100644 index 0000000..515edbe Binary files /dev/null and b/assets/boat.png differ diff --git a/assets/shipwreck.png b/assets/shipwreck.png new file mode 100644 index 0000000..9185fa7 Binary files /dev/null and b/assets/shipwreck.png differ diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..6b23a4a --- /dev/null +++ b/bun.lock @@ -0,0 +1,66 @@ +{ + "lockfileVersion": 2, + "configVersion": 1, + "workspaces": { + "": { + "name": "escape", + "devDependencies": { + "@types/bun": "latest", + }, + "peerDependencies": { + "typescript": "^7", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.4.0", "", { "dependencies": { "bun-types": "1.4.0" } }, "sha512-K+lZULY23vRgK/CfTjFIV+tyifaNdSMlPh9j+6mQ/cLfpOznLyAuzgV/JQysyECpkBQLVMSyvjlr2fBUSA9wFQ=="], + + "@types/node": ["@types/node@26.4.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-k97ENvZWtvA6yqz5/FS6a7duDgOPEeOQOc2iKS/nY6mX6qJUKtLnWzQS+Xj6tXweyj6ZcTAK2Qecetnvi9nCLA=="], + + "@typescript/typescript-aix-ppc64": ["@typescript/typescript-aix-ppc64@7.0.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ=="], + + "@typescript/typescript-darwin-arm64": ["@typescript/typescript-darwin-arm64@7.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA=="], + + "@typescript/typescript-darwin-x64": ["@typescript/typescript-darwin-x64@7.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA=="], + + "@typescript/typescript-freebsd-arm64": ["@typescript/typescript-freebsd-arm64@7.0.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ=="], + + "@typescript/typescript-freebsd-x64": ["@typescript/typescript-freebsd-x64@7.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw=="], + + "@typescript/typescript-linux-arm": ["@typescript/typescript-linux-arm@7.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ=="], + + "@typescript/typescript-linux-arm64": ["@typescript/typescript-linux-arm64@7.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ=="], + + "@typescript/typescript-linux-loong64": ["@typescript/typescript-linux-loong64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ=="], + + "@typescript/typescript-linux-mips64el": ["@typescript/typescript-linux-mips64el@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA=="], + + "@typescript/typescript-linux-ppc64": ["@typescript/typescript-linux-ppc64@7.0.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA=="], + + "@typescript/typescript-linux-riscv64": ["@typescript/typescript-linux-riscv64@7.0.2", "", { "os": "linux", "cpu": "none" }, "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ=="], + + "@typescript/typescript-linux-s390x": ["@typescript/typescript-linux-s390x@7.0.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw=="], + + "@typescript/typescript-linux-x64": ["@typescript/typescript-linux-x64@7.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A=="], + + "@typescript/typescript-netbsd-arm64": ["@typescript/typescript-netbsd-arm64@7.0.2", "", { "os": "none", "cpu": "arm64" }, "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA=="], + + "@typescript/typescript-netbsd-x64": ["@typescript/typescript-netbsd-x64@7.0.2", "", { "os": "none", "cpu": "x64" }, "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA=="], + + "@typescript/typescript-openbsd-arm64": ["@typescript/typescript-openbsd-arm64@7.0.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ=="], + + "@typescript/typescript-openbsd-x64": ["@typescript/typescript-openbsd-x64@7.0.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg=="], + + "@typescript/typescript-sunos-x64": ["@typescript/typescript-sunos-x64@7.0.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g=="], + + "@typescript/typescript-win32-arm64": ["@typescript/typescript-win32-arm64@7.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ=="], + + "@typescript/typescript-win32-x64": ["@typescript/typescript-win32-x64@7.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g=="], + + "bun-types": ["bun-types@1.4.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-iIKw23BspnQQYd3prITOBxeUsxBHnwzX6YJfGMuNOZzeNcMmVqzIIVGRm1l69ogaPQmb4wB6BN8mA5bE9YuC5Q=="], + + "typescript": ["typescript@7.0.2", "", { "optionalDependencies": { "@typescript/typescript-aix-ppc64": "7.0.2", "@typescript/typescript-darwin-arm64": "7.0.2", "@typescript/typescript-darwin-x64": "7.0.2", "@typescript/typescript-freebsd-arm64": "7.0.2", "@typescript/typescript-freebsd-x64": "7.0.2", "@typescript/typescript-linux-arm": "7.0.2", "@typescript/typescript-linux-arm64": "7.0.2", "@typescript/typescript-linux-loong64": "7.0.2", "@typescript/typescript-linux-mips64el": "7.0.2", "@typescript/typescript-linux-ppc64": "7.0.2", "@typescript/typescript-linux-riscv64": "7.0.2", "@typescript/typescript-linux-s390x": "7.0.2", "@typescript/typescript-linux-x64": "7.0.2", "@typescript/typescript-netbsd-arm64": "7.0.2", "@typescript/typescript-netbsd-x64": "7.0.2", "@typescript/typescript-openbsd-arm64": "7.0.2", "@typescript/typescript-openbsd-x64": "7.0.2", "@typescript/typescript-sunos-x64": "7.0.2", "@typescript/typescript-win32-arm64": "7.0.2", "@typescript/typescript-win32-x64": "7.0.2" }, "bin": { "tsc": "bin/tsc" } }, "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA=="], + + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..979154c --- /dev/null +++ b/index.html @@ -0,0 +1,141 @@ + + + + Escape the Island + + + + + + + + +
+
+

Escape the Island

+
+ +
+
+
+
+
+

Backstory

+
+ Click to expand +

+ You and your class planned to go on a one week cruise trip over + spring break to learn about how inflation affects nautical + exploration and catching some sun. The cruise ship is built a pirate + ship which you all find amusing at first. However, issues arise from + an underlying problem. They didn't have the money to get schedule a + final inspection before departing, but they still let you go anyways + (because they are broke). As the boat leaves and cruises away from + land, you see rocky terrain that has formed in the middle of the + ocean (shocking). Your boat hits it and as people don't learn from + the titanic, you don't have enough life boats to fit everyone and + make it home safely. Everybody else gets on boats while you and your + classmates are still on the boat (coincidentally). One of your + friends believes he has a boat license (he doesn't) and tries to + steer the boat before you sink. Magically you find an island. You + all get onto the island safely but with no way home, scattered and + disoriented. +

+
+
+
+

Objective

+
+ Click to expand +

+ You will have 16 hours each day to gain as many resources as + possible to survive. You must choose what to spend your hours doing + each day carefully. The survival requirement for the end of each day + is to have 8 fish and 4 pieces of lumber. Otherwise, you die (lose). + You will be able to trade with other classmates you have found + stranded at no expense of your daily hours. +

+
+
+
+

Requirements

+
+ Click to expand +
    +
  1. + In order to escape, you must have 24 stockpiled fish and a boat at + the START of a new day. +
  2. +
  3. Fish will go bad without a preserver.
  4. +
  5. + Improving skills requires 8 hours and adds 1 per hour the next + day. +
  6. +
  7. Building a preserver requires 8 hours and 25 wood
  8. +
  9. Building a boat requires 16 hours and 100 wood
  10. +
  11. You can only trade with "found" players
  12. +
  13. + It is recommended to donate resources to other players at end of + day if you have a boat (Need to have 24 fish to leave) +
  14. +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Fishing StatsForaging Stats
Days: 000
+ Players Found: 0 + Preserver: NoBoat: No
Hours Left: 16Stored Fish: Stored Wood:
+
+
+
+ + + +
+
+ + + + + +
+
+
+
+ + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..8696c73 --- /dev/null +++ b/index.js @@ -0,0 +1,107 @@ +function create_player_stats() { + let x = Math.floor(Math.random() * 2) + 1; + let y = 0; + if (x == 1) { + y = 2; + } else { + y = 1; + } + return { x: x, y: y }; +} + +let x, y; +function init() { + if (localStorage.getItem("player_x")) { + x = parseInt(localStorage.getItem("player_x")); + y = parseInt(localStorage.getItem("player_y")); + } else { + let player = create_player_stats(); + x = player.x; + y = player.y; + localStorage.setItem("player_x", x); + localStorage.setItem("player_y", y); + } + return { x: x, y: y }; +} +let player = init(); +let gamedata = { + fishing: { + per_hour: player.x, + preserver: "No", + stored: 0, + }, + foraging: { + per_hour: player.y, + boat: "No", + stored: 0, + }, + hours: 16, + days: 0, +}; + +function updateTable() { + document.getElementById("fish_p_hour").innerText = gamedata.fishing.per_hour; + document.getElementById("wood_p_hour").innerText = gamedata.foraging.per_hour; + document.getElementById("fish_stored").innerText = gamedata.fishing.stored; + document.getElementById("wood_stored").innerText = gamedata.foraging.stored; + document.getElementById("preserver").innerText = gamedata.fishing.preserver; + document.getElementById("boat").innerText = gamedata.foraging.boat; + document.getElementById("hours").innerText = gamedata.hours; + document.getElementById("days").innerText = gamedata.days; + if (gamedata.hours < 8) { + document.getElementById("improve-fishing").disabled = true; + } else { + document.getElementById("improve-fishing").disabled = false; + } + if (gamedata.hours < 8) { + document.getElementById("improve-forgaing").disabled = true; + } else { + document.getElementById("improve-forgaing").disabled = false; + } + if (gamedata.foraging.stored < 25 || gamedata.hours < 8) { + document.getElementById("build-preserver").disabled = true; + } else { + document.getElementById("build-preserver").disabled = false; + } + if (gamedata.foraging.stored < 100 || gamedata.hours < 16) { + document.getElementById("build-boat").disabled = true; + } else { + document.getElementById("build-boat").disabled = false; + } +} + +function go_fishing() { + let prompt = window.prompt("How many hours do you want to fish?"); + if (prompt === null || prompt > gamedata.hours) { + window.alert("You dont have the hours for this or prompt exited"); + console.log("Prompt Exited"); + } else { + gamedata.fishing.stored += prompt * gamedata.fishing.per_hour; + gamedata.hours -= prompt; + if (gamedata.hours === 0) { + gamedata.days++; + gamedata.hours = 16; + } + updateTable(); + } +} + +function go_foraging() { + let prompt = window.prompt("How many hours do you want to foraging?"); + if (prompt === null || prompt > gamedata.hours) { + window.alert("You dont have the hours for this or prompt exited"); + console.log("Prompt Exited"); + } else { + gamedata.foraging.stored += prompt * gamedata.foraging.per_hour; + gamedata.hours -= prompt; + if (gamedata.hours === 0) { + gamedata.days++; + gamedata.hours = 16; + } + updateTable(); + } +} +document.getElementById("go-fishing").onclick = go_fishing; +document.getElementById("go-foraging").onclick = go_foraging; + +updateTable(); diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..a609c4b --- /dev/null +++ b/index.ts @@ -0,0 +1,8 @@ +const server = Bun.serve({ + port: 3000, + routes: { + "/": () => new Response("Bun!"), + }, +}); + +console.log(`Listening on ${server.url}`); diff --git a/package.json b/package.json new file mode 100644 index 0000000..697fb69 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "escape", + "module": "index.ts", + "type": "module", + "private": true, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^7" + } +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..2a9a136 --- /dev/null +++ b/styles.css @@ -0,0 +1,167 @@ +html { + background-color: moccasin; + height: 100%; +} + +body { + background-color: cadetblue; + transition: background-color 0.1s ease-out; + margin: 20px; + padding: 0; + font-family: "Almendra"; +} + +header { + background-color: moccasin; + padding: 10px; + border-bottom: 2px dashed gray; + + .header-container { + display: flex; + flex-direction: row-reverse; + align-items: center; + + h1 { + color: cornflowerblue; + font-family: "Almendra"; + text-align: left; + font-size: clamp(20px, 10vh, 55px); + height: auto; + max-height: 100px; + flex: 1; + } + + .boat { + height: auto; + max-width: 150px; + width: 100%; + pointer-events: none; + display: block; + } + + .boat-container { + display: flex; + justify-content: left; + align-items: left; + width: 100%; + flex: 2; + } + } +} + +.Content { + margin-left: 10px; + margin-right: 10px; + + + .Instruction { + display: flex; + align-items: baseline; + gap: 10px; + + details { + p { + line-height: 1.4; + font-size: 20px; + color: black; + } + } + + p { + font-size: 40px; + text-align: left; + line-height: 1; + margin-top: 5px; + margin-bottom: 5px; + } + + li { + line-height: 1.4; + font-size: 20px; + color: black; + + } + + } + + .game { + display: flex; + width: 100%; + gap: 10px; + + .table-container { + padding: 10px; + flex: 1; + background-color: cadetblue; + + table, + th, + td, + tr { + border: 1px solid black; + } + + tr:nth-child(even) { + background-color: rgba(0, 0, 0, 0.2); + } + + tr:nth-child(odd) { + background-color: rgba(0, 0, 0, 0.125); + } + + table { + border-collapse: collapse; + width: 100%; + } + + th, + td { + padding: 10px; + text-align: center; + } + + th { + background-color: darkseagreen; + } + } + + .button-container { + flex: 1; + padding: 10px; + + .button-container-part { + display: flex; + + button { + font-family: "Almendra"; + font-size: 18px; + width: 100%; + text-align: center; + transition-duration: 0.2s; + padding: 7px; + height: clamp(30px, 15vh, 85px); + } + + button:hover { + background-color: darkseagreen; + color: black; + cursor: grab; + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.6); + border: 2px solid black; + } + + button:disabled { + pointer-events: none; + } + } + } + } +} + +footer { + background-color: moccasin; + width: 100%; + margin-top: 25px; + text-align: center; + border-top: 2px dashed gray; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b2e7497 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + "types": ["bun"], + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}