一個很搓很醬油的貪喫蛇

尷尬上課的時候突然有思路,就給寫了下來。。。
思路:
2個線程,主線程獲取輸入的方向,子線程根據主線程得到的方向操作蛇的移動。。。
1個char型的2維數組用於存放座標信息,其中‘0’爲空地,‘1’爲蛇的身體,‘2’爲食物(就定義了這3個,其他的可以自定義)
1個deque存放蛇各位置的座標信息
程序開始時,子線程啓動,蛇按初始方向移動,每移動一步,則分別判斷該位置座標是否爲蛇的身體,空地或者食物 ,如爲蛇的身體則遊戲結束;爲空地則在該位置輸出一個字符(如'*')代表蛇移動到了當前位置,然後將該位置的座標壓入deque前端,並彈出deque最後一個座標(同時要擦除該座標位置的圖案);爲食物,額。。大部分同遇到空地所做的操作,只是最後沒有彈出deque的最後一個座標(蛇的身體增長了。。。)(當然了,,,修改deque的時候要同時修改char型數組相應座標的值。。。)



#include <Windows.h>
#include <conio.h>
#include <thread>
#include <deque>
#include <iostream>
#define LEFT 0
#define TOP 0
#define RIGHT 79
#define BOTTOM 24
#define INITLEN 3
char map[BOTTOM-TOP][RIGHT-LEFT]={'0'};
typedef struct myPOINT
{
	int x;
	int y;
}point;
int currentX=LEFT+INITLEN-1,currentY=(TOP+BOTTOM)/2;
int direction='d';
using std::deque;
using std::thread;
void gotoxy(point& p);
void snakerun();
void erase(deque<point>& snake);
bool add(deque<point>& snake,point& p);
void initialsnake(deque<point>& snake);
void snakemove(deque<point>& snake,point& p);
void createfood(deque<point>snake);
bool foodexist(deque<point>snake,point& p);
void snakerun()
{
	deque<point>snake;
	initialsnake(snake);
	createfood(snake);
	point p;
	while(1)
	{
		switch(tolower(direction)) //穿牆。。。。
		{
		case 'w':
			currentY-=1;
			if(currentY==TOP-1)  //避免越界
				currentY=BOTTOM-1;
			break;
		case 's':
			currentY+=1;
			if(currentY==BOTTOM)
				currentY=TOP;
			break;
		case 'a':
			currentX-=1;
			if(currentX==LEFT-1)
				currentX=RIGHT-1;
			break;
		case 'd':
			currentX+=1;
			if(currentX==RIGHT)
				currentX=LEFT;
			break;
		}
		p.x=currentX;
		p.y=currentY;
		snakemove(snake,p);
		Sleep(200);
	}
}
void snakemove(deque<point>& snake,point& p)
{
	bool eatFood=false;
	eatFood=add(snake,p);
	if(!eatFood)
		erase(snake);
	else
		createfood(snake);
}
void erase(deque<point>& snake)
{
	point p;
	p=snake[snake.size()-1];
	gotoxy(p);
	snake.pop_back();
	std::cout<<" ";//消除該位置的字符
	map[p.y][p.x]='0';
}
bool foodexist(deque<point>snake,point& p)
{
	for(deque<point>::iterator it=snake.begin();it!=snake.end();++it)
		if(it->x==p.x && it->y==p.y)
			return 1;
	return 0;
}
void createfood(deque<point>snake)  //沒效率
{
	point p;
	while(1)
	{
		p.x=rand()%(RIGHT-LEFT);
		p.y=rand()%(BOTTOM-TOP);
		if(!foodexist(snake,p))
			break;
	}
	gotoxy(p);
	printf("#");
	map[p.y][p.x]='2';
}
bool add(deque<point>& snake,point& p)
{
	bool eatfood=false;
	snake.push_front(p);
	gotoxy(p);
	std::cout<<"*";//輸出蛇的身體
	if(map[p.y][p.x]=='1' && !(p.x==snake[snake.size()-1].x && p.y==snake[snake.size()-1].y)) //判斷是否喫到自己。。
	{
		p.x=(RIGHT+LEFT)/2-4; 
		p.y=(TOP+BOTTOM)/2;
		gotoxy(p);
		std::cout<<"Game Over"<<std::endl;
		exit(0);
	}
	else if(map[p.y][p.x]=='2')//喫到食物鳥。。。。
		eatfood=true;
	map[p.y][p.x]='1';
	return eatfood;
}
void initialsnake(deque<point>& snake) //初始化
{
	int mid=(TOP+BOTTOM)/2,i;
	point p;
	for(i = LEFT;i<LEFT+INITLEN;++i)
	{
		p.x=i;
		p.y=mid;
		add(snake,p);
	}
}
void gotoxy(point& p)
{
	COORD pos;
	pos.X=p.x;
	pos.Y =p.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); //光標移動
}
int main()
{
	char curDirection;
	srand(time(NULL));
	std::thread snakethr=std::thread(snakerun);
	while(1)
	{
		curDirection=_getch();
		switch(tolower(curDirection)) //方向不能跟原方向相反
		{
		case 'w':if(direction=='s') curDirection='s';break;
		case 's':if(direction=='w') curDirection='w';break;
		case 'a':if(direction=='d') curDirection='d';break;
		case 'd':if(direction=='a') curDirection='a';break;
		}
		direction=curDirection;
	}
}


運行時的截圖


-----------------------------------------------13/10/11--------------------------------------------------------------

修改了下。。。之前的實在無法吐槽。。。現在改成了一個類。。。

#include <Windows.h>
#include <conio.h>
#include <deque>
#include <ctime>
#include <vector>
#include <iostream>
using std::deque;
using std::vector;
typedef class myPOINT
{
public:
	myPOINT(int xpos,int ypos):x(xpos),y(ypos){}
	myPOINT() {}
	int x,y;
}point;
class greedysnake
{
public:
	greedysnake(int left=20,int top=2,int right=60,int bottom=14,int initlen=3,int speed=1):
		_left(left),_top(top),_right(right),_bottom(bottom),_initlen(initlen),_currentX(left+initlen-1),_currentY((top+bottom)/2),_direction('d'),
		_speed(speed)
	{
		_map.resize(bottom-top);
		for(int i=0;i<signed(_map.size());++i)
			_map[i].resize(right-left);
		if(_speed>5) _speed=5;
	}
	void changespeed(int speed) {_speed=speed>5?5:speed;}
	void getinput();
private:
	int _left,_top,_right,_bottom,_initlen,_direction;
	int _currentX,_currentY;
	int _speed;
	point _p;
	deque<point>_snake;
	vector<vector<char> >_map;
	void _gotoxy(point& p);
	void _erase();
	bool _add();
	void _createframe();
	void _snakemove();
	void _createfood();
	void _initialsnake();
	void _snakerun();
	bool _foodexist(point& p);
	void _buildframe(point& p1,point& p2);
};
void greedysnake::_buildframe(point& p1,point& p2)  //建外框
{
	_gotoxy(p1);
	for(int i=0;i<=p2.x-p1.x;++i)
		if(i!=0 && i!=p2.x-p1.x)
			printf("-");
		else
			printf("+");
	_gotoxy(point(p1.x,p2.y));
	for(int i=0;i<=p2.x-p1.x;++i)
		if(i!=0 && i!=p2.x-p1.x)
			printf("-");
		else
			printf("+");
	for(int i=1;i<p2.y-p1.y;++i)
	{
		_gotoxy(point(p1.x,p1.y+i));
		printf("|");
		_gotoxy(point(p2.x,p1.y+i));
		printf("|");
	}
}
void greedysnake::_snakerun()
{
	switch(tolower(_direction)) //穿牆。。。。
	{
	case 'w':
		_currentY-=1;
		if(_currentY==_top-1)  //避免越界
			_currentY=_bottom-1;
		break;
	case 's':
		_currentY+=1;
		if(_currentY==_bottom)
			_currentY=_top;
		break;
	case 'a':
		_currentX-=1;
		if(_currentX==_left-1)
			_currentX=_right-1;
		break;
	case 'd':
		_currentX+=1;
		if(_currentX==_right)
			_currentX=_left;
		break;
	}
	_p.x=_currentX;
	_p.y=_currentY;
	_snakemove();
	Sleep(200-_speed*30);  //蛇的速度
}
void greedysnake::_snakemove()
{
	bool eatFood=false;
	eatFood=_add();
	if(!eatFood)
		_erase();
	else
		_createfood();
}
void greedysnake::_erase()
{
	point p;
	p=_snake[_snake.size()-1];
	_gotoxy(p);
	_snake.pop_back();
	std::cout<<" ";//消除該位置的字符
	_map[p.y-_top][p.x-_left]='0';
}
bool greedysnake::_foodexist(point& p)
{
	for(deque<point>::iterator it=_snake.begin();it!=_snake.end();++it)
		if(it->x==p.x && it->y==p.y)
			return 1;
	return 0;
}
void greedysnake::_createfood()  //沒效率
{
	point p;
	while(1)
	{
		p.x=_left+rand()%(_right-_left);
		p.y=_top+rand()%(_bottom-_top);
		if(!_foodexist(p))
			break;
	}	
	_gotoxy(p);
	printf("#");
	_map[p.y-_top][p.x-_left]='2';
}
bool greedysnake::_add()
{
	bool eatfood=false;
	_snake.push_front(_p);
	_gotoxy(_p);
	std::cout<<"*";//輸出蛇的身體
	if(_map[_p.y-_top][_p.x-_left]=='1') //判斷是否喫到自己。。
	{
		_p.x=(_right+_left)/2-4; 
		_p.y=(_top+_bottom)/2;
		_gotoxy(_p);
		std::cout<<"Game Over"<<std::endl;
		exit(0);
	}
	else if(_map[_p.y-_top][_p.x-_left]=='2')//喫到食物鳥。。。。
		eatfood=true;
	_map[_p.y-_top][_p.x-_left]='1';
	return eatfood;
}
void greedysnake::_initialsnake() //初始化
{
	int mid=(_top+_bottom)/2,i;
	for(i = _left;i<_left+_initlen;++i)
	{
		_p.x=i;
		_p.y=mid;
		_add();
	}
}
void greedysnake::_gotoxy(point& p)
{
	COORD pos;
	pos.X=p.x;
	pos.Y =p.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); //光標移動
}
void greedysnake::getinput()
{
	char curDirection;
	srand(signed(time(NULL)));
	_initialsnake();
	_buildframe(point(_left-1,_top-1),point(_right,_bottom));
	_createfood();
	while(1)
	{
		if(_kbhit())
		{
			curDirection=_getch();
			switch(tolower(curDirection)) //方向不能跟原方向相反
			{
			case 'w':if(_direction=='s') curDirection='s';break;
			case 's':if(_direction=='w') curDirection='w';break;
			case 'a':if(_direction=='d') curDirection='d';break;
			case 'd':if(_direction=='a') curDirection='a';break;
			default: curDirection=_direction;
			}
			_direction=curDirection;
		}
		_snakerun();
	}
}
int main()
{
	greedysnake snake(10,2,40,14,6,2);
	snake.changespeed(2);
	snake.getinput();
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章