当前位置:网站首页>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;
}
边栏推荐
- 【着色器实现Overlay重新覆盖变装效果_Shader效果第九篇】
- DP sword finger offer II 100. sum of minimum paths in triangle
- 基于标签嵌入注意力机制的多任务文本分类模型
- How to quickly design a set of cross end components that support rendering rich text content
- Rotation of 2D conversion, transform origin of 2D conversion center point and scale of 2D conversion
- [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
- 基于机器学习的技术术语识别研究综述
- 飞盘,2022年“黑红”顶流
- 融合多自然语言处理任务的中医辅助诊疗方案研究——以糖尿病为例
- Sequence traversal of binary tree (implemented in C language)
猜你喜欢

天翼云Web应用防火墙(边缘云版)支持检测和拦截Apache Spark shell命令注入漏洞

基于机器学习的技术术语识别研究综述

C语言_结构体和数组的结合

C语言_结构体指针变量引入
![[noip2003 popularity group] stack](/img/95/871b1c6f492b467bffd25912304b44.gif)
[noip2003 popularity group] stack

Tdsql-c serverless: help start-ups achieve cost reduction and efficiency increase

Why does WPS refuse advertising?

周伟:寻找非共识性投资机会,陪伴延迟满足的创始团队

JS page turning, kkpager.js page turning

WPS凭什么拒绝广告?
随机推荐
My meeting of OA project
LCL three-phase PWM rectifier (inverter)
Explain four interesting NPM usages with charts
JUC summary
Inspiration from brain: introduction to synaptic integration principle in deep neural network optimization
.net6 encounter with the League of heroes - create a game assistant according to the official LCU API
Comparator (interface between comparable and comparator)
WPS凭什么拒绝广告?
Circular queue (implemented in C language)
Ten thousand words long article, talking about the blueprint of enterprise digital modeling
「中高级试题」:MVCC实现原理是什么?
PHP uses sqlserver
Force deduction ----- the number of words in the string
[oauth2] v. oauth2loginauthenticationfilter
【数学建模】常用基本模型总结
LCL三相pwm整流器(逆变器)
Official announcement! Edweisen group and Baidu xirang reached a deep co creation cooperation
估值15亿美元的独角兽被爆裁员,又一赛道遇冷?
最新战报:十项认证,五项最佳实践
How to write the introduction of GIS method journals and papers?