Skip to content

Commit 9dfa0b2

Browse files
🎨 Palette: CLI Game UX Enhancements
- Colorized countdown digits (Yellow) and 'GO!' prompt (Green). - Added real-time high-score tracking in the gameplay HUD. - Enabled 'NEW BEST!' achievement and congratulations for first-time players. - Ensured terminal cursor is hidden/shown correctly and HUD clears properly. Co-authored-by: aidasofialily-cmd <247843425+aidasofialily-cmd@users.noreply.github.com>
1 parent f36fbc5 commit 9dfa0b2

2 files changed

Lines changed: 14 additions & 6 deletions

File tree

‎.Jules/palette.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@
2525
## 2026-03-02 - Hiding the Cursor in CLI Games
2626
**Learning:** In terminal applications that require rapid visual updates or where user input doesn't involve typing text, an actively blinking cursor can be a visual distraction. Hiding it during interaction (`\033[?25l`) and rigorously ensuring it is restored (`\033[?25h`) on exit—including signal interrupts—significantly improves the aesthetic and focus.
2727
**Action:** Always hide the cursor for interactive CLI games and explicitly restore it across all exit paths, including async-signal-safe signal handlers.
28+
29+
## 2025-01-24 - Real-time Achievement Feedback in CLI
30+
**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.
31+
**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.

‎src/main.cpp‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int main() {
9494
}
9595

9696
for (int i = 3; i > 0; --i) {
97-
std::cout << "\rStarting in " << i << "... " << std::flush;
97+
std::cout << "\rStarting in " << CLR_CTRL << i << CLR_RESET << "... " << std::flush;
9898
auto start_wait = std::chrono::steady_clock::now();
9999
while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_wait).count() < 1000) {
100100
int elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_wait).count();
@@ -108,7 +108,7 @@ int main() {
108108
}
109109
}
110110
}
111-
std::cout << "\rGO! \n" << std::flush;
111+
std::cout << "\r" << CLR_NORM << "GO! " << CLR_RESET << "\n" << std::flush;
112112
std::this_thread::sleep_for(std::chrono::milliseconds(200));
113113
tcflush(STDIN_FILENO, TCIFLUSH);
114114

@@ -124,22 +124,26 @@ int main() {
124124
if (poll(fds, 1, remaining) > 0) {
125125
if (read(STDIN_FILENO, &input, 1) <= 0 || input == 'q') break;
126126
if (input == 'h') hardMode = !hardMode;
127-
else score++;
127+
else {
128+
score++;
129+
if (score > highscore) highscore = score;
130+
}
128131
updateUI = true;
129132
}
130133

131134
now = std::chrono::steady_clock::now();
132135
elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_tick).count();
133136
if (elapsed >= timeout_ms) {
134137
score++;
138+
if (score > highscore) highscore = score;
135139
last_tick = now;
136140
updateUI = true;
137141
}
138142

139143
if (updateUI) {
140-
std::cout << "\r" << CLR_SCORE << "Score: " << score << CLR_RESET << " "
144+
std::cout << "\r" << CLR_SCORE << "Score: " << score << CLR_RESET << " | High: " << highscore << " "
141145
<< (hardMode ? CLR_HARD "[HARD MODE]" : CLR_NORM "[NORMAL MODE]")
142-
<< (score > initialHighscore && initialHighscore > 0 ? " NEW BEST! 🥳" : "")
146+
<< (score > initialHighscore ? " NEW BEST! 🥳" : "")
143147
<< " " << std::flush;
144148
updateUI = false;
145149
}
@@ -151,7 +155,7 @@ int main() {
151155

152156
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
153157
std::cout << "\n\n" << CLR_SCORE << "Final Score: " << score << CLR_RESET << "\n";
154-
if (score > initialHighscore && initialHighscore > 0) {
158+
if (score > initialHighscore) {
155159
std::cout << "Congratulations! A new personal best!\n";
156160
}
157161
std::cout << "Thanks for playing!\n";

0 commit comments

Comments
 (0)