[C++ program] Snake game

Recently , I am obsessed with writing games, although they are all simple DOS versions (the previous attempt at visual programming failed), tic-tac-toe , gomoku , and moving mazes , I came up with a snake that has not been designed. So the following program was designed.

program

// This is a simple snake game.

#include <iostream>
#include <string>
#include <vector>
#include <cstddef>
#include <Windows.h>
#include <conio.h>
#include <random>
#include <ctime>
#include <deque>
using namespace std;

struct location {
    
    
	unsigned x, y;
}loc1, loc2;

int state = 0;
int ret = 4; // head right by default
unsigned cnt = 0;
unsigned score = 0;
char p[25][30]; // the board
vector<location> vec;
deque<location> snake;

void p_def() // define p
{
    
    
	for (int i = 0; i != 25; i++)
	{
    
    
		if (i != 0 && i != 24)
		{
    
    
			p[i][0] = p[i][29] = '*';
			for (int j = 1; j != 29; j++)
				p[i][j] = ' ';
		}
		else
		{
    
    
			for (int j = 0; j != 30; j++)
				p[i][j] = '*';
		}
	}
	p[13][5] = 'O'; // body
	p[13][6] = '@'; // head
	loc1.x = 13;
	loc1.y = 6; // the initial location of the head of the snake
	loc2.x = 13;
	loc2.y = 5; // the initial location of the tail of the snake
	snake.push_front(loc2); // store the first location of the snake tail
}

void input(char c1, char c2)
{
    
    
	c1 = _getch();
	c2 = _getch();
	switch (c2)
	{
    
    
	case 72: // up
		if (ret != 2)
			ret = 1;
		break;
	case 80: // down
		if (ret != 1)
			ret = 2;
		break;
	case 75: // left
		if (ret != 4)
			ret = 3;
		break;
	case 77: // right
		if (ret != 3)
			ret = 4;
		break;
	default:
		break;
	}
}

void print()
{
    
    
	for (int i = 0; i != 25; i++)
	{
    
    
		for (int j = 0; j != 30; j++)
			std::cout << " " << p[i][j];
		std::cout << endl;
	}
}

void ran() // generate a random food for the snake to eat
{
    
    
	default_random_engine random1, random2;
	for (int i = 0; i != 644; i++)
	{
    
    
		unsigned ran1 = random1() % 23 + 1; // ranging from 1 to 23
		unsigned ran2 = random2() % 28 + 1; // ranging from 1 to 28
		location ran_l;
		ran_l.x = ran1;
		ran_l.y = ran2;
		vec.push_back(ran_l);
	}
}

void move()
{
    
    
	switch (ret)
	{
    
    
	case 1: // up
		if (p[loc1.x - 1][loc1.y] == 'O' || p[loc1.x - 1][loc1.y] == '*')
			state = 1; // indicate the end of the game
		else
		{
    
    
			if (p[loc1.x - 1][loc1.y] == '#')
			{
    
    
				score++;
				snake.push_front(loc1);
			}
			else
			{
    
    
				p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
				snake.pop_back();
				snake.push_front(loc1); // former head -> front of the tail
			}
		}
		--loc1.x;
		break;
	case 2: // down
		if (p[loc1.x + 1][loc1.y] == 'O' || p[loc1.x + 1][loc1.y] == '*')
			state = 1; // indicate the end of the game
		else
		{
    
    
			if (p[loc1.x + 1][loc1.y] == '#')
			{
    
    
				score++;
				snake.push_front(loc1);
			}
			else
			{
    
    
				p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
				snake.pop_back();
				snake.push_front(loc1); // former head -> front of the tail
			}
		}
		++loc1.x;
		break;
	case 3: // left
		if (p[loc1.x][loc1.y - 1] == 'O' || p[loc1.x][loc1.y - 1] == '*')
			state = 1; // indicate the end of the game
		else
		{
    
    
			if (p[loc1.x][loc1.y - 1] == '#')
			{
    
    
				score++;
				snake.push_front(loc1);
			}
			else
			{
    
    
				p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
				snake.pop_back();
				snake.push_front(loc1); // former head -> front of the tail
			}
		}
		--loc1.y;
		break;
	case 4: // right
		if (p[loc1.x][loc1.y + 1] == 'O' || p[loc1.x][loc1.y + 1] == '*')
			state = 1; // indicate the end of the game
		else
		{
    
    
			if (p[loc1.x][loc1.y + 1] == '#')
			{
    
    
				score++;
				snake.push_front(loc1);
			}
			else
			{
    
    
				p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
				snake.pop_back();
				snake.push_front(loc1); // former head -> front of the tail
			}
		}
		++loc1.y;
		break;
	default: //others
		break;
	}
	for (auto c : snake)
		p[c.x][c.y] = 'O'; // print the tail
	p[loc1.x][loc1.y] = '@'; // print the head
}

int main()
{
    
    
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cci;
	GetConsoleCursorInfo(hOut, &cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(hOut, &cci);
	// The five lines above are used to hide the Console Cursor.
	char c1 = '\0', c2 = '\0';
	int time_set;
	std::cout << "This is a simple snake game.\nProgrammer:Teddy van Jerry" << endl;
	Sleep(300);
	std::cout << "\nNow Loading";
	for (int i = 0; i != 6; i++)
	{
    
    
		Sleep(200);
		std::cout << ".";
	}
	Sleep(500); // stop for a while
	std::cout << "\n\nYou can move the snake using ↑,↓,←,→." << endl;
	std::cout << "\nYou can choose the speed the snake moves.\nVery slow(1) Slow(2) Medium(3) Fast(4) Very Fast(5) Very Very Fast(6)" << endl;
	char choice;
	choice = _getch();
	switch (choice) // set the speed
	{
    
    
	case '1':
		time_set = 1000;
		break;
	case '2':
		time_set = 700;
		break;
	case '3':
		time_set = 500;
		break;
	case '4':
		time_set = 350;
		break;
	case '5':
		time_set = 250;
		break;
	case '6':
		time_set = 150;
		break;
	default:
		time_set = 500;
		break;
	}
	p_def(); // define p
	cout << "\nNow get ready!\n" << endl;
	Sleep(3500);
	ran();
	while (state == 0)
	{
    
    
		unsigned long clock_p = clock();
		print();
		std::cout << "\nYour current score is " << score << " .\n" << endl;
		do
		{
    
    
			if (_kbhit()) // test if there is a click on the button
				input(c1, c2);
		} while (clock() - clock_p < time_set);
		move();
		if (p[(vec[cnt]).x][(vec[cnt]).y] == ' ')
			p[(vec[cnt]).x][(vec[cnt]).y] = '#'; // generate food for the snake to eat
		cnt++;
	}
	std::cout << "\nThe game is over.\nYour final score is " << score << " !" << endl;
	std::cout << "\nALL RIGHTS RESERVED (c) 2020 Teddy van Jerry" << endl;
	char anything;
	cin >> anything;
	return 0;
}

// ALL RIGHTS RESERVED (c) 2020 Teddy van Jerry

Sample output

Output
(Some shortcomings are that the program will flicker a bit, this is no way)

analysis

  • I wrote a lot of questions at the beginning, and it took a long time to find bugs.
    F1
    And then again (Why is it all head and the body was cut off?) And F2
    then there is this (looks right, in fact the body can't move)
    F3
  • Can look at the function of treatment time, it is in the library ctimein the time()function, in milliseconds, the actual output is long.
  • Sleep()It is the library Windows.hwhere the function is suspended so many milliseconds.
  • The 192-196 behavior cancels the cursor code, found online.
  • Line 248 _kbhit()is input determines whether or not the keyboard input. Here use _getch()is of no use (these two functions in the library are conio.hin), I tried this one before so many wrong reasons. It turns out that the program will be stuck in the input without judgment, and it won't move if you don't input it.
  • Regarding the input of the arrow keys, please refer to my blog [C++ Program] Application and Analysis in the Mobile Maze Game .
  • The storage of the snake tail is inside deque. The advantage is that the two ends are operable and the output is convenient. Specific usage can be searched on CSDN.
  • The 258-259 script is meaningless, the purpose is to use the exe file alone, sometimes when the game ends, it will exit directly without displaying the final result. Add this useless sentence to solve it. See my blog thinking about the C ++ program running on other devices .
  • For the custom random position function, ran()please refer to my blog [C++ Program] Random Number .
  • See my blog-defined functions on Thinking in C ++ function definitions impact .

ALL RIGHTS RESERVED © 2020 Teddy van Jerry
welcome to reprint, please indicate the source.


See also

Teddy van Jerry’s navigation page
[C++ program] Gobang game (human VS human)
[C++ program] Tic-Tac-Toe game (human VS human)
[C++ program] Tic-Tac-Toe game (human VS Lv1 computer)
[C++ program] Tic Tac Toe Chess Game (Human VS Lv2 Computer)
[C++ Program] Tic-Tac-Toe Game (Human VS Lv3 Computer)
[C++ Program] Tic-Tac-Toe Game (Human VS Lv3 Computer) (Statistical Version)
[C++ Program] Moving Maze Game
[C++ Program] Random number
[C++ program] Digital push board game (15-puzzle)
[C++ program] 2048 game
[C++ program] Tic-Tac-Toe game (human VS human) (EasyX graphical interface)
[C++ program] Tic-Tac-Toe game ( Human VS Lv3 Computer) (Record Statistics Edition) (EasyX Graphical Interface)

Guess you like

Origin blog.csdn.net/weixin_50012998/article/details/108423053
Recommended