From 8b00f5f22c4848f817d32d817ac400b6e253600c Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:34:28 +0530 Subject: [PATCH 1/6] Issue #1 Increase Difficulty Resolved! --- snake.h | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/snake.h b/snake.h index ebe1192..66069f4 100644 --- a/snake.h +++ b/snake.h @@ -76,26 +76,35 @@ void game_play(){ snake.push_back(make_pair(0,0)); pair food = make_pair(rand() % 10, rand() % 10); + + int speed = 500; // initial speed in ms + const int min_speed = 100; // max difficulty + const int decrement = 20; // speed decrease per growth + for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ - // send the cursor to the top - cout << "\033[H"; - // check self collision + cout << "\033[H"; // send cursor to top-left + if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); cout << "Game Over" << endl; exit(0); - }else if (head.first == food.first && head.second == food.second) { - // grow snake + } else if (head.first == food.first && head.second == food.second) { + snake.push_back(head); + + // spawn new food food = make_pair(rand() % 10, rand() % 10); - snake.push_back(head); - }else{ - // move snake + + // increase difficulty + speed -= decrement; + if(speed < min_speed) speed = min_speed; + } else { snake.push_back(head); snake.pop_front(); } + render_game(10, snake, food); cout << "length of snake: " << snake.size() << endl; - - sleep_for(500ms); + + sleep_for(chrono::milliseconds(speed)); } } From 8fa6bc2b790aca679b5d7e00b67642ff9c774b89 Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:51:31 +0530 Subject: [PATCH 2/6] Issue #2 Food Should Not Spawn Resolved! --- snake.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/snake.h b/snake.h index 66069f4..6fa6f94 100644 --- a/snake.h +++ b/snake.h @@ -68,6 +68,14 @@ pair get_next_head(pair current, char direction){ } +// helper: generate new food not inside snake +pair generate_food(const deque> &snake, int size=10){ + pair food; + do { + food = make_pair(rand() % size, rand() % size); + } while(find(snake.begin(), snake.end(), food) != snake.end()); + return food; +} void game_play(){ @@ -75,7 +83,7 @@ void game_play(){ deque> snake; snake.push_back(make_pair(0,0)); - pair food = make_pair(rand() % 10, rand() % 10); + pair food = generate_food(snake); // ensures no overlap with snake int speed = 500; // initial speed in ms const int min_speed = 100; // max difficulty @@ -91,8 +99,8 @@ void game_play(){ } else if (head.first == food.first && head.second == food.second) { snake.push_back(head); - // spawn new food - food = make_pair(rand() % 10, rand() % 10); + // spawn new food (not inside snake) + food = generate_food(snake); // increase difficulty speed -= decrement; From 607dd18aae8909aa5dbd3b02f949e823e6098c97 Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:54:15 +0530 Subject: [PATCH 3/6] Issue #3 Maintain and Update Scores Resolved! --- snake.h | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/snake.h b/snake.h index 6fa6f94..41c5a20 100644 --- a/snake.h +++ b/snake.h @@ -15,29 +15,25 @@ char direction='r'; void input_handler(){ - // change terminal settings struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; - // turn off canonical mode and echo newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); 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 direction = keymap[input]; - }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); } -void render_game(int size, deque> &snake, pair food){ +void render_game(int size, deque> &snake, pair food, int score){ for(size_t i=0;i> &snake, pair food){ }else{ cout << "⬜"; } + } + cout << endl; } - cout << endl; -} + cout << "Length of snake: " << snake.size() << " | Score: " << score << endl; } 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') - { + }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); - } + 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; - } -// helper: generate new food not inside snake pair generate_food(const deque> &snake, int size=10){ pair food; do { @@ -83,35 +77,35 @@ void game_play(){ deque> snake; snake.push_back(make_pair(0,0)); - pair food = generate_food(snake); // ensures no overlap with snake + pair food = generate_food(snake); - int speed = 500; // initial speed in ms - const int min_speed = 100; // max difficulty - const int decrement = 20; // speed decrease per growth + int speed = 500; + const int min_speed = 100; + const int decrement = 20; + + int score = 0; // NEW: track score for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ - cout << "\033[H"; // send cursor to top-left + cout << "\033[H"; if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); cout << "Game Over" << endl; + cout << "Final Score: " << score << endl; // show score at end exit(0); } else if (head.first == food.first && head.second == food.second) { snake.push_back(head); - - // spawn new food (not inside snake) food = generate_food(snake); - - // increase difficulty speed -= decrement; if(speed < min_speed) speed = min_speed; + + score += 10; // NEW: +10 per food eaten } else { snake.push_back(head); snake.pop_front(); } - render_game(10, snake, food); - cout << "length of snake: " << snake.size() << endl; + render_game(10, snake, food, score); sleep_for(chrono::milliseconds(speed)); } From 997a5a190650f9e95c58e2557841ccb82580ceee Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:58:30 +0530 Subject: [PATCH 4/6] Issue #4 Spawn Poisonous Food Resolved! --- snake.h | 75 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/snake.h b/snake.h index 41c5a20..23f57b6 100644 --- a/snake.h +++ b/snake.h @@ -15,29 +15,35 @@ char direction='r'; void input_handler(){ + // change terminal settings struct termios oldt, newt; tcgetattr(STDIN_FILENO, &oldt); newt = oldt; + // turn off canonical mode and echo newt.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &newt); 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 direction = keymap[input]; - } 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); } -void render_game(int size, deque> &snake, pair food, int score){ +void render_game(int size, deque> &snake, pair food, pair poison){ for(size_t i=0;i> &snake, pair food, in } cout << endl; } - cout << "Length of snake: " << snake.size() << " | Score: " << score << endl; } 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'){ + }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); - } + 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, int size=10){ - pair food; +// helper: generate new item not inside snake +pair generate_item(const deque> &snake, pair other, int size=10){ + pair pos; do { - food = make_pair(rand() % size, rand() % size); - } while(find(snake.begin(), snake.end(), food) != snake.end()); - return food; + pos = make_pair(rand() % size, rand() % size); + } while(find(snake.begin(), snake.end(), pos) != snake.end() || pos == other); + return pos; } @@ -77,35 +84,53 @@ void game_play(){ deque> snake; snake.push_back(make_pair(0,0)); - pair food = generate_food(snake); + pair food = generate_item(snake, {-1,-1}); // ensures no overlap + pair poison = generate_item(snake, food); // separate from snake & food - int speed = 500; - const int min_speed = 100; - const int decrement = 20; + int score = 0; // track score + int moves = 0; // track moves for poison relocation - int score = 0; // NEW: track score + int speed = 500; // initial speed in ms + const int min_speed = 100; // max difficulty + const int decrement = 20; // speed decrease per growth for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ - cout << "\033[H"; + cout << "\033[H"; // send cursor to top-left if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); - cout << "Game Over" << endl; - cout << "Final Score: " << score << endl; // show score at end + cout << "Game Over! Final Score: " << score << endl; exit(0); - } else if (head.first == food.first && head.second == food.second) { + } else if (head == food) { snake.push_back(head); - food = generate_food(snake); + + // spawn new food + food = generate_item(snake, poison); + + // increase difficulty speed -= decrement; if(speed < min_speed) speed = min_speed; - score += 10; // NEW: +10 per food eaten + // update score + score += 10; + } else if (head == poison) { + system("clear"); + cout << "You ate poison! Game Over. Final Score: " << score << endl; + exit(0); } else { snake.push_back(head); snake.pop_front(); } - render_game(10, snake, food, score); + // relocate poison every 5 moves + moves++; + if (moves % 5 == 0) { + poison = generate_item(snake, food); + } + + render_game(10, snake, food, poison); + cout << "length of snake: " << snake.size() << endl; + cout << "score: " << score << endl; sleep_for(chrono::milliseconds(speed)); } From ff3265d4981d927c4dcf7ec04fcecaca289e9216 Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:02:18 +0530 Subject: [PATCH 5/6] Issue #5 Play-Pause Functionality Resolved! --- snake.h | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/snake.h b/snake.h index 23f57b6..6e1aa3e 100644 --- a/snake.h +++ b/snake.h @@ -11,8 +11,9 @@ using namespace std; using std::chrono::system_clock; using namespace std::this_thread; -char direction='r'; +char direction = 'r'; +bool paused = false; // NEW: track pause state void input_handler(){ // change terminal settings @@ -22,21 +23,23 @@ void input_handler(){ // turn off canonical mode and 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'}}; + while (true) { char input = getchar(); + if (keymap.find(input) != keymap.end()) { - // This now correctly modifies the single, shared 'direction' variable - direction = keymap[input]; - }else if (input == 'q'){ + if (!paused) direction = keymap[input]; // movement only when not paused + } else if (input == 'q') { exit(0); + } else if (input == 'p') { + paused = !paused; // toggle pause/resume } - // You could add an exit condition here, e.g., if (input == 'q') break; } tcsetattr(STDIN_FILENO, TCSANOW, &oldt); } - void render_game(int size, deque> &snake, pair food, pair poison){ for(size_t i=0;i 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') - { + }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); - } + 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; } @@ -78,7 +80,6 @@ pair generate_item(const deque> &snake, pair oth return pos; } - void game_play(){ system("clear"); deque> snake; @@ -97,6 +98,15 @@ void game_play(){ for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ cout << "\033[H"; // send cursor to top-left + if (paused) { + render_game(10, snake, food, poison); + cout << "length of snake: " << snake.size() << endl; + cout << "score: " << score << endl; + cout << "[PAUSED] Press 'p' to resume" << endl; + sleep_for(chrono::milliseconds(200)); // small delay to avoid CPU hogging + continue; // skip movement while paused + } + if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); cout << "Game Over! Final Score: " << score << endl; From 9746ea3daa0f7cd5824184c8e04bab4bf9e5f137 Mon Sep 17 00:00:00 2001 From: yashvixshah <156948769+yashvixshah@users.noreply.github.com> Date: Thu, 18 Sep 2025 17:36:52 +0530 Subject: [PATCH 6/6] Issue #6 Keep Track of Top 10 High Scores Resolved! --- snake.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/snake.h b/snake.h index 6e1aa3e..eacf289 100644 --- a/snake.h +++ b/snake.h @@ -13,7 +13,8 @@ using std::chrono::system_clock; using namespace std::this_thread; char direction = 'r'; -bool paused = false; // NEW: track pause state +bool paused = false; // track pause state +vector high_scores; // NEW: top 10 scores void input_handler(){ // change terminal settings @@ -80,6 +81,18 @@ pair generate_item(const deque> &snake, pair oth return pos; } +// NEW: update and print top 10 scores +void update_high_scores(int score) { + high_scores.push_back(score); + sort(high_scores.begin(), high_scores.end(), greater()); // sort descending + if (high_scores.size() > 10) high_scores.pop_back(); // keep only top 10 + + cout << "\n=== High Scores ===" << endl; + for (size_t i = 0; i < high_scores.size(); i++) { + cout << i+1 << ". " << high_scores[i] << endl; + } +} + void game_play(){ system("clear"); deque> snake; @@ -103,13 +116,14 @@ void game_play(){ cout << "length of snake: " << snake.size() << endl; cout << "score: " << score << endl; cout << "[PAUSED] Press 'p' to resume" << endl; - sleep_for(chrono::milliseconds(200)); // small delay to avoid CPU hogging - continue; // skip movement while paused + sleep_for(chrono::milliseconds(200)); + continue; } if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); cout << "Game Over! Final Score: " << score << endl; + update_high_scores(score); exit(0); } else if (head == food) { snake.push_back(head); @@ -126,6 +140,7 @@ void game_play(){ } else if (head == poison) { system("clear"); cout << "You ate poison! Game Over. Final Score: " << score << endl; + update_high_scores(score); exit(0); } else { snake.push_back(head);