From 9918faf9b3818319d696c2886a5c3f8864828457 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 17:22:14 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improve=20game=20?= =?UTF-8?q?responsiveness=20and=20visual=20feedback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Centralize UI rendering to provide immediate tactile feedback on input. - Use ANSI colors (Green/Red) and bold text for better visual clarity. - Optimize the game loop using a dynamic poll() timeout for better responsiveness and CPU efficiency. - Ensure the Hard Mode toggle updates in-place without breaking the single-line UI. - Add a clear 'Game Over' banner. Co-authored-by: aidasofialily-cmd <247843425+aidasofialily-cmd@users.noreply.github.com> --- .Jules/palette.md | 4 ++++ src/main.cpp | 53 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 01736b2..07b4fe2 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -6,3 +6,7 @@ ## 2026-01-09 - Terminal I/O and Blocking **Learning:** Standard terminal I/O is line-buffered by default. For real-time games, it's essential to use non-canonical mode (raw mode) to capture keypresses immediately. Also, internal journals should be kept clean if they are to be included in the repo. + +## 2024-06-03 - Real-time CLI Feedback +**Learning:** For terminal applications, immediate feedback on user input is crucial for a "tactile" feel. Decoupling the UI update from the main game tick and centralizing it in a `render_ui` function ensures the display always reflects the current state instantly. Using `\r` and space padding allows for smooth, in-place updates without the flicker of clearing the whole screen. +**Action:** Always provide immediate visual confirmation of user actions in CLI tools, even if the primary state update happens on a timer. diff --git a/src/main.cpp b/src/main.cpp index a70e887..8931d6f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,22 @@ #include #include #include +#include + +void render_ui(int score, bool hardMode) { + const char* green = "\033[32m"; + const char* red = "\033[31m"; + const char* bold = "\033[1m"; + const char* reset = "\033[0m"; + + std::cout << "\r" << "Score: " << green << bold << score << reset; + if (hardMode) { + std::cout << " [" << red << bold << "HARD MODE" << reset << "] "; + } else { + std::cout << " [NORMAL] "; + } + std::cout << std::flush; +} int main() { struct termios oldt, newt; @@ -18,24 +34,39 @@ int main() { struct pollfd fds[1] = {{STDIN_FILENO, POLLIN, 0}}; auto last_tick = std::chrono::steady_clock::now(); + + render_ui(score, hardMode); + while (true) { - int timeout = hardMode ? 100 : 1000; - if (poll(fds, 1, 0) > 0) { + int interval = hardMode ? 100 : 1000; + auto now = std::chrono::steady_clock::now(); + auto elapsed = std::chrono::duration_cast(now - last_tick).count(); + int wait_time = std::max(0, (int)(interval - elapsed)); + + if (poll(fds, 1, wait_time) > 0) { if (read(STDIN_FILENO, &input, 1) <= 0 || input == 'q') break; if (input == 'h') { hardMode = !hardMode; - std::cout << (hardMode ? "\n[HARD MODE] Speed x10!\n" : "\n[NORMAL MODE]\n"); - } else score++; + } else { + score++; + } + render_ui(score, hardMode); } - auto now = std::chrono::steady_clock::now(); - auto elapsed = std::chrono::duration_cast(now - last_tick).count(); - if (elapsed >= timeout) { - score++; last_tick = now; - std::cout << "Score: " << score << (hardMode ? " [FAST] " : " [NORMAL] ") << "\r" << std::flush; + + now = std::chrono::steady_clock::now(); + elapsed = std::chrono::duration_cast(now - last_tick).count(); + if (elapsed >= interval) { + score++; + last_tick = now; + render_ui(score, hardMode); } - std::this_thread::sleep_for(std::chrono::milliseconds(10)); } + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); - std::cout << "\nFinal Score: " << score << "\nThanks for playing!\n"; + std::cout << "\n\n==========================\n" + << " GAME OVER\n" + << "==========================\n" + << "Final Score: " << score << "\n" + << "Thanks for playing!\n"; return 0; } From 0ef1a97244a2ec36924b630e16753a71dbc49a05 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 4 Feb 2026 17:26:02 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improve=20game=20?= =?UTF-8?q?UX=20and=20fix=20CI=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UX improvements: - Centralize UI rendering to provide immediate tactile feedback on input. - Use ANSI colors (Green/Red) and bold text for better visual clarity. - Optimize the game loop using a dynamic poll() timeout for better responsiveness. - Ensure the Hard Mode toggle updates in-place without breaking the single-line UI. - Add a clear 'Game Over' banner. CI fix: - Replace incorrect Rust workflow with a C++ Build workflow using 'make'. - Add a basic smoke test to the CI pipeline. Co-authored-by: aidasofialily-cmd <247843425+aidasofialily-cmd@users.noreply.github.com> --- .github/workflows/build.yml | 22 ++++++++++++++++++++++ .github/workflows/rust.yml | 22 ---------------------- 2 files changed, 22 insertions(+), 22 deletions(-) create mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f719fd6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,22 @@ +name: C++ Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Build + run: make + + - name: Test + run: | + # Run a simple check to see if the game can start and quit + (echo "q"; sleep 1) | ./game | grep "Thanks for playing!" diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 9fd45e0..0000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Rust - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Build - run: cargo build --verbose - - name: Run tests - run: cargo test --verbose