Linux下C语言实现贪吃蛇
简单记录下贪吃蛇小游戏。
以下是源码:
1 #include <curses.h>
2 #include <stdlib.h>
3 #include <pthread.h>
4 #define UP 1
5 #define DOWN -1
6 #define LEFT 2
7 #define RIGHT -2
8
9 /*蛇和食物的结构体*/
10 struct Snake
11 {
12 int hang;
13 int lie;
14 struct Snake *next;
15 };
16
17 struct Snake *head = NULL; //链表头
18 struct Snake *tail = NULL; //链表尾
19 struct Snake food; //食物
20 int key; //记录键盘输入值
21 int dir; //记录输入的方向键
22
23 /*输入横坐标和纵坐标值,判断是否存在蛇的链表节点*/
24 int hasSnakeNode(int i,int j)
25 {
26 struct Snake *p; //临时变量,用于记录蛇的链表表头
27 p = head;
28
29 while(p != NULL) //当链表头不为空时,进入循环
30 {
31 if(p->hang == i && p->lie == j)
32 {
33 return 1; //输入的行纵坐标存在于蛇的链表中时返回1
34 }
35 p = p->next; //链表头指向下一个节点
36 }
37 return 0; //输入的横纵坐标不存在蛇的链表中时返回0
38 }
39
40 /*食物初始化*/
41 void initFoodnode()
42 {
43 int x; //定义横坐标临时变量
44 int y; //定义纵坐标临时变量
45 x = rand()%20; //在[0-20]范围内随机获取横坐标值
46 y = rand()%20; //在[0-20]范围内随机获取纵坐标值
47
48 if(y == 0)
49 {
50 y = rand()%20; //当纵坐标取值为0时,重新取值
51 }
52
53 food.hang = x; //将前面获取到的横坐标赋值为食物的横坐标
54 food.lie = y; //将前面获取到的纵坐标复制为食物的纵坐标
55 }
56
57 /*输入横纵坐标判断是否存在食物,用于地图刷新*/
58 int hasFoodnode(int i,int j)
59 {
60 if((food.hang == i)&&(food.lie == j))
61 {
62 return 1; //当输入横纵坐标为食物的横纵坐标时,返回1
63 }
64 return 0; //当输入横纵坐标不是食物的横纵坐标时,返回0
65 }
66
67 /*地图绘制*/
68 void gamePic()
69 {
70 int hang,lie; //行列临时变量
71 move(0,0); //每次界面刷新都将界面光标移动到(0,0)的位置
72 for(hang=0;hang<20;hang++) //历遍行
73 {
74 if(hang==0)
75 {
76 for(lie=0;lie<20;lie++)
77 {
78 printw("--"); //判断为第0行时,绘制‘--’边界符号
79 }
80 printw("\n");
81 }
82 if(hang>=0 || hang<=19)
83 {
84 for(lie=0;lie<=20;lie++)
85 {
86 if(lie==0 || lie==20)
87 {
88 printw("|");//第0和19列绘制‘|’边界符号
89 }
90 else if(hasSnakeNode(hang,lie))
91 {
92 printw("[]");//行列值满足蛇的节点坐标时,绘制‘[]’符号
93 }
94 else if(hasFoodnode(hang,lie))
95 {
96 printw("##");//行列之满足食物节点坐标时,绘制‘##’符号
97 }
98 else
99 {
100 printw(" ");//地图上空闲位置绘制‘ ’空格符号
101 }
102 }
103 printw("\n"); //每绘制完一行,该处添加一处换行符
104 }
105 if(hang==19)
106 {
107 for(lie=0;lie<20;lie++)
108 {
109 printw("--"); //判断为第19行时,绘制‘--’边界符号
110 }
111 printw("\n");
112 printw("By chenguanxiong\n");
113 printw("%d",key);
114 }
115 }
116 }
117
118 /*添加蛇身节点*/
119 void addNode()
120 {
121 struct Snake *new; //新节点变量
122 new = (struct Snake *)malloc(sizeof(struct Snake));//为新节点开辟内存空间
123
124 switch(dir) //方向键判断
125 {
126 case UP:
127 new->hang = tail->hang - 1; //向上,行减1,上移
128 new->lie = tail->lie; //列保持
129 break;
130 case DOWN:
131 new->hang = tail->hang + 1; //向下,行加1,下移
132 new->lie = tail->lie; //列保持不变
133 break;
134 case LEFT:
135 new->hang = tail->hang; //行保持不变
136 new->lie = tail->lie - 1; //向左,列减1,左移
137 break;
138 case RIGHT:
139 new->hang = tail->hang; //行保持不变
140 new->lie = tail->lie + 1; //向右,列加1,右移
141 break;
142 default:
143 break;
144
145 }
146
147 new->next = NULL; //新节点的下一个节点指向为NULL
148 tail->next = new; //尾部的下一个节点指向新节点
149 tail = new; //新节点复制给尾部节点
150 }
151
152 /*初始化蛇*/
153 void initSnake()
154 {
155 struct Snake *p; //临时变量,指向蛇的链表头
156 dir = RIGHT; //运动方向初始化为向右
157 while(head != NULL) //当链表头不为空时进入,用于释放蛇当前的链表占用内存空间
158 {
159 p = head; //p指向链表头
160 head = head->next; //链表头指向下一个节点
161 free(p); //释放链表头内存
162 }
163
164 initFoodnode(); //初始化食物
165 head = (struct Snake *)malloc(sizeof(struct Snake)); //为链表头开辟新的内存空间
166 head->hang = 2; //链表头行初始值为2
167 head->lie = 2; //链表头列初始值为2
168 head->next = NULL; //链表头的下一个节点指向为NULL
169 tail = head; //链表尾指向链表头
170
171 addNode(); //为链表添加新节点
172 addNode();
173 addNode();
174 addNode();
175 }
176
177 /*节点删除*/
178 void deleteNode()
179 {
180 struct Snake *p; //创建临时节点
181 p = head; //节点指向链表头
182 head = head->next; //链表头指向下一个节点
183 free(p); //释放p的空间(原链表头)
184 }
185
186 /*判断蛇是否越界或自残*/
187 int ifSnakedie()
188 {
189 struct Snake *p; //创建临时节点
190 p = head; //指向链表头
191
192 if(tail->hang<0 | tail->lie==0 | tail->hang==20 | tail->lie==20)
193 {
194 return 1; //当蛇链表的尾部坐标等于边界值时,返回1
195 }
196
197 while(p->next != NULL)
198 {
199 if((p->hang==tail->hang)&&(p->lie==tail->lie))
200 {
201 return 1; //当蛇链表其它的节点与尾部节点坐标相同,返回1
202 }
203 p = p->next;
204 }
205
206 return 0; //无越界,无自残,返回0
207 }
208
209 /*蛇移动*/
210 void moveSnake()
211 {
212 addNode(); //添加新节点
213 if(hasFoodnode(tail->hang,tail->lie))
214 {
215 initFoodnode(); //当蛇链表尾节点坐标值和食物坐标值一样,刷新食物位置
216 }
217 else
218 {
219 deleteNode(); //否则,删除蛇链表中的头节点
220 }
221
222 if(ifSnakedie())
223 {
224 initSnake(); //如果满足越界或者自残条件,重新初始化蛇链表
225 }
226 }
227
228 /*地图界面刷新线程函数*/
229 void* refreshjiemian()
230 {
231 while(1)
232 {
233 moveSnake(); //蛇链表移动
234 gamePic(); //地图刷新
235 refresh(); //执行刷新
236 usleep(150000); //线程休眠函数,150ms
237 }
238 }
239
240 /*方向函数*/
241 void turn(int direction)
242 {
243 if(abs(dir) != abs(direction))
244 {
245 dir = direction; //方向取绝对值比较,当左右运动时只有上下输入才生效
246 }
247 }
248
249 /*键盘方向输入监测线程函数*/
250 void* changeDir()
251 {
252 while(1)
253 {
254 key = getch(); //获取键盘输入
255 switch(key)
256 {
257 case KEY_UP:
258 turn(UP); //上
259 break;
260 case KEY_DOWN:
261 turn(DOWN); //下
262 break;
263 case KEY_LEFT:
264 turn(LEFT); //左
265 break;
266 case KEY_RIGHT:
267 turn(RIGHT); //右
268 break;
269 default:
270 break;
271 }
272 }
273 }
274
275 int main()
276 {
277 pthread_t t1; //创建线程变量t1
278 pthread_t t2; //创建线程变量t2
279
280 initscr(); //Ncurses初始化
281 keypad(stdscr,1); //在std中接受键盘的功能键
282 noecho(); //控制键盘输入进来的字符
283
284 initSnake(); //初始化蛇列表
285 gamePic(); //地图初始化
286
287 pthread_create(&t1,NULL,refreshjiemian,NULL); //创建界面刷新线程
288 pthread_create(&t2,NULL,changeDir,NULL); //创建键盘方向输入监测线程
289
290 while(1);
291
292 getch();
293 endwin();
294
295 return 0;
296 }
Linux下C语言实现贪吃蛇的更多相关文章
- linux 下C语言学习路线
UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...
- Linux下C语言编程实现spwd函数
Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...
- Linux基础与Linux下C语言编程基础
Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...
- LINUX下C语言编程基础
实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...
- LINUX下中文语言包的安装(转)
在安装盘上已经有各种语言包了,我们只需要找到他们,并安装就可以了.中文的是fonts-chinese-3.02-9.6.el5.noarch.rpmfonts-ISO8859-2-75dpi-1.0- ...
- Unix和Linux下C语言学习指南
转自:http://www.linuxdiyf.com/viewarticle.php?id=174074 Unix和Linux下C语言学习指南 引言 尽管 C 语言问世已近 30 年,但它的魅力仍未 ...
- 笔记整理——Linux下C语言正则表达式
Linux下C语言正则表达式使用详解 - Google Chrome (2013/5/2 16:40:37) Linux下C语言正则表达式使用详解 2012年6月6日Neal627 views发表评论 ...
- linux下常用语言的语法检查插件整理
linux下常用语言的语法检查插件 可以结合vim语法检查插件syntastic使用,具体请参考syntastic使用说明 如php,sql,json,css,js,html,shell,c等语法插件 ...
- LINUX下C语言编程调用函数、链接头文件以及库文件
LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...
- linux下C语言多线程编程实例
用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...
随机推荐
- 【论文阅读笔记】Class-Incremental Learning with Strong Pre-trained Models
Key_words: Continual learning, strong pretrained model, fix, fusion Create_time: April 14, 2022 6:32 ...
- 高可用(keepalived)部署方案
前言:为了减少三维数据中心可视化管理系统的停工时间,保持其服务的高度可用性.同时部署多套同样的三维可视化系统,让三维数据中心可视化系统同时部署并运行到多个服务器上.同时提供一个虚拟IP,然后外面通过这 ...
- UE中根据场景模型,导出缩略图
在实际使用中,我们有了很多模型,但是有时候我们需要这些模型对应的缩略图,比如我有很多物品,我想弄个仓库,有2种方式,要么,弄个仓库场景,一个物体一个格子摆放第二种,就是为每个物体制作一个缩略图 如果一 ...
- Midjourney 提示词工具(10 个国内外最好最推荐的)
Midjourney,是一个革命性的基于人工智能的艺术生成器,可以从被称为提示的简单文本描述中生成令人惊叹的图像.Midjourney已经迅速成为艺术家.设计师和营销人员的首选工具(包括像我这样根本不 ...
- Django框架简单搭建增删改查页面 Django请求生命周期流程图
目录 Django框架简单搭建增删改查页面 一.前期的配置文件以及连接MySQL的基本准备 二.在数据库中准备好数据 三.将MySQL的数据展示到页面(简单认识HTML模板语法 for循环) 在Dja ...
- RK3568用户自定义开机画面功能
RK方案中的开机画面处画逻辑 在RK的方案中,如RK1109,RK1126,RK3568这些嵌入式LINUX方案在开机画面的处理逻辑都是一致的. 用户的uboot,kernel开机画面都是同dts,k ...
- .NET周报 【4月第5期 2023-04-30】
国内文章 基于 Github 平台的 .NET 开源项目模板. 嘎嘎实用! https://www.cnblogs.com/NMSLanX/p/17326728.html 大家好,为了使开源项目的维护 ...
- Weblogic11g安装部署-winserver篇
目录 一.安装weblogic11g 1.1找到下载好的weblogic11g 1.2打开安装程序wls1033_oepe111150_win32.exe,并完成初始化如下图 1.3点击下一步并选择安 ...
- 【Vue2】NavigationDuplicated: Avoided redundant navigation to current location:xxxxx
翻译过来就是,导航重复:避免了到当前位置的冗余导航. 简单来说就是重复跳转了相同路径 原因 触发这种情况是因为vue-router中引入了primise,当传递了多次重复的参数就会抛出异常,而这种问题 ...
- 2022-09-02:以下go语言代码输出什么?A:9;B:11;C:编译错误;D:不确定。
2022-09-02:以下go语言代码输出什么?A:9:B:11:C:编译错误:D:不确定. package main import ( "fmt" ) func main() { ...