首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

小弟我写的贪吃蛇,请大家多多支持

2012-02-22 
我写的贪吃蛇,请大家多多支持C/C++ code//mysnake1.0.c//编译命令:cc mysnake1.0.c -lcurses -o mysnake1.

我写的贪吃蛇,请大家多多支持

C/C++ code
//mysnake1.0.c//编译命令:cc mysnake1.0.c -lcurses -o mysnake1.0//用方向键控制蛇的方向#include <stdio.h>#include <stdlib.h>#include <curses.h>#include <signal.h>#include <sys/time.h>#define NUM 60struct 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;        /* set reload  */    new_timeset.it_interval.tv_usec = n_usecs;      /* new ticker value */    n_msecs = 1;    n_sec = n_msecs / 1000 ;    n_usecs = ( n_msecs % 1000 ) * 1000L ;    new_timeset.it_value.tv_sec     = n_sec  ;      /* store this   */    new_timeset.it_value.tv_usec    = n_usecs ;     /* and this     */    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<COLS;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<COLS;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);} 



学LINUX差不多一个月了,就写一个curses版的贪吃蛇来练习一下吧,同时谢谢CSDN上的朋友对我的帮助
这个程序不难,但也算是我的一个作品吧,呵呵

如果你觉得这个程序写得好,就支持一下,如果觉得不好,就提点改进意见吧。
我也是初学者,大家共同学习,共同进步,呵呵

说一下这个程序的不足之吧(自我感觉)
1:数据封装做得不好,大量使用全局变量,存在安全隐患。(以前用C++用得多了,用回C语言反而不习惯了)
2:这个游戏没有存档功能。(因为我不知该怎样实现)
3:蛇上下行走与左右行走的速度不同。
4:没有使用多线程,多线程技术我现在用得还不是很熟练,如果有机会做2.0版本的话,我会加上多线程机制的。

如果大家发现了这个程序的BUG的话,请和我说一声,我会尽力改正的,
也欢迎大家多提意见,还是那句话,大家共同学习,共同进步。

最后,祝大家国庆节快乐!!

[解决办法]
撞墙之后 随便按个键 会出现一个段错误
[解决办法]
支持,加精,支持开源的程序。
[解决办法]
不错不错,虽然我看不懂C
[解决办法]
不错不错,虽然我看不懂C
[解决办法]

[解决办法]
我改变终端大小,莫名挂了

写得不错
[解决办法]
恩 不错 感谢分享
[解决办法]
恩 不错 感谢分享
[解决办法]
顶了...不错不错哈
[解决办法]
呵呵,不错,还可以短一点
[解决办法]
楼主是我的榜样啊。
我接触Linux都两年多了,除了工作上的事外,还真没写过像样的程序。
向楼主致敬,向楼主学习!

热点排行