-
-
Notifications
You must be signed in to change notification settings - Fork 0
Grand Gardenias #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Grand Gardenias #19
Changes from all commits
2fb7e46
7a6b551
6186a3e
f260bb4
1297f9a
de46bf4
ac9f080
247bebf
b650333
99f9648
c78ba78
f18d8d9
6eac7fb
f36fd45
c29416d
34f6289
608fbce
0f7b87d
3112581
f3b599e
2704bcb
625de32
e90c187
bbe73ba
1692e72
53dc722
76255a6
51ef14f
187b5d3
a9d6d0c
09a1669
ee428c1
ba7a8a4
fed4933
51e8149
5ead106
e250dc0
ac9ae1f
197b410
3e39101
864f46e
9005c8d
e2823dd
0e0d598
4e18f22
a4575ba
26da5c8
03d7f9f
68ea0fe
e81da79
18bc9d1
95717ff
033667b
f8a5fa8
aa60e3b
66b4b7c
ccc2c6c
2768f31
a60c014
943fde8
972d2d7
67fc603
a55a33f
8f15e62
6100925
6781df5
aefc5c9
4f25b9f
1e10d43
f0557fe
b51bb6f
84366f3
0f8bda0
fa8114d
f562120
e9c25af
b0040ac
2dcfcfd
84bffdf
cc76c9a
e98fb68
73d2341
a80c517
25fbee0
c51c626
397d135
2fd72d1
e0de628
4011f1b
a7ccd38
7041d3e
c8d096c
04286b0
15cffd4
2ef134a
006be7a
beb72a1
ca4cf2c
e950965
54aeaeb
bc4d26b
9316796
d23d011
4c876d5
f565d12
a2ac6e6
932e09f
aa6fd97
ab8d860
43dfd3c
e201148
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # GitHub Action workflow enforcing our code style. | ||
|
|
||
| name: Lint | ||
|
|
||
| # Trigger the workflow on both push (to the main repository, on the main branch) | ||
| # and pull requests (against the main repository, but from any repo, from any branch). | ||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| pull_request: | ||
|
|
||
| # Brand new concurrency setting! This ensures that not more than one run can be triggered for the same commit. | ||
| # It is useful for pull requests coming from the main repository since both triggers will match. | ||
| concurrency: lint-${{ github.sha }} | ||
|
|
||
| jobs: | ||
| lint: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| env: | ||
| # The Python version your project uses. Feel free to change this if required. | ||
| PYTHON_VERSION: "3.12" | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python ${{ env.PYTHON_VERSION }} | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ env.PYTHON_VERSION }} | ||
|
|
||
| - name: Run pre-commit hooks | ||
| uses: pre-commit/action@v3.0.1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Files generated by the interpreter | ||
| __pycache__/ | ||
| *.py[cod] | ||
|
|
||
| # Environment specific | ||
| .venv | ||
| venv | ||
| .env | ||
| env | ||
|
|
||
| # Unittest reports | ||
| .coverage* | ||
|
|
||
| # Logs | ||
| *.log | ||
|
|
||
| # PyEnv version selector | ||
| .python-version | ||
|
|
||
| # Built objects | ||
| *.so | ||
| dist/ | ||
| build/ | ||
|
|
||
| # IDEs | ||
| # PyCharm | ||
| .idea/ | ||
| # VSCode | ||
| .vscode/ | ||
| # MacOS | ||
| .DS_Store | ||
|
|
||
| # npm and tailwindcss | ||
| # Dependency directory | ||
| node_modules/ | ||
|
|
||
| # Generated files | ||
| dist/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # Pre-commit configuration. | ||
| # See https://github.com/python-discord/code-jam-template/tree/main#pre-commit-run-linting-before-committing | ||
|
|
||
| repos: | ||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| rev: v5.0.0 | ||
| hooks: | ||
| - id: check-toml | ||
| - id: check-yaml | ||
| - id: end-of-file-fixer | ||
| - id: trailing-whitespace | ||
| args: [--markdown-linebreak-ext=md] | ||
|
|
||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.12.2 | ||
| hooks: | ||
| - id: ruff-check | ||
| - id: ruff-format |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| Copyright 2021 Python Discord | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| <p align="center"> | ||
| <img src="docs/img/logo.svg" alt="Project Logo" width="200"/> | ||
| </p> | ||
|
|
||
| # 👾 Tetris Bugs: The Code Editor You Never Asked For | ||
|
|
||
| Built by **Grand Gardenias** for Python Discord's Summer CodeJam 2025. Challenge theme: **Wrong Tool for the Job** using **Python in the Browser** via [Pyscript](https://pyscript.net/). | ||
|
|
||
| --- | ||
|
|
||
| ## 🎯 The Concept | ||
|
|
||
| Instead of typing code like a normal human, you now have to **catch falling code blocks** and arrange them into working programs. | ||
|
|
||
| ## 🎮 Game Modes (Choose Your Suffering) | ||
|
|
||
| ### 1. 🏗️ Tetris Code Editor | ||
|
|
||
| - New File | ||
| - Export/Save | ||
| - Undo/Redo | ||
| - Run Code | ||
| - Terminal Output | ||
| - Code Falls from Sky | ||
|
|
||
| ### 2. ⚡ CodeRush Mode | ||
|
|
||
| - 5-minute timer counting down | ||
| - Questions show up on the left | ||
| - Solve as many as you can before time’s up | ||
| - Your score = how many problems you solved before the end | ||
|
|
||
| ### 3. 🗡️ Roguelike Mode | ||
|
|
||
| - We provide the CORRECT solution | ||
| - Arrange the blocks properly to "clear" lines like Tetris | ||
| - Wrong arrangements stack up | ||
| - Reach the top = GAME OVER | ||
|
|
||
| ### 4. We could not finish the multiplayer mode, but it is documented in [docs/goals.md](docs/goals.md) | ||
|
|
||
| ## 🛠️ Tech Stack | ||
|
|
||
| - **PyScript** | ||
| - **TailwindCSS** | ||
|
|
||
| ## 📦 Requirements | ||
|
|
||
| - Python 3.13+ | ||
| - Node.js & npm | ||
|
|
||
| ## ⚙️ Setup Instructions | ||
|
|
||
| 1. Clone the repository: | ||
| ```shell | ||
| git clone https://github.com/zishankadri/tetris-bugs.git | ||
| cd tetris-bugs | ||
| ``` | ||
| 3. Start a local Server: | ||
| ```shell | ||
| cd frontend | ||
| npm install | ||
| npm run build | ||
| python -m http.server | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick/out of scope for a brief code jam, but be mindful of how this app is run. I see that multiplayer may be a future feature and this run method allows for path traversal, so could be risky to expose to the internet. |
||
| ``` | ||
|
|
||
| 3. **Open Your Browser** to `http://localhost:8000` | ||
| 4. 💡 For Contributors: Run `npm run dev` to auto-update Tailwind while you code. | ||
|
|
||
| ## 🎉 Achievement Unlocked | ||
| **Congratulations! You now have the most unique answer to "What IDE do you use?"** | ||
|
|
||
| *"Oh, I use Tetris."* | ||
|
|
||
| ## Video Presentation | ||
| [code-editor.webm](https://github.com/user-attachments/assets/cf059496-4f29-4d98-a95a-8969f91b333e) | ||
|
|
||
| <details> | ||
| <summary>⚡ CodeRush Video Presentation </summary> | ||
| https://drive.google.com/file/d/1t6_92z2R_ntOok2yyzjklHpKyxoKZl_g/view | ||
| </details> | ||
|
|
||
| <details> | ||
| <summary>🗡️ Roguelike (BETA) Video Presentation </summary> | ||
|
|
||
| [roguelike.webm](https://github.com/user-attachments/assets/ffc35054-e3de-4e12-ac63-f1e3520f2ee8) | ||
| </details> | ||
|
|
||
| ## 📸 Screenshots | ||
| <details> | ||
| <summary>Preview Images 📸</summary> | ||
| <img width="1314" height="655" alt="code-editor" src="https://github.com/user-attachments/assets/d3d61ead-39b7-44e8-b62f-207709f3b1b6" /> | ||
| <img width="1360" height="676" alt="code-editor" src="https://github.com/user-attachments/assets/b8d619c7-280e-4e5e-b9b6-c59bfa21ccf9" /> | ||
| <img width="1360" height="768" alt="code-rush" src="https://github.com/user-attachments/assets/6f6c9027-1017-43cc-95ef-c971d493ccb7" /> | ||
| <img width="1360" height="676" alt="roguelike" src="https://github.com/user-attachments/assets/4142aa8b-012b-4f29-85a0-8624e1ef33e5" /> | ||
| <img width="1311" height="655" alt="menu" src="https://github.com/user-attachments/assets/1220ca0c-c8a3-49f1-a50d-1bd76965e989" /> | ||
|
|
||
| </details> | ||
|
|
||
| ## 🎯 Wrong Tool for the Job | ||
|
|
||
| ✅ Using Tetris as an IDE | ||
| ✅ Spatial reasoning for coding problems | ||
|
|
||
| With some tweaks and backend, this could be a useful tool as a coding qualifier, as we doubt any LLM alone could pass this test. | ||
|
|
||
| ## 🤝 Credits | ||
|
|
||
| (in order of contributed LOC): | ||
|
|
||
| <table> | ||
| <tr> | ||
| <th></th> | ||
| <th>Name</th> | ||
| <th>Contributions</th> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="https://github.com/zishankadri"><img src="https://github.com/zishankadri.png" alt="Luffy" width="64"></a></td> | ||
| <td><a href="https://github.com/zishankadri">Luffy</a></td> | ||
| <td>Lead developer, Project architecture, Ideation, Frontend</td> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="https://github.com/rxdiationx"><img src="https://github.com/rxdiationx.png" alt="rxdiationx" width="64"></a></td> | ||
| <td><a href="https://github.com/rxdiationx">rxdiationx</a></td> | ||
| <td>Base of CodeRush, sound effects/music, loading screen, Sourcing of problems</td> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="https://github.com/Sapient44"><img src="https://github.com/Sapient44.png" alt="Sapient44" width="64"></a></td> | ||
| <td><a href="https://github.com/Sapient44">Sapient44</a></td> | ||
| <td>Terminal and code execution, Modifications in roguelike mode, Sourcing of audio</td> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="https://github.com/Shivk123"><img src="https://github.com/Shivk123.png" alt="Shivk123" width="64"></a></td> | ||
| <td><a href="https://github.com/Shivk123">Shivk123</a></td> | ||
| <td>Meeting facilitation, Initial file structure, Set up Flask backend</td> | ||
| </tr> | ||
| <tr> | ||
| <td><a href="https://github.com/mhasanali2010"><img src="https://github.com/mhasanali2010.png" alt="mhasanali2010" width="64"></a></td> | ||
| <td><a href="https://github.com/mhasanali2010">mhasanali2010</a></td> | ||
| <td>timer logic, pause screen</td> | ||
| </tr> | ||
| </table> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Define paths | ||
| from pathlib import Path | ||
|
|
||
| from flask import Flask, render_template | ||
|
|
||
| template_dir = Path(__file__).resolve().parent.parent / "frontend" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This path is re-used in run.py, could be better off as a constant in something like |
||
| static_dir = template_dir # if your CSS/JS/config are in frontend/ | ||
|
|
||
| app = Flask( | ||
| __name__, | ||
| template_folder=template_dir, | ||
| static_folder=static_dir, # serve static files from frontend/ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some of these comments may be a bit overboard. If the code is self explanatory, I would avoid comments like this. My best advice here is to focus on the why for code comments. If no explanation for the "why" is needed/helpful, the comment can probably be discarded. I.e |
||
| static_url_path="", # serve at root so /config.json works | ||
| ) | ||
|
|
||
|
|
||
| @app.route("/") | ||
| def home() -> None: | ||
| """Render the main page.""" | ||
| # Render the index.html file from the frontend directory | ||
| return render_template("index.html") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import shutil | ||
| import subprocess | ||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| from flask.cli import main as flask_main | ||
|
|
||
| DEFAULT_ARG_COUNT = 2 # Avoid magic number | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a magic number. Good example of where a comment can help explain the why ;) |
||
|
|
||
|
|
||
| def main() -> None: | ||
| """Run the Flask application and start the frontend development server.""" | ||
| frontend_dir = Path(__file__).parent.parent / "frontend" | ||
|
|
||
| # Locate npm safely | ||
| npm_path = shutil.which("npm") | ||
| if npm_path is None: | ||
| print("npm not found in PATH.") | ||
| sys.exit(1) | ||
|
|
||
| # Start npm dev server | ||
| try: | ||
| subprocess.Popen( # noqa: S603 | ||
| [npm_path, "run", "dev"], | ||
| cwd=frontend_dir, | ||
| ) | ||
| print("Frontend dev server started.") | ||
| except OSError as err: | ||
| print(f"Failed to start frontend: {err}") | ||
|
|
||
| sys.argv.insert(1, "--app=backend.app") | ||
|
|
||
| if len(sys.argv) == DEFAULT_ARG_COUNT: | ||
| sys.argv.append("run") | ||
|
|
||
| flask_main() | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Project Architecture | ||
|
|
||
| *(See  for visual reference.)* | ||
|
|
||
| **Goal:** Avoid circular imports, enable reuse across modes, separate concerns. | ||
|
|
||
| ## Layers | ||
|
|
||
| 1. **Objects Layer** — self-contained game entities (no external knowledge). | ||
| 2. **Core Game Management** — orchestrates state, no DOM access. | ||
| 3. **Support Modules** — UI Manager, controls, block generators. | ||
|
|
||
| **Entry Point:** `main` wires components together and selects the mode. | ||
|
|
||
| ## Dependency Rules | ||
|
|
||
| - Objects → no outward dependencies. | ||
| - Game Manager → can talk to objects & support modules, but no cycles. | ||
| - UI Manager → DOM Manipulation. | ||
| - Controls → interact with Game Manager and objects only. | ||
| - `main` → composition root, no logic. | ||
|
|
||
| Modes can add their own files, but they must follow the same rules. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # MULTIPLAYER | ||
|
|
||
|  | ||
|
|
||
| ## THE CONCEPT OF 👾 Bugs | ||
|
|
||
| Occasionally, instead of the actual code blocks, the player will receive bugs from a number of pre-defined weapons in a class named 'Bugs' e.g. Bugs.beetle(). I originally thought of Bugs.bomb (), which on placing will immediately disappear from the player's own screen, but a bomb will appear at the same spot on the enemy's screen touching which will require the enemy to do over that one block, giving us a 'time advantage'. This will make so much sense if we create a 'time-based winner' game. (Open to suggestions this is just an example I have in mind for now.) | ||
|
|
||
|  | ||
|
|
||
| ## Bugs.beetle() | ||
|
|
||
|  |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I appreciate how easy your app is to run, I really like adding docker as an option to full-stack projects. When there is a frontend and backend component, building and running can be nicely automated and simplified this way.
A really rough example of a Dockerfile (emphasis on rough) that could work for something like this is as follows:
Then run
docker build -t grand-gardenias ., followed bydocker run grand-gardenias -p 8000:8000