当前位置:网站首页>C language Snake linked list and pointer practice
C language Snake linked list and pointer practice
2022-07-26 13:58:00 【Shining uncle】
A simple console game , Use a linked list to achieve greedy snake . Less than 200 lines of code , You can compress it in 100 Within the line .
Many students have just learned C Language , I don't know what I can do . Actually C Language can do anything , But it may be complicated , But deep learning C Language , It is very good for learning the underlying data structure and algorithm principles .
Learn other languages later , Learning speed is the same as flying .
For example, this greedy snake applet , There are many ways to do it , Array is OK , Here is a linked list , Mainly to practice the use of linked lists and pointers .

One 、 Control cursor
Want to make the console a game screen ,printf As the output , You have to realize the specified location first printf
The header file #include <conio.h>
Code :
COORD coord;
HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
// Get console buffer handle
coord.X = x;
coord.Y = y;
// Set cursor position
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("*");Using the above code, you can (x,y) Position output , The coordinate of the upper left corner of the console is (0,0).
Two 、 timing
Greedy snakes take every step , It takes some time , So it needs to be timed .
curTime = GetTickCount();
if (curTime - lastTime > 300)
{
if (move(dire, &head, food, &tail) == -1)
break;
lastTime = curTime;
}move Function is a moving function of greedy snake ,GetTickCount() Get the current time , The difference between the current time and the last time is only greater than 300ms Just move once .
You can also use a macro definition , Or output the control interval from the keyboard, that is, control the speed ( difficulty ).
3、 ... and 、 Get directions
The header file :#include <conio.h>
Code :
if (_kbhit())
{
switch (_getch())
{
case 'w':
dire = 'w'; break;
case 's':
dire = 's'; break;
case 'a':
dire = 'a'; break;
case 'd':
dire = 'd'; break;
default:break;
}
}_kbhit() Function to detect whether the keyboard is pressed , With the return 1, No return 0;_getch() Function to get the keyboard value .
We use it w,s,a,d I'd like to express it separately , Next , Left , Right .
Four 、 Construct greedy snakes
typedef struct {
int x;
int y;
}POS;
typedef struct BODY {
POS pos;
struct BODY* next;
}BODY; BODY* head = malloc(sizeof(BODY));
BODY* body = malloc(sizeof(BODY));
BODY* tail = malloc(sizeof(BODY));
BODY* food = malloc(sizeof(BODY));
int lastTime;
int curTime;
head->pos.x = w_max / 2;
head->pos.y = h_max / 2;
body->pos.x = w_max / 2 + 1;
body->pos.y = h_max / 2;
tail->pos.x = w_max / 2 + 2;
tail->pos.y = h_max / 2;
head->next = body;
body->next = tail;
tail->next = NULL;Every body , There are two parts ,pos coordinate ,next The pointer , Point to the next section . Initialize the greedy snake into three sections ,head head ,body The body ,tail tail .
5、 ... and 、 Move
There is no movement of food :
The moving position is determined according to the direction .
First, check whether the new position is on the body , That is, the traversal of the linked list , In this traversal , We put the front position of the tail pretail recorded .
The process of moving is actually turning the tail into a new head , The front part of the tail becomes the tail , The new position becomes head , The original head becomes the next section of the head .
The movement of eating food :
In fact, the position of food becomes the head node .
6、 ... and 、 Complete code
If the compilation fails , As long as malloc(sizeof(BODY)) Change it to (BODY*)malloc(sizeof(BODY)).
You can add an interface by yourself , Such as start and gameover, And speed selection , Map size selection .
tips: If you want to do the function of starting from scratch after failure, remember to release malloc Out of the space .
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#define H 52// Long
#define W 102// wide
#define h_max (H-1)
#define w_max (W-1)
#define h_min 1
#define w_min 1
typedef struct {
int x;
int y;
}POS;
typedef struct BODY {
POS pos;
struct BODY* next;
}BODY;
void produceFood(BODY* food)
{
food->pos.x = rand() % (W - 2) + 1;
food->pos.y = rand() % (H - 2) + 1;
show_point(food->pos.x, food->pos.y);
}
int show_point(int x, int y)
{
COORD coord;
HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
coord.X = x;
coord.Y = y; // Set cursor position
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("*");
return 0;
}
int clear_point(int x, int y)
{
COORD coord;
HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); // Get console buffer handle
coord.X = x;
coord.Y = y; // Set cursor position
SetConsoleCursorPosition(ConsoleHandle, coord);
printf(" ");
return 0;
}
int move(char dire, BODY** head, BODY* food, BODY** tail)
{
BODY newhead;
BODY* search;
BODY* pretail;
pretail = NULL;
int pretail_flag = 0;
newhead.pos.x = (*head)->pos.x;
newhead.pos.y = (*head)->pos.y;
switch (dire)
{
case 'w':newhead.pos.y--; break;
case 's':newhead.pos.y++; break;
case 'a':newhead.pos.x--; break;
case 'd':newhead.pos.x++; break;
default:break;
}
if (newhead.pos.y >= h_max || newhead.pos.y < h_min || newhead.pos.x < w_min || newhead.pos.x >= w_max)// Cross the line and exit
return -1;
if (newhead.pos.x == food->pos.x && newhead.pos.y == food->pos.y) // Eat food
{
BODY* newHead = malloc(sizeof(BODY));// Apply for a new space and join snakehead
newHead->pos.x = newhead.pos.x;
newHead->pos.y = newhead.pos.y;
newHead->next = *head;
*head = newHead;
produceFood(food);// Eat food to produce a new food
return 0;
}
else// If you don't eat food, move forward in the direction ( In fact, the tail becomes a new head , The front of the tail changes its tail ), At the same time, we need to see whether the new position is on the body
{
search = *head;
pretail_flag = 0;
while (1)
{
if(pretail_flag==0)
{
pretail = search;
if ((pretail->next)->next == NULL)
pretail_flag = 1;
}
if (search->pos.x == newhead.pos.x && search->pos.y == newhead.pos.y)
return -1;
if (search->next == NULL)
break;
search = search->next;
}
clear_point((*tail)->pos.x, (*tail)->pos.y);
show_point(newhead.pos.x, newhead.pos.y);
// No return -1 It means there is no collision , A new head with a new tail ,pretail New tail
pretail->next = NULL;
(*tail)->next = *head;
(*tail)->pos.x = newhead.pos.x;
(*tail)->pos.y = newhead.pos.y;
*head = *tail;
*tail = pretail;
return 0;
}
}
void show()// Draw the background
{
COORD coord;
// Get console buffer handle
HANDLE ConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
// Set cursor position
for (int i = 0; i < W; i++)
{
coord.X = i;
coord.Y = 0;
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("#");
coord.Y = H - 1;
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("#");
}
for (int i = 0; i < H; i++)
{
coord.X = 0;
coord.Y = i;
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("#");
coord.X = W - 1;
SetConsoleCursorPosition(ConsoleHandle, coord);
printf("#");
}
}
int main()
{
srand((unsigned)time(NULL));
// initialization
BODY* head = malloc(sizeof(BODY));
BODY* body = malloc(sizeof(BODY));
BODY* tail = malloc(sizeof(BODY));
BODY* food = malloc(sizeof(BODY));
int lastTime;
int curTime;
head->pos.x = w_max / 2;
head->pos.y = h_max / 2;
body->pos.x = w_max / 2 + 1;
body->pos.y = h_max / 2;
tail->pos.x = w_max / 2 + 2;
tail->pos.y = h_max / 2;
head->next = body;
body->next = tail;
tail->next = NULL;
lastTime = GetTickCount();
//
char dire;//0,1,2,3, The up and down or so
dire = 'w';
show();
show_point(head->pos.x, head->pos.y);
show_point(body->pos.x, body->pos.y);
show_point(tail->pos.x, tail->pos.y);
produceFood(food);
while (1)
{
if (_kbhit())
{
switch (_getch())
{
case 'w':
dire = 'w'; break;
case 's':
dire = 's'; break;
case 'a':
dire = 'a'; break;
case 'd':
dire = 'd'; break;
default:break;
}
}
curTime = GetTickCount();
if (curTime - lastTime > 300)
{
if (move(dire, &head, food, &tail) == -1)
break;
lastTime = curTime;
}
}
return 0;
}
边栏推荐
- 基于机器学习的技术术语识别研究综述
- Thoughts on the compilation of Dr. Shuo's opening report
- The last time I heard about eBay, or the last time
- 白帽子揭秘:互联网千亿黑产吓退马斯克
- 【数学建模】常用基本模型总结
- 基于双层主题模型的技术演化分析框架及其应用
- Integer internal cache
- Add a display horizontal line between idea methods
- C language_ Structure pointer variable introduction
- See you tomorrow at the industrial session of cloud intelligence technology forum!
猜你喜欢

.net6与英雄联盟邂逅之——根据官方LCU API制作游戏助手

飞盘,2022年“黑红”顶流

Ros2 learning (1) introduction to ros2

C语言_结构体指针变量引入

二叉树的层序遍历(C语言实现)

基于标签嵌入注意力机制的多任务文本分类模型

历时15年、拥有5亿用户的飞信,彻底死了

Feixin, which lasted 15 years and had 500million users, was completely dead

Zhou Wei: look for non consensual investment opportunities to accompany the founding team that delays satisfaction

Tianyi cloud web application firewall (edge cloud version) supports the detection and interception of Apache spark shell command injection vulnerabilities
随机推荐
2022-07-26日报:Alphafold DB数据库建立一周年,官推盘点亮点研究
Ten thousand words long article, talking about the blueprint of enterprise digital modeling
Difference between base addressing and index addressing
[dark horse morning post] many apps under bytek have been taken off the shelves; The leakage of deoxidizer in three squirrels caused pregnant women to eat by mistake; CBA claimed 406million yuan from
技术分享 | 需要小心配置的 gtid_mode
C language_ Combination of structure and array
C language_ Structure pointer variable introduction
Docker integrates the redis sentinel mode (one master, two slave and three sentinels)
Docker swarm cluster builds highly available MySQL active and standby
.net6与英雄联盟邂逅之——根据官方LCU API制作游戏助手
How to remove black edges from hyperimage images (two methods)
Circular queue (implemented in C language)
数据泄漏、删除事件频发,企业应如何构建安全防线?
Pass parameters to the routing component
My meeting of OA project
Completable future practical usage
[noip2003 popularity group] stack
Mobile dual finger scaling event (native), e.originalevent.touches
基于多特征的技术融合关系预测及其价值评估
Native JS get transform value x y z and rotate rotation angle