Snake Game
一个使用C++实现的控制台简易贪吃蛇小游戏,刚开始做项目训练。
使用方式
使用W,S,A,D来实现上下左右移动,Q退出,P暂停。
注意事项
- 要C++ 11或以上的版本
- 作者是在读大学生,如果你对我的代码有任何问题或优化方法,请务必告知❤️❤️
代码
cpp
#include <iostream>
#include <random>
#include <vector>
#include <Windows.h>
#include <conio.h>
#include <fstream>
using namespace std;
const int WIDTH = 22;
const int LENGTH = 32;
// 蛇头的朝向
enum Direction {
UP,
DOWN,
LEFT,
RIGHT
};
class GameMap {
public:
char gameMap[WIDTH][LENGTH]; // 游戏地图
int food_x, food_y; // 食物的坐标
int Score; // 得分
int Round; // 轮次
int AllTimeHigh_score; // 历史最高得分
public:
GameMap()
{
for (int j = 0; j < LENGTH; j++) gameMap[0][j] = gameMap[WIDTH - 1][j] = '-'; // 上下边界
for (int i = 1; i < WIDTH-1; i++) gameMap[i][0] = gameMap[i][LENGTH - 1] = '|'; // 左右边界
for (int i = 1; i < WIDTH - 1; i++) for (int j = 1; j < LENGTH - 1; j++) gameMap[i][j] = ' '; // 中间清空
Score = Round = AllTimeHigh_score = 0; // 初始化,Round用0是因为程序员的第一是0
generate_food();
}
void generate_food()
{
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dist_x(1, WIDTH - 2); food_x = dist_x(gen);
uniform_int_distribution<> dist_y(1, LENGTH - 2); food_y = dist_y(gen);
gameMap[food_x][food_y] = '$';
}
void show()
{
system("cls"); // 清屏刷新
cout << "All-time high score: " << loadHighScore() << ", Round: " << Round << ", Score: " << Score << endl;
for (int i = 0; i < WIDTH; i++)
{
for (int j = 0; j < LENGTH; j++) cout << gameMap[i][j];
cout << endl;
}
}
int loadHighScore()
{
ifstream ifs("AllTimeHighScore.txt", ios::in);
int hs = 0;
if (ifs >> hs) return hs;
return 0;
}
void saveHighScore(int hs)
{
ofstream ofs("AllTimeHighScore.txt", ios::out);
ofs << hs;
}
};
class Snake : public GameMap {
private:
vector<pair<int, int>> mySnake; // 蛇的坐标
int head_x, head_y; // 蛇头
Direction Dir; // 蛇头朝向
public:
Snake()
{
head_x = 10, head_y = 15;
mySnake.push_back(make_pair(head_x, head_y));
mySnake.push_back(make_pair(head_x, head_y-1)); // 初始时设置蛇的长度为2
gameMap[head_x][head_y] = '0';
gameMap[head_x][head_y] = 'o';
Dir = RIGHT;
}
bool control_direction()
{
if (_kbhit())
{
char key = _getch();
switch (key)
{
case 'w': if(Dir != DOWN) Dir = UP; break;
case 's': if(Dir != UP) Dir = DOWN; break;
case 'a': if(Dir != RIGHT) Dir = LEFT; break;
case 'd': if(Dir != LEFT) Dir = RIGHT; break;
case 'p': system("pause"); break;
case 'q': return false;
}
}
return true;
}
bool move()
{
// 更新头部
switch (Dir)
{
case UP: head_x--; break;
case DOWN: head_x++; break;
case LEFT: head_y--; break;
case RIGHT: head_y++; break;
}
mySnake.insert(mySnake.begin(), make_pair(head_x, head_y));
// 撞墙检测
if (head_x <= 0 || head_x >= WIDTH-1 || head_y <= 0 || head_y >= LENGTH-1)
{
cout << "You hit the wall!" << endl;
return false;
}
// 撞到自己检测
for (int i = 1; i < (int)mySnake.size(); i++)
if (mySnake[i].first == head_x && mySnake[i].second == head_y)
{
cout << "You are eating yourself!" << endl;
return false;
}
// 吃到食物了
if (head_x == food_x && head_y == food_y)
{
if (Round < 3) Score += 5;
else if (Round < 7) Score += 10;
else if (Round < 10) Score += 15;
else if (Round < 30) Score += 20;
else if (Round < 50) Score += 25;
else if (Round < 100) Score += 30;
else Score += 50;
generate_food();
Round++;
}
// 没吃到,要删除蛇尾
else
{
gameMap[mySnake.back().first][mySnake.back().second] = ' ';
mySnake.pop_back();
}
gameMap[head_x][head_y] = '0';
gameMap[mySnake[1].first][mySnake[1].second] = 'o';
return true;
}
void run()
{
while (true)
{
bool q = control_direction();
if (!move() || !q)
{
cout << "Game over!" << endl;
if (Score > AllTimeHigh_score) saveHighScore(Score);
return;
}
show();
if (Round < 3) Sleep(1000);
else if (Round < 7) Sleep(700);
else if (Round < 10) Sleep(500);
else if (Round < 30) Sleep(400);
else if (Round < 50) Sleep(300);
else if (Round < 100) Sleep(200);
else Sleep(100);
}
}
};
int main()
{
Snake snake;
snake.run();
return 0;
}
如果你喜欢的话,能不能给我的github处也点各⭐:https://github.com/Shu-Jvan/Snake-Game