diff --git a/snake.h b/snake.h index ebe1192..0ff25ea 100644 --- a/snake.h +++ b/snake.h @@ -1,101 +1,155 @@ +#ifndef SNAKE_H +#define SNAKE_H + #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::this_thread; -char direction='r'; +using std::chrono::system_clock; +char direction = 'r'; +bool paused = false; +int score = 0; +vector highScores; -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); 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]; + } else if (input == 'p') { + paused = !paused; // Toggle pause + } 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){ - for(size_t i=0;i> &snake, pair food, 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 (find(snake.begin(), snake.end(), make_pair(int(i), int(j))) != snake.end()) { + } else if (i == poison.first && j == poison.second) { + cout << "☠️"; + } else if (find(snake.begin(), snake.end(), make_pair(i, j)) != snake.end()) { cout << "🐍"; - }else{ + } else { cout << "⬜"; } + } + cout << endl; } - cout << endl; -} + cout << "Score: " << score << endl; + cout << "Length of snake: " << snake.size() << endl; + cout << "[p] Pause/Resume | [q] Quit" << endl; } -pair get_next_head(pair current, char direction){ + +pair get_next_head(pair current, char direction, int size) { 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); - } + if (direction == 'r') { + next = make_pair(current.first, (current.second + 1) % size); + } else if (direction == 'l') { + next = make_pair(current.first, current.second == 0 ? size - 1 : current.second - 1); + } else if (direction == 'd') { + next = make_pair((current.first + 1) % size, current.second); + } else if (direction == 'u') { + next = make_pair(current.first == 0 ? size - 1 : current.first - 1, current.second); + } return next; - } +pair spawn_food(int size, deque> &snake) { + pair food; + do { + food = make_pair(rand() % size, rand() % size); + } while (find(snake.begin(), snake.end(), food) != snake.end()); + return food; +} + -void game_play(){ - system("clear"); +void game_play() { + srand(time(0)); + int size = 10; + int speed = 500; // in ms deque> snake; snake.push_back(make_pair(0,0)); - pair food = make_pair(rand() % 10, rand() % 10); - for(pair head=make_pair(0,1);; head = get_next_head(head, direction)){ - // send the cursor to the top + pair food = spawn_food(size, snake); + pair poison = spawn_food(size, snake); + + for (pair head = make_pair(0,1); ; head = get_next_head(head, direction, size)) { cout << "\033[H"; - // check self collision + + if (paused) { + cout << "⏸️ Game Paused ⏸️" << endl; + sleep_for(300ms); + continue; + } + + // Collision with self if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); - cout << "Game Over" << endl; + cout << "πŸ’€ Game Over πŸ’€" << endl; + cout << "Final Score: " << score << endl; + + highScores.push_back(score); + sort(highScores.rbegin(), highScores.rend()); + if (highScores.size() > 10) highScores.resize(10); + + cout << "\nπŸ† Top 10 High Scores πŸ†\n"; + for (size_t i = 0; i < highScores.size(); i++) { + cout << i+1 << ". " << highScores[i] << endl; + } 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); - }else{ - // move snake + } + // Eating food + else if (head.first == food.first && head.second == food.second) { + score += 10; + food = spawn_food(size, snake); + poison = spawn_food(size, snake); + snake.push_back(head); + + if (speed > 100) speed -= 20; // Increase difficulty + } + // Eating poison + else if (head.first == poison.first && head.second == poison.second) { + system("clear"); + cout << "☠️ Game Over (Ate Poison) ☠️" << endl; + cout << "Final Score: " << score << endl; + exit(0); + } + else { snake.push_back(head); snake.pop_front(); } - render_game(10, snake, food); - cout << "length of snake: " << snake.size() << endl; - - sleep_for(500ms); + + render_game(size, snake, food, poison); + sleep_for(std::chrono::milliseconds(speed)); } } + +#endif