From 764b4685c16acce73ed7fe7072943d9b04132fed Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:54:01 +0000 Subject: [PATCH] Add ANSI Erase in Line escape sequence to prevent CLI trailing artifacts Co-authored-by: EiJackGH <172181576+EiJackGH@users.noreply.github.com> --- .Jules/palette.md | 4 ++++ .gitignore | 1 + src/main.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.Jules/palette.md b/.Jules/palette.md index 853ef9c..c604501 100644 --- a/.Jules/palette.md +++ b/.Jules/palette.md @@ -29,3 +29,7 @@ ## 2025-01-24 - Real-time Achievement Feedback in CLI **Learning:** In terminal-based games, displaying achievement progress (like a live high score) in real-time provides immediate tactile reward and engagement. Furthermore, inclusive UX means ensuring first-time players also receive "New Best" feedback, even when their initial record is zero. **Action:** Update session-high-score variables immediately upon record-breaking and display them in the live HUD. Ensure achievement conditions (`score > highscore`) don't exclude the first-time user experience. + +## 2026-05-24 - Preventing Trailing Artifacts in CLI +**Learning:** When using `\r` (carriage return) to repeatedly update a single line in the terminal, simply padding the output with hardcoded spaces is brittle. If the new output is shorter than the previous, the trailing characters from the older output will remain visible as "ghosts" unless completely overwritten. +**Action:** Always append the ANSI escape sequence `\033[K` (Erase in Line) immediately after `\r` to clear the current line from the cursor to the end, ensuring crisp, dynamic updates without hardcoding padding spaces. diff --git a/.gitignore b/.gitignore index eb2c19a..d07c78a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ highscore.txt # Persistent data highscore.txt +venv/ diff --git a/src/main.cpp b/src/main.cpp index af692c8..a74d829 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -94,7 +94,7 @@ int main() { } for (int i = 3; i > 0; --i) { - std::cout << "\rStarting in " << CLR_CTRL << i << CLR_RESET << "... " << std::flush; + std::cout << "\r\033[KStarting in " << CLR_CTRL << i << CLR_RESET << "... " << std::flush; auto start_wait = std::chrono::steady_clock::now(); while (std::chrono::duration_cast(std::chrono::steady_clock::now() - start_wait).count() < 1000) { int elapsed = std::chrono::duration_cast(std::chrono::steady_clock::now() - start_wait).count(); @@ -108,7 +108,7 @@ int main() { } } } - std::cout << "\r" << CLR_NORM << "GO! " << CLR_RESET << "\n" << std::flush; + std::cout << "\r\033[K" << CLR_NORM << "GO!" << CLR_RESET << "\n" << std::flush; std::this_thread::sleep_for(std::chrono::milliseconds(200)); tcflush(STDIN_FILENO, TCIFLUSH); @@ -141,10 +141,10 @@ int main() { } if (updateUI) { - std::cout << "\r" << CLR_SCORE << "Score: " << score << CLR_RESET << " | High: " << highscore << " " + std::cout << "\r\033[K" << CLR_SCORE << "Score: " << score << CLR_RESET << " | High: " << highscore << " " << (hardMode ? CLR_HARD "[HARD MODE]" : CLR_NORM "[NORMAL MODE]") << (score > initialHighscore ? " NEW BEST! 🥳" : "") - << " " << std::flush; + << std::flush; updateUI = false; } }