diff --git a/main.cpp b/main.cpp index ef65093..5601a52 100644 --- a/main.cpp +++ b/main.cpp @@ -1,9 +1,15 @@ #include "snake.h" -int main(int argc, char *argv[]) { +int main() { + srand(time(0)); // seed random generator + + select_difficulty(); + thread input_thread(input_handler); - thread game_thread(game_play); + thread game_thread(game_play); + input_thread.join(); game_thread.join(); -return 0; -} \ No newline at end of file + + return 0; +} diff --git a/snake b/snake new file mode 100755 index 0000000..8c6e675 Binary files /dev/null and b/snake differ diff --git a/snake.h b/snake.h index ebe1192..e3242e1 100644 --- a/snake.h +++ b/snake.h @@ -9,93 +9,134 @@ #include #include using namespace std; -using std::chrono::system_clock; using namespace std::this_thread; -char direction='r'; +char direction = 'r'; +int game_speed = 500; // default in ms (easy) +int score = 0; // score tracker -void input_handler(){ - // change terminal settings +// --- Input Handler --- +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'}}; 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){ - for(size_t i=0;i> &snake, pair food, pair poison) { + for (size_t i = 0; i < size; i++) { + for (size_t j = 0; j < size; j++) { + if (i == food.first && j == food.second) { + cout << "🍎"; // normal food + } else if (i == poison.first && j == poison.second) { + cout << "🍄"; // poisonous food + } else if (find(snake.begin(), snake.end(), make_pair(int(i), int(j))) != snake.end()) { cout << "🐍"; - }else{ + } else { cout << "⬜"; } + } + cout << endl; } - cout << 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') - { - 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); - } +// --- Snake Movement --- +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; - } +// --- Food Generator --- +pair generate_item(deque> &snake, pair other = {-1, -1}) { + pair f; + do { + f = make_pair(rand() % 10, rand() % 10); + } while (find(snake.begin(), snake.end(), f) != snake.end() || f == other); + return f; +} - -void game_play(){ +// --- Game Play --- +void game_play() { system("clear"); deque> snake; - snake.push_back(make_pair(0,0)); + 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 - cout << "\033[H"; - // check self collision + pair food = generate_item(snake); + pair poison = generate_item(snake, food); + + for (pair head = make_pair(0, 1);; head = get_next_head(head, direction)) { + cout << "\033[H"; // move cursor to top if (find(snake.begin(), snake.end(), head) != snake.end()) { system("clear"); - cout << "Game Over" << endl; + cout << "Game Over! You hit yourself!\n"; + cout << "Final Score: " << score << 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 + } else if (head == food) { + // Eat normal food + snake.push_back(head); + score += 10; + if (game_speed > 80) game_speed -= 20; + + // generate both food and poison again, ensuring they never overlap + food = generate_item(snake); + poison = generate_item(snake, food); + + } else if (head == poison) { + // Eat poisonous food → game ends + system("clear"); + cout << "☠️ Game Over! You ate poisonous food!\n"; + cout << "Final Score: " << score << endl; + exit(0); + } else { + // Normal move snake.push_back(head); snake.pop_front(); } - render_game(10, snake, food); - cout << "length of snake: " << snake.size() << endl; - - sleep_for(500ms); + + render_game(10, snake, food, poison); + cout << "Score: " << score << endl; + cout << "Length: " << snake.size() << endl; + cout << "Speed: " << game_speed << "ms" << endl; + sleep_for(chrono::milliseconds(game_speed)); + } +} + +// --- Difficulty Selection --- +void select_difficulty() { + cout << "Choose Difficulty:\n"; + cout << "1. Easy (500ms)\n"; + cout << "2. Medium (300ms)\n"; + cout << "3. Hard (150ms)\n"; + cout << "Enter choice: "; + int choice; + cin >> choice; + + switch (choice) { + case 1: game_speed = 500; break; + case 2: game_speed = 300; break; + case 3: game_speed = 150; break; + default: game_speed = 500; break; } }