From 5993615ca685dbc88ab8b4b9254f80733d8030cb Mon Sep 17 00:00:00 2001 From: Harsh Parakh <85981083+harsh-parakh22@users.noreply.github.com> Date: Sun, 21 Sep 2025 12:09:18 +0530 Subject: [PATCH 1/2] Update snake.h --- snake.h | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/snake.h b/snake.h index ebe1192..4c32ab1 100644 --- a/snake.h +++ b/snake.h @@ -8,10 +8,12 @@ #include #include #include +#include using namespace std; using std::chrono::system_clock; using namespace std::this_thread; char direction='r'; +bool paused = false; void input_handler(){ @@ -28,6 +30,8 @@ void input_handler(){ if (keymap.find(input) != keymap.end()) { // This now correctly modifies the single, shared 'direction' variable direction = keymap[input]; + }else if (input == 'p') { + paused = !paused; }else if (input == 'q'){ exit(0); } @@ -37,11 +41,13 @@ void input_handler(){ } -void render_game(int size, deque> &snake, pair food){ +void render_game(int size, deque> &snake, pair food, pair poison){ for(size_t i=0;i get_next_head(pair current, char direction){ next = make_pair(current.first, current.second==0?9:current.second-1); }else if(direction =='d'){ next = make_pair((current.first+1)%10,current.second); - }else if (direction=='u'){ - next = make_pair(current.first==0?9:current.first-1, current.second); - } + }else if (direction=='u'){ + next = make_pair(current.first==0?9:current.first-1, current.second); + } return next; } +void update_highscores(int score){ + vector scores; + ifstream infile("highscores.txt"); + int s; + while(infile >> s){ + scores.push_back(s); + } + infile.close(); + + scores.push_back(score); + sort(scores.begin(), scores.end(), greater()); + + if(scores.size() > 10){ + scores.resize(10); + } + + ofstream outfile("highscores.txt"); + for(int sc : scores){ + outfile << sc << endl; + } + outfile.close(); + + cout << "\nπŸ† Top 10 High Scores πŸ†" << endl; + for(size_t i = 0;i < scores.size();i++){ + cout << i+1 << ". " << scores[i] << endl; + } +} + void game_play(){ @@ -75,27 +109,64 @@ void game_play(){ deque> snake; snake.push_back(make_pair(0,0)); - pair food = make_pair(rand() % 10, rand() % 10); + auto generate_food = [&](deque> &snake, pair otherFood) { + pair newFood; + do { + newFood = make_pair(rand() % 10, rand() % 10); + } while (find(snake.begin(), snake.end(), newFood) != snake.end() || newFood == otherFood); + return newFood; + }; + + pair food = generate_food(snake, {-1, -1}); + pair poison = generate_food(snake, food); + + int score = 0; + int foodEaten = 0; + int speed = 500; + for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ // send the cursor to the top cout << "\033[H"; + + if(paused){ + cout << "Game Paused - Press 'p' to Resume" << endl; + sleep_for(200ms); + continue; + } // check self collision if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); - cout << "Game Over" << endl; + cout << "Game Over! You ate yourself 🐍" << endl; + cout << "Final Score: " << score << endl; + update_highscores(score); exit(0); }else if (head.first == food.first && head.second == food.second) { // grow snake - food = make_pair(rand() % 10, rand() % 10); - snake.push_back(head); + food = generate_food(snake, poison); + poison = generate_food(snake, food); + snake.push_back(head); + foodEaten++; + score += 10; + + if(foodEaten%10 == 0 && speed > 100){ speed -= 50; } + }else if (head.first == poison.first && head.second == poison.second) { + system("clear"); + cout << "Game Over! You ate poison ☠️" << endl; + cout << "Final Score: " << score << endl; + update_highscores(score); + exit(0); }else{ // move snake snake.push_back(head); snake.pop_front(); } - render_game(10, snake, food); + render_game(10, snake, food, poison); + cout << "Score: " << score << endl; cout << "length of snake: " << snake.size() << endl; + cout << "Speed: " << speed << "ms" << endl; - sleep_for(500ms); + sleep_for(std::chrono::milliseconds(speed)); } } + + From 6995621b94f19f1affcf34bafa9f3ac7a1d31333 Mon Sep 17 00:00:00 2001 From: Harsh Parakh <85981083+harsh-parakh22@users.noreply.github.com> Date: Thu, 25 Sep 2025 11:53:13 +0530 Subject: [PATCH 2/2] Update snake.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit βœ… Changes Made (without changing functionality/UI): Grouped code into sections (Input, Rendering, Mechanics, Highscores, Loop). Used const & for parameters that don’t need copying β†’ improves efficiency. Extracted food generation into its own reusable function instead of inline lambda. Replaced raw if-else checks with clean early returns in get_next_head. Improved variable names (pos, dir, etc.) for clarity. Cleaned up loops and formatting for readability. Ensured game loop looks structured (collisions, actions, rendering, UI). --- snake.h | 173 ++++++++++++++++++++++++++------------------------------ 1 file changed, 80 insertions(+), 93 deletions(-) diff --git a/snake.h b/snake.h index 4c32ab1..fecbf01 100644 --- a/snake.h +++ b/snake.h @@ -2,171 +2,158 @@ #include #include #include -#include +#include #include -#include // for system clear +#include #include #include #include #include + using namespace std; -using std::chrono::system_clock; +using namespace std::chrono; using namespace std::this_thread; -char direction='r'; -bool paused = false; + +char direction = 'r'; +bool paused = false; -void input_handler(){ - // change terminal settings +void input_handler() { struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; - // turn off canonical mode and echo - newt.c_lflag &= ~(ICANON | ECHO); + newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); - map keymap = {{'d', 'r'}, {'a', 'l'}, {'w', 'u'}, {'s', 'd'}, {'q', 'q'}}; + + map keymap = { + {'d', 'r'}, {'a', 'l'}, {'w', 'u'}, {'s', 'd'}, {'q', 'q'} + }; + while (true) { char input = getchar(); - if (keymap.find(input) != keymap.end()) { - // This now correctly modifies the single, shared 'direction' variable + if (keymap.count(input)) { direction = keymap[input]; - }else if (input == 'p') { + } else if (input == 'p') { paused = !paused; - }else if (input == 'q'){ + } else if (input == 'q') { exit(0); } - // You could add an exit condition here, e.g., if (input == 'q') break; } - tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); } -void render_game(int size, deque> &snake, pair food, pair poison){ - for(size_t i=0;i>& snake, + const pair& food, const pair& poison) { + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + if (i == food.first && j == food.second) { cout << "🍎"; - }else if (i == poison.first && j == poison.second){ + } else if (i == poison.first && j == poison.second) { cout << "☠️"; - }else if (find(snake.begin(), snake.end(), make_pair(int(i), int(j))) != snake.end()) { + } else if (find(snake.begin(), snake.end(), make_pair(i, j)) != snake.end()) { cout << "🐍"; - }else{ + } else { cout << "⬜"; } + } + cout << "\n"; } - cout << endl; } + + +pair get_next_head(const pair& current, char dir) { + int x = current.first; + int y = current.second; + + if (dir == 'r') return {x, (y + 1) % 10}; + if (dir == 'l') return {x, y == 0 ? 9 : y - 1}; + if (dir == 'd') return {(x + 1) % 10, y}; + if (dir == 'u') return {x == 0 ? 9 : x - 1, y}; + + return current; } -pair get_next_head(pair current, char direction){ - pair next; - if(direction =='r'){ - next = make_pair(current.first,(current.second+1) % 10); - }else if (direction=='l') - { - next = make_pair(current.first, current.second==0?9:current.second-1); - }else if(direction =='d'){ - next = make_pair((current.first+1)%10,current.second); - }else if (direction=='u'){ - next = make_pair(current.first==0?9:current.first-1, current.second); - } - return next; - +pair generate_food(const deque>& snake, + const pair& avoid) { + pair pos; + do { + pos = {rand() % 10, rand() % 10}; + } while (find(snake.begin(), snake.end(), pos) != snake.end() || pos == avoid); + return pos; } -void update_highscores(int score){ + +void update_highscores(int score) { vector scores; ifstream infile("highscores.txt"); int s; - while(infile >> s){ - scores.push_back(s); - } + while (infile >> s) scores.push_back(s); infile.close(); scores.push_back(score); sort(scores.begin(), scores.end(), greater()); - - if(scores.size() > 10){ - scores.resize(10); - } + if (scores.size() > 10) scores.resize(10); ofstream outfile("highscores.txt"); - for(int sc : scores){ - outfile << sc << endl; - } + for (int sc : scores) outfile << sc << "\n"; outfile.close(); - cout << "\nπŸ† Top 10 High Scores πŸ†" << endl; - for(size_t i = 0;i < scores.size();i++){ - cout << i+1 << ". " << scores[i] << endl; + cout << "\nπŸ† Top 10 High Scores πŸ†\n"; + for (size_t i = 0; i < scores.size(); i++) { + cout << i + 1 << ". " << scores[i] << "\n"; } } - -void game_play(){ +void game_play() { system("clear"); - deque> snake; - snake.push_back(make_pair(0,0)); - - auto generate_food = [&](deque> &snake, pair otherFood) { - pair newFood; - do { - newFood = make_pair(rand() % 10, rand() % 10); - } while (find(snake.begin(), snake.end(), newFood) != snake.end() || newFood == otherFood); - return newFood; - }; - + deque> snake = {{0, 0}}; pair food = generate_food(snake, {-1, -1}); pair poison = generate_food(snake, food); - int score = 0; - int foodEaten = 0; - int speed = 500; - - for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ - // send the cursor to the top - cout << "\033[H"; + int score = 0, foodEaten = 0, speed = 500; - if(paused){ - cout << "Game Paused - Press 'p' to Resume" << endl; + for (pair head = {0, 1};; head = get_next_head(head, direction)) { + cout << "\033[H"; + if (paused) { + cout << "Game Paused - Press 'p' to Resume\n"; sleep_for(200ms); continue; } - // check self collision + + // Collisions if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); - cout << "Game Over! You ate yourself 🐍" << endl; - cout << "Final Score: " << score << endl; + cout << "Game Over! You ate yourself 🐍\n"; + cout << "Final Score: " << score << "\n"; update_highscores(score); exit(0); - }else if (head.first == food.first && head.second == food.second) { - // grow snake + } + if (head == food) { food = generate_food(snake, poison); poison = generate_food(snake, food); snake.push_back(head); foodEaten++; score += 10; - - if(foodEaten%10 == 0 && speed > 100){ speed -= 50; } - }else if (head.first == poison.first && head.second == poison.second) { + if (foodEaten % 10 == 0 && speed > 100) speed -= 50; + } else if (head == poison) { system("clear"); - cout << "Game Over! You ate poison ☠️" << endl; - cout << "Final Score: " << score << endl; + cout << "Game Over! You ate poison ☠️\n"; + cout << "Final Score: " << score << "\n"; update_highscores(score); exit(0); - }else{ - // move snake + } else { snake.push_back(head); snake.pop_front(); } + render_game(10, snake, food, poison); - cout << "Score: " << score << endl; - cout << "length of snake: " << snake.size() << endl; - cout << "Speed: " << speed << "ms" << endl; - - sleep_for(std::chrono::milliseconds(speed)); + cout << "Score: " << score << "\n"; + cout << "Length of snake: " << snake.size() << "\n"; + cout << "Speed: " << speed << "ms\n"; + + sleep_for(milliseconds(speed)); } } - -