1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
#include <iostream> #include <conio.h> #include <windows.h> #include <deque> using namespace std; const int WIDTH = 20; const int HEIGHT = 17; const char SNAKE_HEAD = '@'; const char SNAKE_BODY = 'o'; const char FOOD = '*'; const char EMPTY = ' '; enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN }; class SnakeGame { private: bool gameOver; Direction dir; int score; pair<int, int> food; deque<pair<int, int>> snake; void setup() { gameOver = false; dir = STOP; score = 0; snake.clear(); snake.push_front({WIDTH / 2, HEIGHT / 2}); generateFood(); } void generateFood() { food = {rand() % WIDTH, rand() % HEIGHT}; } void draw() { system("cls"); // Clear the screen for (int y = 0; y < HEIGHT; ++y) { for (int x = 0; x < WIDTH; ++x) { if (x == 0 || x == WIDTH - 1 || y == 0 || y == HEIGHT - 1) { cout << '#'; // Draw walls } else if (x == food.first && y == food.second) { cout << FOOD; // Draw food } else { bool printed = false; for (auto segment : snake) { if (segment.first == x && segment.second == y) { cout << (segment == snake.front() ? SNAKE_HEAD : SNAKE_BODY); printed = true; break; } } if (!printed) { cout << EMPTY; // Draw empty space } } } cout << endl; } cout << "Score: " << score << endl; } void input() { if (_kbhit()) { switch (_getch()) { case 'a': if (dir != RIGHT) dir = LEFT; break; case 'd': if (dir != LEFT) dir = RIGHT; break; case 'w': if (dir != DOWN) dir = UP; break; case 's': if (dir != UP) dir = DOWN; break; case 'x': gameOver = true; break; } } } void logic() { pair<int, int> head = snake.front(); switch (dir) { case LEFT: head.first--; break; case RIGHT: head.first++; break; case UP: head.second--; break; case DOWN: head.second++; break; } if (head.first < 1 || head.first >= WIDTH - 1 || head.second < 1 || head.second >= HEIGHT - 1) { gameOver = true; // Collision with wall } for (auto segment : snake) { if (segment == head) { gameOver = true; // Collision with itself } } if (head == food) { score += 10; snake.push_front(food); generateFood(); } else { snake.push_front(head); snake.pop_back(); } } public: SnakeGame() { setup(); } void run() { while (!gameOver) { draw(); input(); logic(); Sleep(100); // Slow down the loop } cout << "Game Over!" << endl; } }; int main() { SnakeGame game; game.run(); return 0; } |
Explanation
- Class Definition:
SnakeGame
manages the game state and logic.- Private members include game status (
gameOver
), direction of movement (dir
), score (score
), food location (food
), and the snake (snake
).
- Initialization (
setup()
):- Initializes the game state, sets the snake’s initial position, and generates the first piece of food.
- Drawing (
draw()
):- Clears the console and prints the game board.
- Draws walls, snake, and food.
- Input Handling (
input()
):- Checks for user input and updates the direction of the snake accordingly.
- Game Logic (
logic()
):- Updates the position of the snake based on direction.
- Checks for collisions with walls or itself.
- Handles food consumption and growth of the snake.
- Game Loop (
run()
):- Continuously updates the game by drawing, processing input, and applying game logic.
- Ends when the game is over.
- Main Function:
- Creates an instance of
SnakeGame
and starts the game loop.
- Creates an instance of