C++ 貪食蛇代碼

 

參考其他人的代碼用自己的習慣寫了一版

Wall.h

#pragma once
#ifndef _Util_Wall_Def
#define _Util_Wall_Def

#include <sstream>
#include "mPoint.h"
#include "Food.h"


class Wall
{

public:
	Wall();
	int getHight();
	int getWidth();
	void setHight(int hight);
	void setWidth(int width);
	void drawWall();
	bool checkTouchWall(class mPoint* np);

private:
	 int hight ;
	 int width;
	 
};

#endif

Wall.cpp

#include "Wall.h"



Wall::Wall()
{
	 hight = 25;
	 width = hight * 2;
}

int Wall::getHight() {
	return hight;
}

int Wall::getWidth() {
	return width;
}

void Wall::setHight(int hight)
{
	this->hight = hight;
}

void Wall::setWidth(int width)
{
	this->width = width;
}

bool static checkSamePoint(mPoint p1, mPoint p2)
{
	if (p1.x == p2.x && p1.y == p2.y) return true;

	return false;
}   


bool Wall::checkTouchWall(mPoint* cp)
{
	if (cp->getX() < width-1 && cp->getY() < hight-1 && cp->getX()>0&& cp->getY()>0) {
		return false;
	}
	else {
		return true;
	}
}


void Wall::drawWall()
{

	for (int i = 0; i < width; i++)
	{
		for (int j = 0; j < hight; j++)
		{

			if (i == 0 ||  i == width - 1)//上下
			{
				Util::drawxy(i, j, "*",2);
				continue;
			}

			if (j == 0 || j == hight - 1 )
			{
				Util::drawxy(i, j, "*",2);
				continue;
			}
		}
	}

	stringstream ss;
	ss << "Left:a Right:d,Up:w,Down:s ";
	Util::drawxy(60, 8, ss.str(),3);

	
}

 

食物

Food.h

#pragma once

#ifndef _Food_Head_Def
#define _Food_Head_Def
#include "Snake.h"
#include "Wall.h"
using namespace std;
class Food
{

public:
	Food(class Wall* wall,class  Snake* snake);
	int getX();
	int getY();
	bool getStatus();
	void setStatus(bool status);
	void clear();

private:
	int x;
	int y;
	bool status;
};

#endif

Food.cpp

#include "Food.h"


Food::Food(class Wall* wall, class  Snake* snake)
{
LOOP:
	 x = Util::getRandomNum(1, wall->getWidth() - 2);
	 y = Util::getRandomNum(1, wall->getHight() - 2);
	//bool touch = snake.touchSnake(x, y);

	mPoint tmp(x,y);
	if (!snake->touchSnake(snake,tmp)) {
		Util::drawxy(x, y, "$",1);
		setStatus(true);
	}
	else {
		goto LOOP;
	}


}

int Food::getX()
{
	return x;
}
int Food::getY()
{
	return y;
}
bool Food::getStatus()
{
	return status;
}
void Food::setStatus(bool status)
{
	this->status = status;
}
void Food::clear()
{
	Util::drawxy(x, y, " ", 1);
}
;

Snake.h

#pragma once
#ifndef _Snake_Head_Def
#define _Snake_Head_Def

#include <list>
#include <conio.h>
#include <sstream>
#include "mPoint.h"
#include "Wall.h"

using namespace std;


class Snake
{

public:
    enum moveDirection { RIGHT=1, DOWN=-2, LEFT=-1, UP=2 };
	Snake(class Wall* tmpwall);
	bool move(class Food* food, class  Wall* wall);
	int size();
	int getDirection();
	//算成績
    void draw(int headColor);
	class mPoint getHead();
	void clear();
	bool touchSnake(class Snake* snake, class mPoint m);
	bool currentUpOrDown();
private:	
	list<mPoint> *head_body;
	void addPoint(class mPoint np);
	void removeEnd();
	bool alive;
	
	int currentDir;



};
#endif

Snake.cpp

#include "Snake.h"

void Snake::removeEnd()
{
	mPoint m = head_body->back();
		
	head_body->pop_back();
	Util::drawxy(m," ",3);


	
}

void Snake::addPoint(mPoint np)
{
	head_body->push_back(np);
}

Snake::Snake(Wall* tmpwall)
{
	alive = true;
	mPoint np(10,10);
	mPoint np2(9,10);
	mPoint np3(8,10);
	head_body = new list<mPoint>;
	head_body->push_front(np3);
	head_body->push_front(np2);
	head_body->push_front(np);
	currentDir = moveDirection::RIGHT;
	
};



bool Snake::move(Food* food,Wall* wall)
{

		mPoint np;

		mPoint head = getHead();
		int _x = head.getX();
		int _y = head.getY();

		switch (currentDir) {
		case moveDirection::UP:
			np.setX(_x);
			np.setY(_y - 1);
			break;
		case moveDirection::DOWN:
			np.setX(_x);
			np.setY(_y + 1);
			break;
		case moveDirection::LEFT:
			np.setX(_x - 1);
			np.setY(_y);
			break;
		case moveDirection::RIGHT:
			np.setX(_x + 1);
			np.setY(_y);
			break;
		}
		
		
		//是否碰到自己 
		mPoint m;
		for (list<mPoint>::iterator ite = head_body->begin(); ite != head_body->end(); ite++) {
			m = *ite;
			if (m.getX() == np.getX() && m.getY() == np.getY()) {
				Util::printInfo("Touch Snake Body!");
				head_body->push_front(np);
				draw(1);
				return false;
			}
		}
		

		//是否撞牆
		if (wall->checkTouchWall(&np)) {
			Util::printInfo("Touch Wall!");
			head_body->push_front(np);
			draw(1);
			return false;
		}

		//是否喫到食物
		if (np.getX() == food->getX() && np.getY() == food->getY()) {
			Util::printInfo("Got Food!");
			food->setStatus(false);
		}
		else {
			if (head_body->size() > 2) {
               removeEnd();
			}
		}
		head_body->push_front(np);
	
		return true;
	
}



int Snake::getDirection() {

	char input= 'N';
	while (_kbhit())
	{
		input = _getch();
	}
	int dir = currentDir;
	
	switch (input)
	{
	case 'w':dir =2; break;
	case 'W':dir = 2; break;
	case 's':dir = -2; break;
	case 'S':dir = -2; break;
	case 'a':dir = -1; break;
	case 'A':dir = -1; break;
	case 'd':dir = 1; break;
	case 'D':dir = 1; break;
	}





	if (dir == this->currentDir*-1) {
		//dir = this->currentDir;
	}else {
		this->currentDir = dir;
	}

	return dir;
}


void  Snake::draw(int headColor)
{
	if (!head_body->empty())
	{
		int i = 0;
		for (list<mPoint>::iterator it = head_body->begin(); it != head_body->end(); it++, i++)
		{
			mPoint cp = *it;
			if (i != 0) {
				Util::drawxy(cp, "#",2);
			}
		}

		mPoint head = getHead();
		Util::drawxy(head, "@", headColor);
	}

}





mPoint Snake::getHead() {
	return head_body->front();
}

void Snake::clear()
{
	if (!head_body->empty())
	{
		for (list<mPoint>::iterator it = head_body->begin(); it != head_body->end(); it++)
		{
			mPoint cp = *it;
			Util::drawxy(cp, " ", 2);
		}
	}
}

bool Snake::touchSnake(Snake* snake, mPoint m)
{
	if (head_body != nullptr&&head_body->size()>0) {
		
		for (list<mPoint> ::iterator ite = head_body->begin(); ite != head_body->end(); ite++)
		{
			if(ite->getX()==m.getX()&& ite->getY() == m.getY()) 
				return true;
		}
	}
	return false;
}

bool Snake::currentUpOrDown()
{
	switch (currentDir) {
	case moveDirection::UP:
		return true;
	case moveDirection::DOWN:
		return true;
	case moveDirection::LEFT:
		return false;
	case moveDirection::RIGHT:
		return false;
	}


	return false;
}

int Snake::size()
{
	return head_body->size();
}

mPoint.h

#pragma once

#ifndef _CPoint_Head_Def
#define _CPoint_Head_Def

#include <string>
#include <iostream>
#include "Util.h"

using namespace std;

class mPoint
{

public:
	mPoint(int x, int y);
	mPoint();

	int getX();
	int getY();
	
	void draw(string str, int color);
	void clear();


	void setX(int x);
	void setY(int y);
	friend class Util;
	friend static bool checkSamePoint(mPoint p1, mPoint p2);
private:
	int x;
	int y;
};



#endif

mPoint.cpp

#include "mPoint.h"


void mPoint::draw(string str,int color)
{
	
	Util::drawxy(x, y, str, color);
	
}

void mPoint::clear() {
	Util::drawxy(x, y, " ",1);
}

void mPoint::setX(int x)
{
	
		this->x = x;
	
}

void mPoint::setY(int y)
{
	this->y = y;
}

mPoint::mPoint(int x, int y)
{
	this->x = x;
	this->y = y;
	
}

mPoint::mPoint()
{
}

int mPoint::getX()
{
	return x;
}

int mPoint::getY()
{
	return y;
}

 

工具

Util.h

#pragma once

#ifndef _Util_Head_Def
#define _Util_Head_Def

#include <iostream>
#include <windows.h>
#include <time.h>
#include "Snake.h"
#include "Util.h"

using namespace std;
class Util
{
public:
	enum COLOR{RED=1,GREEN=2,BLUE=3};
	
	static void gotoxy(int x, int y);
	static void drawxy(int x, int y, string str, int color);
	static void drawxy(class mPoint mp, string str, int color);
	static int getRandomNum(int limitDown, int limitUp);
	static void printScore(class Snake* snake);
	static void printInfo(string str);
	static void printFinalInfo(string str);
};

#endif

Util.cpp

#include "Util.h"




void Util::gotoxy(int x, int y)
{
	COORD coord = { (short)x,(short)y };
	HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hHandle, coord);


	
}


void Util::drawxy(int x, int y, string str,int color)
{
	gotoxy(x, y);

	HANDLE hHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	switch (color)
	{
	case COLOR::GREEN:
		SetConsoleTextAttribute(hHandle, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
		break;

	case COLOR::RED:
		SetConsoleTextAttribute(hHandle, FOREGROUND_RED | FOREGROUND_RED | FOREGROUND_INTENSITY);
		break;
	case COLOR::BLUE:
		SetConsoleTextAttribute(hHandle, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
		break;
	}
	cout << str;
}

void Util::drawxy(mPoint mp, string str, int color)
{
	drawxy(mp.getX(),mp.getY(),str,color);

}


int Util::getRandomNum(int limitDown, int limitUp)
{


	srand(time(NULL));

	return limitDown + rand() % limitUp;

}

void Util::printScore(Snake* snake)
{
	int i= snake->size();
	stringstream ss;
	ss << "score:" << i-3;
	
	drawxy(60, 10, ss.str(),2);
}

void Util::printInfo(string str)
{
	drawxy(60,12,str,1) ;
}

void Util::printFinalInfo(string str)
{
	drawxy(60, 14, str, 1);
}

 

主程序(main)

SnakeGame.cpp

#include <iostream>
#include "Util.h"
#include "Wall.h"
#include "Snake.h"
#include "Food.h"
#include <windows.h>



int main()
{
Snake* snake = nullptr;
Food* food = nullptr;
LOOP:

		if (food != nullptr) {
			food->clear();
		}
		if (snake != nullptr) {
			snake->clear();
		}

		Wall *wall=new Wall();
		wall->drawWall();

		snake = new Snake(wall);
		
		food = new Food(wall, snake);
	    bool foodAvailable = true;
		bool alive = true;
		while (alive) 
		{
			snake->draw(2);
			snake->getDirection();
			if (!food->getStatus()) {
				food = new Food(wall, snake);
			}
			if (!snake->move(food,wall)) {
				alive = false;
			}
			else {
				snake->draw(2);
				Util::printScore(snake);
				if (snake->currentUpOrDown()) {
					Sleep(400);
				}
				else {
					Sleep(200);
				}
				
			}
		}

		Util::printFinalInfo("Game Over! Press Y to Restart!");

		while (1)
		{
			while (_kbhit()) {
				char c = _getch();
				if (c == 'y' || c == 'Y')
				{
					goto LOOP;
				}
			}
		}
	
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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