From e959f1998db03fa41869e3853177d0a2712f651b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:15:31 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improved=20input?= =?UTF-8?q?=20responsiveness=20and=20visual=20feedback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced sleep-based loop with dynamic poll() timeout for better responsiveness. - Added immediate visual feedback on keypresses. - Cleaned up mode toggle display to avoid terminal clutter. - Added UX learning to .Jules/palette.md. Co-authored-by: aidasofialily-cmd <247843425+aidasofialily-cmd@users.noreply.github.com> --- .Jules/palette.md | 4 ++++ src/main.cpp | 34 ++++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 01736b2..36fd6b3 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. + +## 2026-01-09 - Tactile CLI Feedback +**Learning:** For terminal-based games, users expect immediate visual confirmation of their actions. Triggering a UI redraw instantly on input events—rather than waiting for the next timer-based tick—makes the application feel significantly more responsive. +**Action:** Always call the display update function immediately after processing user input, and use carriage returns (`\r`) with padding to maintain a clean, single-line interface. diff --git a/src/main.cpp b/src/main.cpp index a70e887..31e89d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include int main() { struct termios oldt, newt; @@ -18,22 +19,35 @@ int main() { struct pollfd fds[1] = {{STDIN_FILENO, POLLIN, 0}}; auto last_tick = std::chrono::steady_clock::now(); + auto updateDisplay = [&](int s, bool hm) { + std::cout << "\rScore: " << s << (hm ? " [HARD MODE] " : " [NORMAL] ") << std::flush; + }; + + updateDisplay(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 timeout = std::max(0, static_cast(interval - elapsed)); + + if (poll(fds, 1, timeout) > 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++; + } + updateDisplay(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; + updateDisplay(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"; From 86c0a0c534690feab5888c20afa03e9720b3cc82 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 17:18:39 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Improved=20input?= =?UTF-8?q?=20responsiveness=20and=20fixed=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced sleep-based loop with dynamic poll() timeout for better responsiveness. - Added immediate visual feedback on keypresses. - Cleaned up mode toggle display to avoid terminal clutter. - Fixed GitHub Actions CI by switching from Rust to C++ build/test workflow. - Added UX learning to .Jules/palette.md. Co-authored-by: aidasofialily-cmd <247843425+aidasofialily-cmd@users.noreply.github.com> --- .github/workflows/{rust.yml => build.yml} | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename .github/workflows/{rust.yml => build.yml} (65%) diff --git a/.github/workflows/rust.yml b/.github/workflows/build.yml similarity index 65% rename from .github/workflows/rust.yml rename to .github/workflows/build.yml index 9fd45e0..f85021b 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Rust +name: Build and Test on: push: @@ -6,17 +6,16 @@ on: 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 + run: make + - name: Run tests - run: cargo test --verbose + run: | + echo "aaaq" | ./game | grep "Final Score: 3"