Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@
## 2026-02-13 - Tactile Feedback in CLI
**Learning:** In terminal-based games, users expect immediate visual feedback for their actions. Relying on a periodic "tick" to update the UI creates a laggy feel. Using `poll()` with a dynamic timeout allows the application to remain idle yet wake up instantly to process and render user input.
**Action:** Always trigger a UI refresh immediately after processing user input in CLI applications, and use efficient waiting mechanisms (like `poll`) that can be interrupted by input.

## 2025-05-15 - Improving Game Readiness in CLI
**Learning:** Transitioning directly from instructions to a high-speed game loop can be jarring. A "Press any key to start" prompt followed by a timed countdown (3-2-1-GO) gives the user time to prepare. Furthermore, using `tcflush` after the countdown is critical to ensure that any accidental keypresses during the preparation phase do not unfairly affect the game state.
**Action:** Use animated countdowns and input buffer flushing for time-sensitive CLI interactions.
1 change: 1 addition & 0 deletions .github/workflows/apisec-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ permissions:
jobs:

Trigger_APIsec_scan:
if: ${{ secrets.apisec_username != '' && secrets.apisec_password != '' }}
permissions:
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: C++ CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Build
run: make

- name: Run Test
run: (echo ' '; sleep 5; echo 'q') | ./game | grep "Thanks for playing!"
3 changes: 2 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ env:

jobs:
build:

runs-on: ubuntu-latest
# Only run if there are actually Rust files to build
if: hashFiles('**/*.rs') != ''

steps:
- uses: actions/checkout@v4
Expand Down
26 changes: 18 additions & 8 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
#include <termios.h>
#include <algorithm>

#define CLR_SCORE "\033[1;32m"
#define CLR_HARD "\033[1;31m"
#define CLR_NORM "\033[1;34m"
#define CLR_CTRL "\033[1;33m"
#define CLR_RESET "\033[0m"

int main() {
struct termios oldt, newt;
tcgetattr(STDIN_FILENO, &oldt);
Expand All @@ -14,12 +20,19 @@ int main() {
tcsetattr(STDIN_FILENO, TCSANOW, &newt);

int score = 0; bool hardMode = false; char input;
std::cout << YELLOW << "==========================\n SPEED CLICKER\n==========================\n" << RESET
<< "Controls:\n " << YELLOW << "[h]" << RESET << " Toggle Hard Mode (10x Speed!)\n "
<< YELLOW << "[q]" << RESET << " Quit Game\n " << YELLOW << "[Any key]" << RESET << " Click!\n\n";
std::cout << CLR_CTRL << "==========================\n SPEED CLICKER\n==========================\n" << CLR_RESET
<< "Controls:\n " << CLR_CTRL << "[h]" << CLR_RESET << " Toggle Hard Mode (10x Speed!)\n "
<< CLR_CTRL << "[q]" << CLR_RESET << " Quit Game\n [Any key] Click!\n\n";
<< CLR_CTRL << "[q]" << CLR_RESET << " Quit Game\n " << CLR_CTRL << "[Any key]" << CLR_RESET << " Click!\n\n";

std::cout << CLR_CTRL << "Press any key to start..." << CLR_RESET << std::flush;
read(STDIN_FILENO, &input, 1);

for (int i = 3; i > 0; --i) {
std::cout << "\r" << CLR_SCORE << "Starting in " << i << "..." << CLR_RESET << " " << std::flush;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
std::cout << "\r" << CLR_SCORE << "GO! " << CLR_RESET << std::endl;
tcflush(STDIN_FILENO, TCIFLUSH);

struct pollfd fds[1] = {{STDIN_FILENO, POLLIN, 0}};
auto last_tick = std::chrono::steady_clock::now();
Expand All @@ -46,12 +59,9 @@ int main() {
}

if (updateUI) {
std::cout << GREEN << "Score: " << score << RESET
<< (hardMode ? RED " [FAST] " : BLUE " [NORMAL] ") << RESET
<< " \r" << std::flush;
std::cout << "\r" << CLR_SCORE << "Score: " << score << CLR_RESET << " "
<< (hardMode ? CLR_HARD "[HARD MODE]" : CLR_NORM "[NORMAL MODE]")
<< " " << std::flush;
<< CLR_RESET << " " << std::flush;
updateUI = false;
}
}
Expand Down