龙芯俱乐部开源技术社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 4482|回复: 6

贪吃蛇源代码

[复制链接]

52

主题

125

帖子

4661

积分

论坛元老

Rank: 8Rank: 8

积分
4661
发表于 2017-10-13 01:42:04 | 显示全部楼层 |阅读模式
    #include <stdio.h>   
    #include <stdlib.h>   
    #include <curses.h>   
    #include <signal.h>   
    #include <sys/time.h>   
    #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<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);   
    }   

------------------------------------------------------------------
xiongyao@xiongyao-Lenovo:~$ gedit snake.c
xiongyao@xiongyao-Lenovo:~$ gcc snake.c -lcurses -o snake  
xiongyao@xiongyao-Lenovo:~$ ./snake

5

主题

33

帖子

1789

积分

金牌会员

Rank: 6Rank: 6

积分
1789
发表于 2017-10-13 09:44:13 | 显示全部楼层
这个感觉不错。
既然发布源码了?为什么不直接上传附件呢? 比如编译好的bin文件。

25

主题

218

帖子

10万

积分

论坛元老

Rank: 8Rank: 8

积分
101939
发表于 2017-10-14 08:42:16 | 显示全部楼层
本帖最后由 xieyug2012 于 2017-10-14 08:50 编辑

既然是源码,就用上传代码的功能把源码贴上来,可以另外加分的 !!!

25

主题

218

帖子

10万

积分

论坛元老

Rank: 8Rank: 8

积分
101939
发表于 2017-10-14 08:48:55 | 显示全部楼层
本帖最后由 xieyug2012 于 2017-10-14 08:50 编辑

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

0

主题

22

帖子

953

积分

高级会员

Rank: 4

积分
953
发表于 2017-10-14 08:57:24 | 显示全部楼层
支持支持

84

主题

465

帖子

44万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
440441
发表于 2017-10-14 09:47:46 | 显示全部楼层
可以在智龙上运行吗?

26

主题

150

帖子

4038

积分

超级版主

Rank: 8Rank: 8

积分
4038
发表于 2017-10-26 09:50:37 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|龙芯俱乐部开源技术社区

GMT+8, 2024-4-20 14:59 , Processed in 0.114860 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表