C++贪吃蛇

food.h

/**********  food.h  ************/
#include<iostream>
using namespace std;
#include "wall.h"

class Food
{
public:
	Food(Wall& wall);
	//设置食物
	void setFood();
private:
	int foodX;
	int foodY;
	Wall& wall;
};

food.cpp

/**********  food.cpp  ************/
#include "food.h"
Food::Food(Wall& tempWall):wall(tempWall){}

void Food::setFood()
{
	while(true)
	{
		foodX = rand() % (Wall::ROW - 2) + 1;
		foodY = rand() % (Wall::COL - 2) + 1;
		cout<<"foodX="<<foodX<<" foodY="<<foodY<<endl;
		//如果随机的位置是蛇头或者蛇身,就重新生成随机数
		if(wall.getWall(foodX,foodY) == ' ')
		{
			wall.setWall(foodX,foodY, '#');
			break;
		}
	}

}

wall.h

/**********  wall.h  ************/
#ifndef _WALL_HEAD
#define _WALL_HEAD
#include<iostream>
using namespace std;
class Wall
{
public:
	enum{
		ROW = 26,
		COL = 26
	};
	//初始化墙壁
	void initWall();
	//画出墙壁
	void drawWall();
	//根据索引设置二维数组的内容
	void setWall(int x,int y, char c);
	//根据索引获取当前位置的符号
	char getWall(int x,int y);

private:
	char gameArray[ROW][COL];
};
#endif

wall.cpp

/**********  wall.cpp  ************/
#include "wall.h"
void Wall::initWall()
{
	for(int i = 0;i < ROW; i++)
	{
		for(int j = 0;j < COL; j++)
		{
			//放墙壁
			if(i == 0 || j == 0 || i == ROW -1 || j == COL -1)
			{
				gameArray[i][j] = '*';
			}
			else
			{
				gameArray[i][j] = ' ';
			}
		}
	}
}

void Wall::drawWall()
{
	for(int i = 0;i < ROW;i++)
	{
		for(int j = 0;j < COL;j++)
		{
			cout<< gameArray[i][j]<<" ";
		}
		if(i == 5)
		{
			cout<<"create by zt";
		}
		if(i == 6)
		{
			cout<<"a: left";
		}
		if(i == 7)
		{
			cout<<"d: right";
		}
		if(i == 8)
		{
			cout<<"w: up";
		}
		if(i == 9)
		{
			cout<<"s: down";
		}
		cout<<endl;
	}
}

void Wall::setWall(int x,int y,char c)
{
	gameArray[x][y] = c;	
}

char Wall::getWall(int x,int y)
{
	return gameArray[x][y];
}

snake.h

/**********  snake.h  ************/
#include<iostream>
//#include "wall.h"
#include "food.h"
using namespace std;

class Snake
{
public:
	enum {
		UP = 'w',
		DOWN = 's',
		LEFT = 'a',
		RIGHT = 'd'
	};	
	//Snake();
	Snake(Wall& tempWall, Food& food);

	void initSnake();
	//销毁节点
	void destroyPoint();
	//添加节点
	void addPoint(int x,int y);
	//删除节点
	void deletePoint();
	//移动操作,返回值代表移动是否成功
	bool move(char key);
private:
	struct Point
	{
		//数据域
		int x;
		int y;
		//指针域
		Point *next;
	};
	Point *pHead;
	Point* pTail;
	//这里使用的是引用,顾名思义,只有之前存在
	//才能够进行引用,那么源砸在哪?需要从构造函数中传递进来
	Wall& wall;
	Food& food;
	bool isRool;//是否是个环,蛇头紧挨着蛇尾
};

snake.cpp

/**********  snake.cpp  ************/
#include "snake.h"


void Snake::destroyPoint()
{
	//Point* pCur = pHead;
	//while(pHead != NULL)
	//{
	//	pCur = pHead->next;
	//	delete pHead;
	//	pHead = pCur;
	//}
	Point* pCur = pTail;
	while(pTail != NULL)
	{
		pCur = pTail->next;
		delete pTail;
		pTail = pCur;
	}
}

void Snake::initSnake()
{
	destroyPoint();
	addPoint(5,3);
	addPoint(5,4);
	addPoint(5,5);
	cout<<"添加节点了";
}

//Snake::Snake()
//{
//	pHead = NULL;
//	wall = NULL;
//}
Snake::Snake(Wall& tempWall,Food& tempFood):wall(tempWall),food(tempFood)
{
	pHead = NULL;
	pTail = NULL;
	isRool = false;
}

void Snake::addPoint(int x,int y)
{
	//创建新节点
	Point* newPoint = new Point;
	newPoint->x = x;
	newPoint->y = y;
	newPoint->next = NULL;

	//如果原来头不为空,改为身子
	if(pHead != NULL)
	{
		wall.setWall(pHead->x,pHead->y,'=');
		pHead->next = newPoint;
		pHead = newPoint;
		wall.setWall(pHead->x,pHead->y,'@');
		//cout<<x<<y<<"@"<<endl;
	}
	else
	{
		//cout<<"为空了\n";
		pHead = newPoint;
		wall.setWall(pHead->x,pHead->y,'@');
		pTail = pHead;
	}

}

void Snake::deletePoint()
{
	if(pTail == NULL)
		return;
	Point* pCur = pTail;
	pTail = pTail->next;
	wall.setWall(pCur->x,pCur->y,' ');

	delete pCur;
}

bool Snake::move(char key){
	int x = pHead->x;
	int y = pHead->y;

	switch(key)
	{
	case UP:
		x--;
		break;
	case DOWN:
		x++;
		break;
	case LEFT:
		y--;
		break;
	case RIGHT:
		y++;
		break;
	default:
		return false;
	}
	if(pTail->x == x && pTail->y == y)
	{//碰到尾巴,循环
		isRool = true;
	}
	else
	{
		//判断用户到达的位置是否成功
		if(wall.getWall(x,y) == '*' || wall.getWall(x,y) == '=')
		{
			cout<<"Game OVRE"<<endl;
			return false;
		}
	}

	//移动成功 分两种
	//吃到食物 没有吃到食物
	if(wall.getWall(x,y) == '#')
	{
		addPoint(x,y);
		//重新设置食物
		food.setFood();
	}
	else//吃到和未吃到食物的重要区别是未吃到食物的时候需要删除尾部节点
	{
		addPoint(x,y);
		deletePoint();
		if(isRool == true)
		{
			wall.setWall(x,y,'@');
		}
	}
	return true;
}

game.cpp

/**********  game.cpp  ************/
#include "snake.h"
#include<ctime>
//#include<conio.h>
#include<ncurses.h>//用于接收用户输入
//#include<Windows.h>//提供sleep函数
#include<unistd.h>//sleep in unix
#include <sys/ioctl.h>
#include <termios.h>


bool kbhit()
{
	termios term;
	tcgetattr(0, &term);

	termios term2 = term;
	term2.c_lflag &= ~ICANON;
	tcsetattr(0, TCSANOW, &term2);

	int byteswaiting;
	ioctl(0, FIONREAD, &byteswaiting);

	tcsetattr(0, TCSANOW, &term);

	return byteswaiting > 0;
}

int main(){
	//添加随机种子
	srand((unsigned int)time(NULL));
	bool isDead = false;
	Wall wall;
	//Food food;
	wall.initWall();
	Food food(wall);
	Snake snake(wall,food);
	snake.initSnake();
	//snake.deletePoint();
	//wall.setWall(5,6,'=');
	//wall.setWall(5,7,'@');
	//Food food(wall);
	food.setFood();
	//snake.move('w');
	//snake.move('w');
	//snake.move('a');
	wall.drawWall();

	//cout<<wall.getWall(0,0)<<endl;
	//cout<<wall.getWall(5,5)<<endl;
	//cout<<wall.getWall(5,6)<<endl;
	//cout<<wall.getWall(1,1)<<endl;
	char preKey = ' ';
	while(!isDead)
	{
		//接收用户输入
		//char key = getchar();
		char key;
		cin>>key;

		if(preKey == ' ' && key == snake.LEFT)
			continue;
		//char key = getchar();
		//cout<<"key="<<key<<endl;
		do
		{
			if(key == snake.UP || key == snake.DOWN || key == snake.LEFT || key == snake.RIGHT)
			{
				if((key == snake.LEFT && preKey == snake.RIGHT) || (key == snake.RIGHT && preKey == snake.LEFT) || (key == snake.UP && preKey == snake.DOWN) || (key == snake.DOWN && preKey == snake.UP))
				{
					key = preKey;
				}
				preKey = key;
				if(snake.move(key) == true)
				{
					//移动成功 代码
					system("cls");
					wall.drawWall();

					sleep(1);
				}
				else
				{
					isDead = true;
					break;
				}
			}
			else
			{
				key = preKey;//强制将错误按键设为上一次的按键
			}

		}while(!kbhit());
		//cout<<key<<endl;
		//char key = wgetch();

	}


	//system("exit");
	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值