#include <iostream>
#include <vector>
#include <conio.h> // 用于_getch()
#include <windows.h> // 用于Sleep()和系统函数
#include <ctime> // 用于随机数种子
using namespace std;
void cls(){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coordScreen = { 0, 0 }; // home for the cursor
SetConsoleCursorPosition( hConsole, coordScreen );
}
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
vector<pair<int, int>> snake; // 蛇的身体坐标
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
void Setup() {
gameOver = false;
dir = STOP;
x = width / 2;
y = height / 2;
snake.push_back({x, y});
// 随机生成水果位置
srand(static_cast<unsigned int>(time(0)));
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
}
void Draw() {
system("cls"); // 清屏
// 绘制上边界
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (j == 0)
cout << "#"; // 左边界
// 绘制蛇头
if (i == y && j == x)
cout << "O";
// 绘制水果
else if (i == fruitY && j == fruitX)
cout << "F";
else {
bool isBody = false;
// 绘制蛇身
for (auto segment : snake) {
if (segment.first == j && segment.second == i) {
cout << "o";
isBody = true;
break;
}
}
if (!isBody)
cout << " ";
}
if (j == width - 1)
cout << "#"; // 右边界
}
cout << endl;
}
// 绘制下边界
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
cout << "Score: " << score << endl;
}
void Input() {
if (_kbhit()) {
switch (_getch()) {
case 'a':
dir = LEFT;
break;
case 'd':
dir = RIGHT;
break;
case 'w':
dir = UP;
break;
case 's':
dir = DOWN;
break;
case 'x':
gameOver = true;
break;
}
}
}
void Logic() {
// 保存蛇尾位置
int prevX = snake.back().first;
int prevY = snake.back().second;
// 移动蛇身
for (size_t i = snake.size() - 1; i > 0; i--) {
snake[i].first = snake[i-1].first;
snake[i].second = snake[i-1].second;
}
// 移动蛇头
switch (dir) {
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
case UP:
y--;
break;
case DOWN:
y++;
break;
default:
break;
}
// 更新蛇头位置
if (!snake.empty()) {
snake[0].first = x;
snake[0].second = y;
}
// 检查是否吃到水果
if (x == fruitX && y == fruitY) {
score += 10;
// 添加新的蛇身段
snake.push_back({prevX, prevY});
// 生成新的水果
fruitX = rand() % width;
fruitY = rand() % height;
}
// 检查撞墙
if (x >= width || x < 0 || y >= height || y < 0)
gameOver = true;
// 检查撞到自己
for (size_t i = 1; i < snake.size(); i++) {
if (snake[i].first == x && snake[i].second == y)
gameOver = true;
}
}
int main() {
Setup();
while (!gameOver) {
Draw();
Input();
Logic();
Sleep(100); // 控制游戏速度
}
cout << "Game Over! Final Score: " << score << endl;
return 0;
}
这是完善后的代码:
#include <iostream>
#include <vector>
#include <conio.h> // 用于_getch()
#include <windows.h> // 用于Sleep()和系统函数
#include <ctime> // 用于随机数种子
using namespace std;
// 隐藏光标函数
void HideCursor() {
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(handle, &cursorInfo);
cursorInfo.bVisible = false; // 隐藏光标
SetConsoleCursorInfo(handle, &cursorInfo);
}
void cls() {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
COORD coordScreen = { 0, 0 }; // home for the cursor
SetConsoleCursorPosition(hConsole, coordScreen);
}
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY, score;
vector<pair<int, int>> snake; // 蛇的身体坐标
enum eDirection { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirection dir;
void Setup() {
gameOver = false;
dir = STOP;
x = width / 2;
y = height / 2;
snake.push_back({x, y});
// 随机生成水果位置
srand(static_cast<unsigned int>(time(0)));
fruitX = rand() % width;
fruitY = rand() % height;
score = 0;
HideCursor(); // 隐藏光标
}
void Draw() {
cls(); // 使用自定义清屏函数
// 绘制上边界
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (j == 0)
cout << "#"; // 左边界
// 绘制蛇头
if (i == y && j == x)
cout << "O";
// 绘制水果
else if (i == fruitY && j == fruitX)
cout << "F";
else {
bool isBody = false;
// 绘制蛇身
for (auto segment : snake) {
if (segment.first == j && segment.second == i) {
cout << "o";
isBody = true;
break;
}
}
if (!isBody)
cout << " ";
}
if (j == width - 1)
cout << "#"; // 右边界
}
cout << endl;
}
// 绘制下边界
for (int i = 0; i < width + 2; i++)
cout << "#";
cout << endl;
cout << "Score: " << score << endl;
}
void Input() {
if (_kbhit()) {
switch (_getch()) {
case 'a':
dir = LEFT;
break;
case 'd':
dir = RIGHT;
break;
case 'w':
dir = UP;
break;
case 's':
dir = DOWN;
break;
case 'x':
gameOver = true;
break;
}
}
}
void Logic() {
// 保存蛇尾位置
int prevX = snake.back().first;
int prevY = snake.back().second;
// 移动蛇身
for (size_t i = snake.size() - 1; i > 0; i--) {
snake[i].first = snake[i-1].first;
snake[i].second = snake[i-1].second;
}
// 移动蛇头
switch (dir) {
case LEFT:
x--;
break;
case RIGHT:
x++;
break;
case UP:
y--;
break;
case DOWN:
y++;
break;
default:
break;
}
// 更新蛇头位置
if (!snake.empty()) {
snake[0].first = x;
snake[0].second = y;
}
// 检查是否吃到水果
if (x == fruitX && y == fruitY) {
score += 10;
// 添加新的蛇身段
snake.push_back({prevX, prevY});
// 生成新的水果
fruitX = rand() % width;
fruitY = rand() % height;
}
// 检查撞墙
if (x >= width || x < 0 || y >= height || y < 0)
gameOver = true;
// 检查撞到自己
for (size_t i = 1; i < snake.size(); i++) {
if (snake[i].first == x && snake[i].second == y)
gameOver = true;
}
}
int main() {
Setup();
while (!gameOver) {
Draw();
Input();
Logic();
Sleep(100); // 控制游戏速度
}
// 游戏结束时恢复光标显示
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(handle, &cursorInfo);
cursorInfo.bVisible = true;
SetConsoleCursorInfo(handle, &cursorInfo);
cout << "Game Over! Final Score: " << score << endl;
return 0;
}