It turns out that there is such an easy-to-understand snake writing CFood class && CMap class (the idea is very detailed, with a detailed code explanation)

Tip: Reading this article requires a certain C++ foundation. This idea is only used to implement the basic functions of Snake. There is no graphics and no EasyX library is used. (Respect the originality, please indicate the source when reprinting this article)
This idea is very suitable for Jincheng students, this is a small project for one semester.

foreword

hint:
Please click – > https://github.com/qing-qing-mei/Snake
Previous Article: CUnit class

Reminder: The following is the main text of this article

1. Code

CFood class:

#pragma once
#include "CUnit.h"
class CFood :
    public Cunit
{
public:
    CFood(int x =0, int y=0, char pic = '#');
    virtual ~CFood();
    void createPos();   //Create food locations
};
```cpp
#include "CFood.h"
#include"CUnit.h"
#include"CMap.h"
#include<iostream>
#include<ctime>
#include<cstdlib>

using namespace std;

CFood::CFood(int x, int y, char pic) : Cunit(x, y, pic)  //Initialize with a list of members
{

}

CFood::~CFood()
{

}

void CFood::createPos()
{
	/*m_ix = CMap::KLEFT + rand() % (CMap::KWIDTH - 2);
	m_iy = CMap::KUP + rand() % (CMap::KHEIGHT - 4);*/
	m_ix = CMap::KLEFT + rand() % (CMap::KWIDTH - CMap::KLEFT - 1);
	m_iy = CMap::KUP + rand() % (CMap::KHEIGHT - CMap::KUP - 1);
}

CMap class:

#pragma once
class CMap
{
public:
	void drawGameArea();
	void drawGameInfo();
	void drawGameWindows();
public:
	static const int KLEFT;
	static const int KUP;
	static const int KWIDTH;
	static const int KHEIGHT;
	static const int KSCORE_OFFSET;
	static const int KLEVEL_OFFSET;
};
#include "CMap.h"
#include<iostream>
#include<windows.h>
#include"Cunit.h"
using namespace std;

const int CMap::KLEFT = 1;    //map left border
const int CMap::KUP = 3;     //border on map
const int CMap::KWIDTH = 80;     //long
const int CMap::KHEIGHT = 30;    //high
const int CMap::KSCORE_OFFSET = 0;    //initial score
const int CMap::KLEVEL_OFFSET = 1;   //initial game level

void CMap::drawGameWindows()  //Initialize the game window size
{
	SMALL_RECT win_size = { 0,0,KWIDTH ,KHEIGHT + 2 };  //Define four points up, down, left and right
	SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), true, &win_size);
}

void CMap::drawGameArea()  //map
{
	drawGameWindows();
	int wall[KHEIGHT][KWIDTH] = { {0} };
	for (int i = 1; i < KHEIGHT - 1; i++)
		for (int j = 1; j < KWIDTH - 1; j++)
			wall[i][j] = 1;
	for (int i = 0; i < KHEIGHT; i++)
	{
		for (int j = 0; j < KWIDTH; j++)
		{
			if (wall[i][j]) cout << " ";
			else
			{
				if (i == 0 || i == KHEIGHT - 1) cout << "-";
				else cout << "|";
			}
		}
		cout << endl;
	}
}

void CMap::drawGameInfo()  //Function: Display game information
{
	Cunit::gotoxy(1, 2);
	for (int i = 0; i < KWIDTH - 2; i++)
	{
		cout << '-';
	}
	Cunit::gotoxy(KLEFT, 1);
	cout << "Game name: Snake";
	Cunit::gotoxy(KLEFT + 1 * (KWIDTH / 4), 1);
	cout << "Writer:***";
	Cunit::gotoxy(KLEFT + 2 * (KWIDTH / 4), 1);
	cout << "Game Score:" << KSCORE_OFFSET;
	Cunit::gotoxy(KLEFT + 3 * (KWIDTH / 4), 1);
	cout << "Game level:" << KLEVEL_OFFSET;
}

2. Ideas

CFood class:
The only difficulty in the CFood class is how to make the food randomly generated within the range of the map.
To generate random numbers, please refer to this article – > c++ generate random numbers
CMap class:
In this class, we use three member functions which are
void drawGameArea(); //Initialize the game window size
void drawGameInfo(); //Display game information
void drawGameWindows(); //Draw the map

Displaying game information is relatively simple, just call the gotoxy() function in the CUnit class to position the cursor at the specified position and output the corresponding information.

It is not difficult to draw a map as long as the idea is clear. We define a two-dimensional array and initialize it to 0 to represent the map, and then pass a double loop to change the boundary of the map to 1; in this way, in the next double loop , we will output the corresponding boundary symbol with a value of 1, and output a space with a value of 0, so that a map border is drawn!

Initializing the window size is actually not difficult. The difficulty lies in the SMALL_RECT structure and the SetConsoleWindowInfo() interface. We are all unfamiliar with it, because we have never seen it before. In fact, we don't need to know how it is implemented, just what it can be used for. That's it! It only needs to be said here that basically, the windows.h header file needs to be added to call the structure or API in windows.

Regarding the SMALL_RECT structure, it is actually the four points that help us define the border of the game, which is the window boundary value.
I put a more detailed explanation here:
https://docs.microsoft.com/zh-cn/windows/console/small-rect-str
or
https://wenku.baidu.com/view/380fae4dc850ad02de8041b0.html

Regarding SetConsoleWindowInfo(), it actually completes the initialization of the window size. I have also organized two links for everyone to understand:
https://docs.microsoft.com/en-us/windows/console/setconsolewindowinfo
or
https://www.cnblogs.com/X-Jun/p/6910430.html?utm_source=itdadao&utm_medium=referral

Summarize

This article introduces food and maps. Generally speaking, it is not difficult. The next article introduces the most important snakes among greedy snakes!

Tags: C++

Posted by chadowch on Sun, 07 Aug 2022 21:42:50 +0530