简单记录下贪吃蛇小游戏。

以下是源码:

  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语言实现贪吃蛇的更多相关文章

  1. linux 下C语言学习路线

    UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...

  2. Linux下C语言编程实现spwd函数

    Linux下C语言编程实现spwd函数 介绍 spwd函数 功能:显示当前目录路径 实现:通过编译执行该代码,可在终端中输出当前路径 代码实现 代码链接 代码托管链接:spwd.c 所需结构体.函数. ...

  3. Linux基础与Linux下C语言编程基础

    Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...

  4. LINUX下C语言编程基础

    实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...

  5. LINUX下中文语言包的安装(转)

    在安装盘上已经有各种语言包了,我们只需要找到他们,并安装就可以了.中文的是fonts-chinese-3.02-9.6.el5.noarch.rpmfonts-ISO8859-2-75dpi-1.0- ...

  6. Unix和Linux下C语言学习指南

    转自:http://www.linuxdiyf.com/viewarticle.php?id=174074 Unix和Linux下C语言学习指南 引言 尽管 C 语言问世已近 30 年,但它的魅力仍未 ...

  7. 笔记整理——Linux下C语言正则表达式

    Linux下C语言正则表达式使用详解 - Google Chrome (2013/5/2 16:40:37) Linux下C语言正则表达式使用详解 2012年6月6日Neal627 views发表评论 ...

  8. linux下常用语言的语法检查插件整理

    linux下常用语言的语法检查插件 可以结合vim语法检查插件syntastic使用,具体请参考syntastic使用说明 如php,sql,json,css,js,html,shell,c等语法插件 ...

  9. LINUX下C语言编程调用函数、链接头文件以及库文件

    LINUX下C语言编程经常需要链接其他函数,而其他函数一般都放在另外.c文件中,或者打包放在一个库文件里面,我需要在main函数中调用这些函数,主要有如下几种方法: 1.当需要调用函数的个数比较少时, ...

  10. linux下C语言多线程编程实例

    用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...

随机推荐

  1. python入门教程之八列表,字典,字符串,集合常用操作

    一列表常用方法 Python包含以下函数: 序号 函数 1 cmp(list1, list2)比较两个列表的元素 2 len(list)列表元素个数 3 max(list)返回列表元素最大值 4 mi ...

  2. python入门教程之一 什么是python

    python简介 1 什么是python Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页 ...

  3. win32api中文在线文档

    中文文档http://www.yfvb.com/help/win32sdk/ 英文手册https://www.jb51.net/books/724576.html

  4. [WEB]对于"Refused to execute script from 'http://xx.xx.xx/yy/zz.js' because its MIME type ('') is not executable, and strict MIME type checking is enabled."问题的解决办法

    1 文由 阶段一:对WEB服务器HTTP通信的header设置了安全头(X-Content-Options:nosniff) 两个月前协助交付侧大哥处理.修复一个三级等保项目的第三方安全公司释出的安全 ...

  5. Redis(四)主从复制

    主从复制 简介 主机数据更新之后根据配置和策略,自动同步数据到备机的Master/Slaver机制,Master以写为主,Slaver以读为主. 这样的机制能够实现: 读写分离:Master以写为主, ...

  6. $el,$nextTick,$set

    this.$el this.$el DOM的根元素 => 是一个完全唯一的 $el 直到组件挂载完成 (mounted) 之前都会是 undefined. 对于单一根元素的组件,$el 将会指向 ...

  7. 帝国cms将没有搜索到结果的关键字存入到数据库的方法

    在帝国cms网站前台搜索一个关键字,如果在网站中查询到了,这个关键字会被记录入搜索关键字表中,但是如果在网站中没有搜索到,就不会记录入搜索关键字表中,那怎么把没有搜索结果的关键字才能记录到数据库中,方 ...

  8. Sementic Kernel 案例之网梯科技在线教育

    2023年4月25日,微软公布了2023年第一季度财报,营收528亿美元, 微软CEO纳德称,「世界上最先进的AI模型与世界上最通用的用户界面--自然语言--相结合,开创了一个新的计算时代.」该公司有 ...

  9. 基于create-react-app构建静态博客

    前言: 用过hexo后,我被其强大的功能惊艳到了,于是便想自己也写一个静态博客生成器,并且可以发布到GitHub托管. 首先我们来看下效果图: 具体是怎么实现的呢? 我们通过create-react- ...

  10. Vue中使用原生js实现轮播图滑动效果

    1.在视图层模板里面绑定touchstart和touchend事件 <div class="tuWap" @touchstart="touchStart" ...