c++简易版贪吃蛇
效果图
代码
#include<deque>
#include<vector>
#include<conio.h>
#include<windows.h>
#include<iostream>
using namespace std;
deque<pair<int, int>> player_snake;
enum direction { left_, up_, right_, below_ };
size_t max_food_num = 2;
size_t current_food_num;
template<class T>
bool step_correct(vector<vector<T>>& vis, deque<pair<int, int>>& snake, pair<int, int>& position);
template<class T>
void generate_food(vector<vector<T>>& vis, int num = 1);
class Direction {
public:
Direction(int flag, pair<int, int>& positon) {
switch (flag)
{
case 0:--positon.second; break;//left
case 1:--positon.first; break;//up
case 2:++positon.second; break;//right
case 3:++positon.first; break;//below
default:
break;
}
}
};
void snake(int n, int m) {
vector<vector<char>> map(n);
for (auto& line : map) {
line.resize(m, '.');
}
vector<vector<int>> vis(n);
for (auto& line : vis) {
line.resize(m, 0);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
vis[i][j] = 0;
}
}
player_snake.clear();
current_food_num = 0;
int d = left_; //default direction
player_snake.push_back(pair<int, int>(n / 2, m / 2));//startPoint
player_snake.push_back(pair<int, int>(n / 2, m / 2 + 1));
player_snake.push_back(pair<int, int>(n / 2, m / 2 + 2));
char op = 0;
while (op != '\r') {
system("cls");
for (auto& node : player_snake) {
vis[node.first][node.second] = 1;
}
generate_food(vis, 2);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (vis[i][j] == 1)
cout << '*';
else if (vis[i][j] == 0)
cout << map[i][j];
else {
cout << '$';
}
}
cout << endl;
}
Sleep(100);
if (_kbhit()) // kbhit()是一个C和C++函数,非阻塞地响应键盘输入事件
op = _getch();
switch (op)
{
case 'w':
case 'W':if (d != below_) d = up_; break;
case 's':
case 'S':if (d != up_) d = below_; break;
case 'a':
case 'A':if (d != right_) d = left_; break;
case 'd':
case 'D':if (d != left_) d = right_; break;
default:
break;
}
pair<int, int> temp = *player_snake.begin();
Direction a(d, temp);
if (!step_correct(vis, player_snake, temp)) {
cout << "GAME OVER!" << endl;
break;
}
else {
if (vis[temp.first][temp.second] == 2) { //got the food
player_snake.push_back(pair<int, int>());
--current_food_num;
}
for (deque<pair<int, int>>::iterator p = --player_snake.end(), q = p; q != player_snake.begin(); --q) {
vis[(*q).first][(*q).second] = 0;
p = q - 1;
*q = *p;
}
vis[(*player_snake.begin()).first][(*player_snake.begin()).second] = 0;
Direction a(d, *player_snake.begin());
for (auto& node : player_snake) {
vis[node.first][node.second] = 1;
}
}
}
}
template<class T>
bool step_correct(vector<vector<T>>& vis, deque<pair<int, int>>& snake, pair<int, int>& position) {
size_t x = position.first;
size_t y = position.second;
if (x < 0 || x >= vis.size() || y < 0 || y >= vis[0].size())
return false;
for (deque<pair<int, int>>::iterator it = ++snake.begin(); it != snake.end(); ++it) {
if ((*it).first == x && (*it).second == y) {
return false;
}
}
return true;
}
template<class T>
void generate_food(vector<vector<T>>& vis, int num) {
for (int i = 0; i < num; i++) {
if (current_food_num + 1 > max_food_num)
return;
while (true) {
int x = rand() % vis.size();
int y = rand() % vis[0].size();
if (vis[x][y] != 1 && vis[x][y] != 2) {
vis[x][y] = 2;
++current_food_num;
break;
}
}
}
}
int main() {
cout << "Use the W-A-S-D to play this game ," << endl;
cout << "\t and press any key for start, enjoy it! " << endl;
_getch();
do {
snake(20, 60);
cout << "Press Enter to continue , or other keys to exit." << endl;
} while (_getch() == '\r');
getchar();
return 0;
}