用C++实现贪吃蛇(vs2017)绝对不会报错!!!

用C++实现贪吃蛇(vs2017)


初学c++,找了一个简单的游戏做一做,如果有什么地方思路复杂了,希望看到的大佬能指导一下。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>
#include <vector>
typedef enum DIR { up = 1, down, lef, rig };
using namespace std;
HANDLE Hout = GetStdHandle(STD_OUTPUT_HANDLE);
COORD Coord;
/************ 隐藏光标 ********************/
void hide() {
	CONSOLE_CURSOR_INFO curso_info = { 1,0 };
	SetConsoleCursorInfo(Hout, &curso_info);
}
/************ 定位 ************************/
void locate(int x, int y) {
	Coord.X = x;
	Coord.Y = y;
	SetConsoleCursorPosition(Hout, Coord);
}
/************* 地图点 *******************/
typedef struct nobe {
	int x, y;
	char ty;
	DIR nobe_dir;
};
/************ 建立n*n的地图 ****************/
void Map(COORD &c, const int x, const int y) {
	for (int i = 0; i < y; i++) {
		for (int j = 0; j < x; j++) {
			if (i == 0 || i == (y - 1)) {
				cout << '-';
			}
			else if (j == 0 || j == (x - 1)) {
				cout << '|';
			}
			else {
				cout << ' ';
			}
		}
		cout << endl;
	}
}
/*********** 定义蛇******************/
typedef struct Food;                                          //预声明
class Snake {
	nobe p1, p2;
public:
	bool live = true;
	bool got = false;                                                                                      //是否吃到
	vector<nobe> body;                                                                             //蛇的身体
	Snake(int i = 25, int j = 10, DIR d = down) {
		p1.x = i; p1.y = j; p1.ty = '*'; p1.nobe_dir = down; p2.x = i; p2.y = j - 1; p2.ty = '*'; p2.nobe_dir = down;
		body.push_back(p1);
		body.push_back(p2);
	}
	void go(DIR direction, Food *fd);                                                              //移动
	void clean(nobe cln_buf);                                                                             //清楚尾部
	void eat(nobe &f);                                                                             //蛇进食
	void die(void);
	vector<nobe>::size_type Get_Sna_Length() { return body.size(); }
};
/*********** 食物 *************/
typedef struct Food {
	nobe point;
	vector<nobe> granary;                                                   //粮仓
	int x, y;
	bool g_flag = true;                                                     //生成食物是否和蛇冲突
	bool over = false;                                                      //生成完成标志
	void generate(int size_x, int size_y, Snake &Sna);                      //生成食物    
	void eaten(int p);
	vector<nobe>::size_type Get_grabary() { return granary.size(); }
};
/********* 蛇进食 *******************/
void Snake::eat(nobe &f) {
	got = true;
	body.insert(body.begin(), f);
	body.begin()->ty = '*';
	locate(body.begin()->x, body.begin()->y);
	cout << body.begin()->ty;
}
void Snake::die(void) {
	system("cls");
	cout << "Game Over" << endl;
	cout << "Your Length is " << Get_Sna_Length() << endl;
	live = false;
}
void Snake::clean(nobe cln_buf) {
	body.erase(body.begin());
	locate(cln_buf.x, cln_buf.y);
	cout << cln_buf.ty;
}
/********** 蛇移动 ***********************/
void Snake::go(DIR direction, Food *fd) {
	nobe buffer;                                             //身体节数缓存区
	nobe clean_buff;                                         //清除缓冲区
	clean_buff.x = 0; clean_buff.y = 0; clean_buff.ty = ' ';
	buffer.x = body.begin()->x;
	buffer.y = body.begin()->y;
	switch (direction) {
	case up: {
		buffer.x += 0; buffer.y -= 1; buffer.ty = '*';
		for (int n = 0; n < (int)fd->Get_grabary(); n++) {
			if ((buffer.x == fd->granary[n].x) && (buffer.y == fd->granary[n].y)) { eat(fd->granary[n]); fd->eaten(n); break; }
			else { got = false; }
		}
		if (!got) {
			clean_buff.x = body[(int)Get_Sna_Length() - 1].x;
			clean_buff.y = body[(int)Get_Sna_Length() - 1].y;
			for (int i = (int)Get_Sna_Length() - 2; i >= 0; i--) {
				body[i + 1] = body[i];
				if (i == 0) { clean(clean_buff); }
			}
			body.insert(body.begin(), buffer);
		}
	}break;
	case down: {
		buffer.x += 0; buffer.y += 1; buffer.ty = '*';
		for (int n = 0; n < (int)fd->Get_grabary(); n++) {
			if ((buffer.x == fd->granary[n].x) && (buffer.y == fd->granary[n].y)) { eat(fd->granary[n]); fd->eaten(n); break; }
			else { got = false; }
		}
		if (!got) {
			clean_buff.x = body[(int)Get_Sna_Length() - 1].x;
			clean_buff.y = body[(int)Get_Sna_Length() - 1].y;
			for (int i = (int)Get_Sna_Length() - 2; i >= 0; i--) {
				body[i + 1] = body[i];
				if (i == 0) {clean(clean_buff); }
			}
			body.insert(body.begin(), buffer);
		}
	}break;
	case lef: {
		buffer.x -= 1; buffer.y -= 0; buffer.ty = '*';
		for (int n = 0; n < (int)fd->Get_grabary(); n++) {
			if ((buffer.x == fd->granary[n].x) && (buffer.y == fd->granary[n].y)) { eat(fd->granary[n]); fd->eaten(n); break; }
			else { got = false; }
		}
		if (!got) {
			clean_buff.x = body[(int)Get_Sna_Length() - 1].x;
			clean_buff.y = body[(int)Get_Sna_Length() - 1].y;
			for (int i = (int)Get_Sna_Length() - 2; i >= 0; i--) {
				body[i + 1] = body[i];
				if (i == 0) { clean(clean_buff); }
			}
			body.insert(body.begin(), buffer);
		}
	}break;
	case rig: {
		buffer.x += 1; buffer.y -= 0; buffer.ty = '*';
		for (int n = 0; n < (int)fd->Get_grabary(); n++) {
			if ((buffer.x == fd->granary[n].x) && (buffer.y == fd->granary[n].y)) { eat(buffer); fd->eaten(n); break; }
			else { got = false; }
		}
		if (!got) {
			clean_buff.x = body[(int)Get_Sna_Length() - 1].x;
			clean_buff.y = body[(int)Get_Sna_Length() - 1].y;
			for (int i = (int)Get_Sna_Length() - 2; i >= 0; i--) {
				body[i + 1] = body[i];
				if (i == 0) { clean(clean_buff); }
			}
			body.insert(body.begin(), buffer);
		}
	}break;
	}
	for (int t = 0; t < (int)Get_Sna_Length(); t++) {
		locate(body[t].x, body[t].y);
		cout << body[t].ty;
	}
}
/********* 食物被吃 *******/
void Food::eaten(int p) {
	granary.erase(granary.begin() + p);
}
/************ 生成食物 ****************/
void Food::generate(int size_x, int size_y, Snake &Sna) {
	int n = 0;
	srand((unsigned)time(NULL));
	over = false;
	while (!over) {
		x = rand() % (size_x - 2) + 1;            //这里有点迷???
		y = rand() % (size_y - 2) + 1;
		for (int i = 0; i < (int)Sna.Get_Sna_Length(); i++) {
			if (g_flag == false) { n--; g_flag = true; }
			if (x == Sna.body[i].x && y == Sna.body[i].y && g_flag == true) {
				g_flag = false;
				break;
			}
		}
		if (g_flag = true) {
			point.x = x;
			point.y = y;
			point.ty = '$';
			granary.push_back(point);
			locate(point.x, point.y);
			cout << point.ty;
			n++;
			if (n == 10) { over = true; }
		}
	}
}
/************** 获取键盘输入 *******************/
DIR scan_key(DIR &d) {
	if (_kbhit()) {
		switch (_getch()) {
		case 119: {                                         //按下W
			if (d == down) { return d; }
			else { d = up; return up; }
		}
		case 115: {                                        //按下S
			if (d == up) { return d; }
			else { d = down; return down; }
		}
		case 97: {                                        //按下A
			if (d == rig) { return d; }
			else { d = lef; return lef; }
		}
		case 100: {                                        //按下D
			if (d == lef) { return d; }
			else { d = rig; return rig; }
		}
		default: {return d; }
		}
	}
	else { return d; }               //返回上一次按键值
}
int main() {
	Food food;
	Snake snake = Snake();
	Coord.X = 0;
	Coord.Y = 0;
	Map(Coord, 50, 20);
	clock_t begin, end;
	DIR Last_Dir = down;
	hide();
	int hard = 0;
	while (1) {
		hard = snake.Get_Sna_Length();
		if ((int)food.Get_grabary() == 0) { food.generate(50, 20, snake); }
		if (!snake.live) { break; }
		snake.go(scan_key(Last_Dir), &food);
		begin = clock();
		if (snake.body[0].x == 0 || snake.body[0].x == 49 || snake.body[0].y == 0 || snake.body[0].y == 19) { snake.die(); break; } //碰到墙壁就死
		for (int t = 1; t < (int)snake.Get_Sna_Length(); t++) { 
			if ((snake.body[0].x == snake.body[t].x) && (snake.body[0].y == snake.body[t].y)) { snake.die(); break; }
		}                                                                                                                           //自撞死亡
		while (1) {
			end = clock();
			if (end - begin >= (200 - 5 * hard)) break;
		}
		locate(0, 22);
		cout << "Snake's length : " << snake.Get_Sna_Length() << endl;
		cout << "Granary : " << food.Get_grabary() << endl;
	}
	return 0;
}
  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值