linux贪吃蛇c程序,Linux环境下C语言实现贪吃蛇游戏

Linux环境下C语言实现贪吃蛇游戏

[liul@test snake]$ more snake.c

#include

#include

#include

#include

#include

#define NUM 60

struct direct //用来表示方向的

{

int cx;

int cy;

};

typedef struct node //链表的结点

{

int cx;

int cy;

struct node *back;

struct node *next;

}node;

void initGame(); //初始化游戏

int setTicker(int); //设置计时器

void show(); //显示整个画面

void showInformation(); //显示游戏信息(前两行)

void showSnake(); //显示蛇的身体

void getOrder(); //从键盘中获取命令

void over(int i); //完成游戏结束后的提示信息

void creatLink(); //(带头尾结点)双向链表以及它的操作

void insertNode(int x, int y);

void deleteNode();

void deleteLink();

int ch; //输入的命令

int hour, minute, second; //时分秒

int length, tTime, level; //(蛇的)长度,计时器,(游戏)等级

struct direct dir, food; //蛇的前进方向,食物的位置

node *head, *tail; //链表的头尾结点

int main()

{

initscr();

[liul@test snake]$ more snake.c

#include

#include

#include

#include

#include

#define NUM 60

struct direct //用来表示方向的

{

int cx;

int cy;

};

typedef struct node //链表的结点

{

int cx;

int cy;

struct node *back;

struct node *next;

}node;

void initGame(); //初始化游戏

int setTicker(int); //设置计时器

void show(); //显示整个画面

void showInformation(); //显示游戏信息(前两行)

void showSnake(); //显示蛇的身体

void getOrder(); //从键盘中获取命令

void over(int i); //完成游戏结束后的提示信息

void creatLink(); //(带头尾结点)双向链表以及它的操作

void insertNode(int x, int y);

void deleteNode();

void deleteLink();

int ch; //输入的命令

int hour, minute, second; //时分秒

int length, tTime, level; //(蛇的)长度,计时器,(游戏)等级

struct direct dir, food; //蛇的前进方向,食物的位置

node *head, *tail; //链表的头尾结点

int main()

{

initscr();

initGame();

signal(SIGALRM, show);

getOrder();

endwin();

return 0;

}

void initGame()

{

cbreak(); //把终端的CBREAK模式打开

noecho(); //关闭回显

curs_set(0); //把光标置为不可见

keypad(stdscr, true); //使用用户终端的键盘上的小键盘

srand(time(0)); //设置随机数种子

//初始化各项数据

hour = minute = second = tTime = 0;

length = 1;

dir.cx = 1;

dir.cy = 0;

ch = 'A';

food.cx = rand() % COLS;

food.cy = rand() % (LINES-2) + 2;

creatLink();

setTicker(20);

}

//设置计时器(这个函数是书本上的例子,有改动)

int setTicker(int n_msecs)

{

struct itimerval new_timeset;

long n_sec, n_usecs;

n_sec = n_msecs / 1000 ;

n_usecs = ( n_msecs % 1000 ) * 1000L ;

new_timeset.it_interval.tv_sec = n_sec;

new_timeset.it_interval.tv_usec = n_usecs;

n_msecs = 1;

n_sec = n_msecs / 1000 ;

n_usecs = ( n_msecs % 1000 ) * 1000L ;

new_timeset.it_value.tv_sec = n_sec ;

new_timeset.it_value.tv_usec = n_usecs ;

return setitimer(ITIMER_REAL, &new_timeset, NULL);

}

void showInformation()

{

tTime++;

if(tTime >= 1000000) //

tTime = 0;

if(1 != tTime % 50)

return;

move(0, 3);

//显示时间

printw("time: %d:%d:%d %c", hour, minute, second);

second++;

if(second > NUM)

{

second = 0;

minute++;

}

if(minute > NUM)

{

minute = 0;

hour++;

}

//显示长度,等级

move(1, 0);

int i;

for(i=0;i

addstr("-");

move(0, COLS/2-5);

printw("length: %d", length);

move(0, COLS-10);

level = length / 3 + 1;

printw("level: %d", level);

}

//蛇的表示是用一个带头尾结点的双向链表来表示的,

//蛇的每一次前进,都是在链表的头部增加一个节点,在尾部删除一个节点

//如果蛇吃了一个食物,那就不用删除节点了

void showSnake()

{

if(1 != tTime % (30-level))

return;

//判断蛇的长度有没有改变

bool lenChange = false;

//显示食物

move(food.cy, food.cx);

printw("@");

//如果蛇碰到墙,则游戏结束

if((COLS-1==head->next->cx && 1==dir.cx)

|| (0==head->next->cx && -1==dir.cx)

|| (LINES-1==head->next->cy && 1==dir.cy)

|| (2==head->next->cy && -1==dir.cy))

{

over(1);

return;

}

//如果蛇头砬到自己的身体,则游戏结束

if('*' == mvinch(head->next->cy+dir.cy, head->next->cx+dir.cx) )

{

over(2);

return;

}

insertNode(head->next->cx+dir.cx, head->next->cy+dir.cy);

//蛇吃了一个“食物”

if(head->next->cx==food.cx && head->next->cy==food.cy)

{

lenChange = true;

length++;

//恭喜你,通关了

if(length >= 50)

{

over(3);

return;

}

//重新设置食物的位置

food.cx = rand() % COLS;

food.cy = rand() % (LINES-2) + 2;

}

if(!lenChange)

{

move(tail->back->cy, tail->back->cx);

printw(" ");

deleteNode();

}

move(head->next->cy, head->next->cx);

printw("*");

}

void show()

{

signal(SIGALRM, show); //设置中断信号

showInformation();

showSnake();

refresh(); //刷新真实屏幕

}

void getOrder()

{

//建立一个死循环,来读取来自键盘的命令

while(1)

{

ch = getch();

if(KEY_LEFT == ch)

{

dir.cx = -1;

dir.cy = 0;

}

else if(KEY_UP == ch)

{

dir.cx = 0;

dir.cy = -1;

}

else if(KEY_RIGHT == ch)

{

dir.cx = 1;

dir.cy = 0;

}

else if(KEY_DOWN == ch)

{

dir.cx = 0;

dir.cy = 1;

}

setTicker(20);

}

}

void over(int i)

{

//显示结束原因

move(0, 0);

int j;

for(j=0;j

addstr(" ");

move(0, 2);

if(1 == i)

addstr("Crash the wall. Game over");

else if(2 == i)

addstr("Crash itself. Game over");

else if(3 == i)

addstr("Mission Complete");

setTicker(0); //关闭计时器

deleteLink(); //释放链表的空间

}

//创建一个双向链表

void creatLink()

{

node *temp = (node *)malloc( sizeof(node) );

head = (node *)malloc( sizeof(node) );

tail = (node *)malloc( sizeof(node) );

temp->cx = 5;

temp->cy = 10;

head->back = tail->next = NULL;

head->next = temp;

temp->next = tail;

tail->back = temp;

temp->back = head;

}

//在链表的头部(非头结点)插入一个结点

void insertNode(int x, int y)

{

node *temp = (node *)malloc( sizeof(node) );

temp->cx = x;

temp->cy = y;

temp->next = head->next;

head->next = temp;

temp->back = head;

temp->next->back = temp;

}

//删除链表的(非尾结点的)最后一个结点

void deleteNode()

{

node *temp = tail->back;

node *bTemp = temp->back;

bTemp->next = tail;

tail->back = bTemp;

temp->next = temp->back = NULL;

free(temp);

temp = NULL;

}

//删除整个链表

void deleteLink()

{

while(head->next != tail)

deleteNode();

head->next = tail->back = NULL;

free(head);

free(tail);

}

运行

[liul@test snake]$

[liul@test snake]$ gcc snake.c -lcurses -o snake

[liul@test snake]$ ./snake

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点!

本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java正则表达式的使用和详解(上)

1.匹配验证-验证Email是否正确 public static void main(String[] args) {// 要验证的字符串String str "servicexsoftlab.net";// 邮箱验证规则String regEx "[a-zA-Z_]{1,}[0-9]{0,}(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";// 编译正则表达式P…

在组策略中使用脚本为域用户添加网络打印机

使用脚本为用户添加网络打印机 如果你想让培训部门的用户登录后就能添加网络打印机,就可以使用登录脚本来实现。其中DCServer是域控制,MarketPC1是市场部门的计算机,韩立辉用户是培训部门的用户。下面就验证使用组策略为培训部门的用户添加网…

leetcode257. 二叉树的所有路径(回溯算法)

给定一个二叉树,返回所有从根节点到叶子节点的路径。 说明: 叶子节点是指没有子节点的节点。 示例: 输入: 1 / 2 3 5 输出: [“1->2->5”, “1->3”] 解释: 所有根节点到叶子节点的路径为: 1->2->5, 1->3 代码 /*** Definition for a b…

英特尔神经计算棒_如何设置英特尔Movidius神经计算棒

英特尔神经计算棒by Rishal Hurbans由Rishal Hurbans 如何设置英特尔Movidius神经计算棒 (How to set up the Intel Movidius Neural Compute Stick) In 2017 I was approached by Intel to join their Innovator Programme. After a couple interviews I was inducted as an …

linux 脚本中的push,linux shell之pushd、popd和dirs的使用讲解

1 问题我们有时候需要保存多个路径,上下键切换不方便,用cd-只能到上个目录,我们可以用dirs和pushd和popd2 dirs、pushd、popddirs: 这个命令显示栈里面所有的路径,一定会包含当前路径,常用参数如下dirs -v 显示栈里面的所有路径和…

为什么我从 Git Flow 开发模式切换到了 Trunk Based 开发模式?

我已经使用 Git Flow 构建我的 Git 分支有几年了。但是,我遇到了 Git Flow 的一些问题,其中大部分来自长期存在的分支。解决这些问题的方案就是 Trunk Based Development。这是一个非常简单的技术,也是有效的持续交付的基础。在这篇文章中&am…

DedeCMS 提示信息! ----------dede_addonarticle

把数据保存到数据库附加表 dede_addonarticle 时出错,请把相关信息提交给DedeCms官方。Duplicate entry ’2532′ for key ‘PRIMARY’出现这种情况其实是你的主键是不可重复的,现在重复插入值为2532的主键了。可以去掉主键唯一,或是设成自增…

angular 模块构建_通过构建全栈应用程序学习Angular 6

angular 模块构建Angular 6 is out! The new features include better performance, new powerful CLI additions and a new way to inject services.Angular 6出来了! 新功能包括更好的性能,新的功能强大的CLI附加功能以及注入服务的新方法。 This tut…

leetcode74. 搜索二维矩阵(二分查找)

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性: 每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。 示例 1: 输入: matrix [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] tar…

搭建基于.NetFrameWork的私有nuget服务端及打包项目发布上传

一、私有Nuget服务端搭建 1.创建一个.NetFramework web项目 2.在nuget管理中 安装 nuget.server包 3.安装完成后修改web.config里面的 apikey 和 packagesPath apikey:推送包到nuget服务端 packpage: 上传上来的包存放的服务器位置 4.发布web项目到IIS中&#xff0c…

linux 网络配置 阮一峰,Vim 配置入门

Vim 是最重要的编辑器之一,主要有下面几个优点。可以不使用鼠标,完全用键盘操作。系统资源占用小,打开大文件毫无压力。键盘命令变成肌肉记忆以后,操作速度极快。服务器默认都安装 Vi 或 Vim。Vim 的配置不太容易,它有…

spring 之 property-placeholder 分析

不难知道&#xff0c; property-placeholder 的解析是 PropertyPlaceholderBeanDefinitionParser 完成的&#xff0c; 但是 它仅仅是个parser &#xff0c; 它仅仅是读取了 location 等配置属性&#xff0c; 并没有完成真正的解析&#xff0c;及 注册。 <context:property-p…

leetcode面试题 10.02. 变位词组

编写一种方法&#xff0c;对字符串数组进行排序&#xff0c;将所有变位词组合在一起。变位词是指字母相同&#xff0c;但排列不同的字符串。 注意&#xff1a;本题相对原题稍作修改 示例: 输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”], 输出: [ [“ate”,…

hacktoberfest_我第一次参加Hacktoberfest中学到了什么

hacktoberfestImposter syndrome is something we all struggle with to one degree or another. Imposter syndrome is the fear of exposure as a fraud. If you’re anything like me you have felt like your work was not good enough to show. Or you weren’t far along…

--save 和--save-dev的区别

npm install 在安装 npm 包时&#xff0c;有两种命令参数可以把它们的信息写入 package.json 文件&#xff0c;一个是npm install --save另一个是 npm install --save-dev&#xff0c;他们表面上的区别是--save 会把依赖包名称添加到 package.json 文件 dependencies 键下&…

Linux 文件区块连续吗,关于Linux文件系统的的简单理解和认识

关于Linux文件系统的的简单理解和认识关于文件系统的运作&#xff0c;这与操作系统带的档案数据有关。例如Linux操作系统的档案权限(rwx)与文件属性(拥有者&#xff0c;群组&#xff0c;时间参数等)。文件系统通常会将这两部分的数据分别存放在不同的区块&#xff0c;权限与属性…

服务器性能和活动监视

监视数据库的目的是评估服务器的性能。 有效监视包括定期拍摄当前性能的快照来隔离导致问题的进程&#xff0c;以及连续收集数据来跟踪性能趋势。 Microsoft SQL Server 和 Microsoft 操作系统提供实用工具&#xff0c;使您可以查看数据库的当前状态并跟踪性能的状态变化。 下一…

Microsoft Desktop Virtualization

基本上有两套啦&#xff0c;一是大家较为熟悉的MED-V。另外就是VDI(虚拟桌面基础架构)&#xff0c;也就是以下的组合&#xff1a;1、Windows Server 2008 with Hyper-V 2、System Center Virtual Machine Manager (VMM) 2008 VMM 20083、Windows Vista Enterprise Centralized …

leetcode60. 第k个排列(回溯算法)

给出集合 [1,2,3,…,n]&#xff0c;其所有元素共有 n! 种排列。 按大小顺序列出所有排列情况&#xff0c;并一一标记&#xff0c;当 n 3 时, 所有排列如下&#xff1a; “123” “132” “213” “231” “312” “321” 给定 n 和 k&#xff0c;返回第 k 个排列。 说明&…

webpack设置应用缓存_如何使用Webpack在Rails应用程序中设置TinyMCE

webpack设置应用缓存by Joanna Gaudyn乔安娜高登(Joanna Gaudyn) 如何使用Webpack在Rails应用程序中设置TinyMCE (How to setup TinyMCE in your Rails app using Webpack) The popularity of using Webpack to deal with your assets in Rails is steadily increasing. Getti…