Today is June 1 children’s Day, the reward oneself a bottle of wang Zai milk, feel still have more than enough, as six years old and 170 months of children, I turned out a big write snake small game, play up although rough, but exclaimed “ye qinghui”, let me return to the small board brick nokia on the snake era.

June 1 Children’s Day, it is suggested that we collect to find childhood ow, ha, ha, ha, like the author’s hope of a key three point attention. The full code is at the end of the article.

This article is a console based on the implementation of the snake game, at that time will not interface these operations, but is because of this just have childhood that flavor! @TOC

The interface display

The initial screen has some hints for the game, the initial location of the snake and the food, and a border around it. # for our snake, * for food, and ● for borders.End of game picture:

Design ideas

Design a snake class like this:

Draw borders and other operations

Concrete implementation can see the following source code

class snake;
void Init_Console(a);// Console initialization
void gotoPos(SHORT x = 0, SHORT y = 0);// Cursor coordinate control
void Init_Map(a);/ / picture frame
void KeyConctrl(snake &, int);// Keyboard control function
void is_gameover(a);// End prompt
void Prompt_info(int.int);// Prompt message
void dis_date(int.int.double.int);// Score information
Copy the code

How to express position

The COORD structure is used for both the snake body and the food position.

COORD is a structure defined in the WindowsAPI that represents the coordinates of a character on the console screen.

typedef struct _COORD {
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate} COORD;
Copy the code

How to represent snake body

Use “#” to represent the body of the snake, which grows by one “#” with each food eaten.

How to represent food

Use the “*” to represent food, and each time a food is eaten, the next food will appear randomly on the map.

How to move

“#” for a snake, each move starts with the head of the snake, so the snake can’t reverse, which means it can’t reverse. Each time the arrow key is entered, the snake’s head moves in that direction, and the snake’s body changes direction at that point. The directions are stop, left, right, up and down.

enum direction { go_stop = 0, go_left, go_right, go_up, go_down }dir;
Copy the code

Every time you move, you do a collision detection to see if a collision has occurred.

/ / / / move
	bool move(a)
	{
		switch (this->dir)
		{
		case go_stop:
			break;
		case go_left:
			in_Pos.X -= 2;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_right:
			in_Pos.X += 2;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_up:
			in_Pos.Y--;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_down:
			in_Pos.Y++;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		}
		return false; }};Copy the code

Check the collision

Check the expansion border is relatively simple, is to test whether the snake head coordinates beyond the border range.

// Snake bump edge detection
	bool check_snk(COORD snk_Pos)
	{
		// Boundary detection
		if (snk_Pos.Y <= 1 || (snk_Pos.Y >= 23) || (snk_Pos.X <= 1) || snk_Pos.X >= 45)
		{
			return true;
		}
		for (int i = clear_bit; i <= print_bit; i++)
		{
			if (_Pos[i].X == snk_Pos.X && _Pos[i].Y == snk_Pos.Y) return true;
		}
		return false;
	}
Copy the code

Speed upgrade

Every time the snake eats five foods and scores 500 points, its speed is increased by 1, and the maximum speed is set to 5.

void up_speed(a)
	{
		if (this->speed < 5) (this->speed)++;

	}
Copy the code

The source code

#include <iomanip>
#include <windows.h>
#include <iostream>
#include <conio.h>
using namespace std;

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// Global handle
class snake;
void Init_Console(a);// Console initialization
void gotoPos(SHORT x = 0, SHORT y = 0);// Cursor coordinate control
void Init_Map(a);/ / picture frame
void KeyConctrl(snake &, int);// Keyboard control function
void is_gameover(a);// End prompt
void Prompt_info(int.int);// Prompt message
void dis_date(int.int.double.int);// Score information

bool gameOver = false;
bool withdraw = false;

class snake
{
private:
	bool flash;
	int speed, length, print_bit, clear_bit;
	COORD in_Pos, bit_Pos;
	COORD _Pos[255];
	enum direction { go_stop = 0, go_left, go_right, go_up, go_down }dir;
public:
	snake(SHORT x = 9, SHORT y = 5)
	{
		clear_bit = print_bit = length = speed = 0;
		in_Pos.X = x; in_Pos.Y = y; bit_Pos.X = 11; bit_Pos.Y = 8;
		flash = true;
		dir = go_stop;
		_Pos[0].X = in_Pos.X;
		_Pos[0].Y = in_Pos.Y;
	}
	~snake() {}
	void up_speed(a)
	{
		if (this->speed < 5) (this->speed)++;


	}
	double get_speed(a)
	{
		return this->speed;
	}
	int get_length(a)
	{
		return this->length;
	}
	//
	void dir_control(char _dir)
	{
		switch (_dir)
		{
		case 's': this->dir = go_stop;
			break;
		case 'l': if (this->dir ! = go_right)this->dir = go_left;
			break;
		case 'r': if (this->dir ! = go_left)this->dir = go_right;
			break;
		case 'u': if (this->dir ! = go_down)this->dir = go_up;
			break;
		case 'd': if (this->dir ! = go_up)this->dir = go_down;
			break; }}// Cursor position
	void setPos(COORD pos)
	{
		SetConsoleCursorPosition(hOut, pos);
	}

	// Collision detection
	void check_bit(a)
	{
		if (in_Pos.X == bit_Pos.X && in_Pos.Y == bit_Pos.Y)
		{
			length++;
			if ((length % 5= =0))
			{
				if (this->speed < 5)this->speed++;
			}
			if (length == 254)
			{
				cout << "Beat the game!";
			}
			do
			{
				srand(time(NULL));
				bit_Pos.X = 3 + (rand() % 20) * 2;
				bit_Pos.Y = 2 + rand() % 20;
			} while (check_snk(bit_Pos));
		}
		else
		{
			cle();
			clear_bit++;
		}
	}
	// Snake bump edge detection
	bool check_snk(COORD snk_Pos)
	{
		// Boundary detection
		if (snk_Pos.Y <= 1 || (snk_Pos.Y >= 23) || (snk_Pos.X <= 1) || snk_Pos.X >= 45)
		{
			return true;
		}
		for (int i = clear_bit; i <= print_bit; i++)
		{
			if (_Pos[i].X == snk_Pos.X && _Pos[i].Y == snk_Pos.Y) return true;
		}
		return false;
	}

	/ / show
	void dis(a)
	{
		if(! flash) {setPos(bit_Pos);
			SetConsoleTextAttribute(hOut, 0x0e);
			cout << "";
			flash = true;
		}
		else
		{
			setPos(bit_Pos);
			SetConsoleTextAttribute(hOut, 0x0e);
			cout << "*";
			flash = false;
		}
		setPos(in_Pos);
		SetConsoleTextAttribute(hOut, 0x09);
		cout << "#";

	}
	void cle(a)
	{

		setPos(_Pos[clear_bit]);
		SetConsoleTextAttribute(hOut, 0x05);
		cout << "";
	}

	void save_date(a)
	{

		if (print_bit == 254)
		{
			for (int i = 0; i <= length; i++)
			{
				_Pos[i].X = _Pos[clear_bit + i].X;
				_Pos[i].Y = _Pos[clear_bit + i].Y;
			}
			clear_bit = 0;
			print_bit = length;
		}
		print_bit++;
		_Pos[print_bit].X = in_Pos.X;
		_Pos[print_bit].Y = in_Pos.Y;

	}

	/ / / / move
	bool move(a)
	{
		switch (this->dir)
		{
		case go_stop:
			break;
		case go_left:
			in_Pos.X -= 2;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_right:
			in_Pos.X += 2;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_up:
			in_Pos.Y--;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		case go_down:
			in_Pos.Y++;
			if (check_snk(in_Pos))
			{
				return true;
			}
			dis(a);save_date(a);check_bit(a);break;
		}
		return false; }};int main(a)
{
	do
	{
		Init_Console(a);Init_Map(a);Prompt_info(3.3);
		snake s(27.11);
		clock_t t_in, t_out;
		t_in = clock(a); s.dis(a);//
		while(! gameOver) {if (_kbhit())
			{
				KeyConctrl(s, _getch());
			}

			t_out = clock(a);dis_date(3.5, s.get_speed(), s.get_length());
			if (t_out - t_in > ((0.25 - (s.get_speed(a) /25)) * CLOCKS_PER_SEC))
			{
				t_in = t_out;
				gameOver = s.move(a);if (gameOver)
				{
					is_gameover();
				}
			}
			Sleep(10);
		}
		//
		while (gameOver)
		{
			if (_kbhit())
			{
				switch (_getch())
				{
				case 'y':
				case 'Y':
					gameOver = false;
					system("cls");
					break;
				case 'n':
				case 'N':
					gameOver = false;
					withdraw = true;
					break; }}Sleep(10); }}while(! withdraw);gotoPos(15.13);
	return 0;
}

// Console initialization
void Init_Console(a)
{
	SetConsoleTitleA("Console_ snake");
	COORD dSiz = { 80.25 };
	SetConsoleScreenBufferSize(hOut, dSiz);// Set the window buffer size
	CONSOLE_CURSOR_INFO _guan_biao = { 1, FALSE };// Set the cursor size to hide the cursor
	SetConsoleCursorInfo(hOut, &_guan_biao);
	system("color 0f");// Set the canvas color

}
// Cursor position
void gotoPos(SHORT x, SHORT y)
{
	COORD pos = { x, y };
	SetConsoleCursorPosition(hOut, pos);
}
/ / picture frame
void Init_Map(a)
{
	//SetConsoleTextAttribute(hOut, 0xF0); // Set the foreground color and background color
	system("cls");
	/ / the left margin
	for (int i = 0; i < 23; i++)
	{
		cout << endl << "Low";
	}
	/ / on the border
	gotoPos(3.1);
	for (int i = 0; i < 21; i++)
	{
		cout << "Low";
	}
	/ / bottom border
	gotoPos(3.23);
	for (int i = 0; i < 21; i++)
	{
		cout << "Low";
	}
	/ / right border
	for (SHORT i = 1; i <= 23; i++)
	{
		gotoPos(45, i);
		cout << "Low"; }}// Keyboard control function
void KeyConctrl(snake &_snk, int _key)
{
	switch (_key)
	{
	case ' ':
		_snk.dir_control('s');
		break;
	case 'w':
	case 'W':
	case 72: _snk.dir_control('u');
		break;
	case 'a':
	case 'A':
	case 75: _snk.dir_control('l');
		break;
	case 'd':
	case 'D':
	case 77: _snk.dir_control('r');
		break;
	case 's':
	case 'S':
	case 80: _snk.dir_control('d');
		break;
	case '+': _snk.up_speed(a);break;
	default: break; }}// End prompt
void is_gameover(a)
{

	gotoPos(17.11);
	SetConsoleTextAttribute(hOut, 0xec);
	cout << "game over!";
	gotoPos(15.12);
	cout << "Y restart /N exit";
	SetConsoleTextAttribute(hOut, 0x0f);

}
// Prompt message
void Prompt_info(int _x, int _y)
{

	SetConsoleTextAttribute(hOut, 0xB);
	gotoPos(_x + 47, _y + 0);
	cout << ■ Game description:;
	gotoPos(_x + 51, _y + 2);
	cout << "A. Movement speed automatically increases by 1 for every 500 points scored.";
	gotoPos(_x + 51, _y + 3);
	cout << "B. Manual acceleration with a maximum speed of 5";
	gotoPos(_x + 47, _y + 5);
	cout << ■ Operating instructions:;
	gotoPos(_x + 51, _y + 7);
	cout << "□ Move left: ← A";
	gotoPos(_x + 51, _y + 8);
	cout << "□ Move to the right: → D";
	gotoPos(_x + 51, _y + 9);
	cout << "□ Move down: ↓ S";
	gotoPos(_x + 51, _y + 10);
	cout << "□ Upward movement: ↑ W";
	gotoPos(_x + 51, _y + 11);
	cout << □ Control acceleration: +;
	gotoPos(_x + 51, _y + 12);
	cout << "□ Pause the game: space";
	gotoPos(_x + 51, _y + 13);
	cout << "□ Start the game: Any arrow keys";
	gotoPos(_x + 47.22);
	cout << ■By: Codebowl is pretty Me;
}
// Speed integral display
void dis_date(int _x, int _y, double Sped, int Score)
{
	SetConsoleTextAttribute(hOut, 0xB);
	gotoPos(_x + 47, _y + 13);
	cout << setw(2) < <◆ Moving speed:;
	SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
	cout << Sped;
	gotoPos(_x + 47, _y + 14);
	SetConsoleTextAttribute(hOut, 0xB);
	cout << ◆ Current score:;
	SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_INTENSITY);
	cout << setw(2) << Score * 100;
}
Copy the code

Programming these small games, you will unknowingly fall in love with programming, especially suitable for beginners to study and achieve.

This is Codebowl. A C++ development interview, but entered the big factory data development of the handsome boy. I hope you can pay attention to it