当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 4 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 基于curses库的在纯命令行下运行的贪食蛇
帖子发表于 : 2010-01-16 16:38 

注册: 2010-01-16 16:20
帖子: 16
送出感谢: 0 次
接收感谢: 0 次
本人接触linux不久,为了研究gcc和linux就决定做个程序练手。这个程序用c++写成,有Makefile,对和我一样的小菜鸟们有点参考价值。
代码下载和截图在附件里。
注意:源码编译需要curses库。

源码:
Makefile
代码:
#Makefile of the snake

objects = main.o h_Snake.o

curses : $(objects)
    g++ -o curses $(objects) -lcurses
main.o : h_Snake.h
    g++ -c main.cpp
h_Snake.o : h_Snake.h
    g++ -c h_Snake.cpp
   
.PHONY : clean

clean :
    rm curses $(objects)


main.c
代码:
#include <curses.h>
#include <unistd.h>
#include "h_Snake.h"

int main()
{
    long Delay=100000;
    h_Snake* m_pSnake;
    m_pSnake=new h_Snake;
    initscr();
    nodelay(stdscr,true);
    while(1)
    {
        unsigned char k;
        k=getch();
        if(!m_pSnake->IfCrush)
        {
            switch(k)
            {
                case 27:
                    endwin();
                    return 0;
                case 'n':
                    Delay+=1000;
                    break;
                case 'm':
                    if(Delay>=20000) Delay-=1000;
                    break;
                case 'w':
                    if(m_pSnake->Dir!=DOWN) m_pSnake->Dir=UP;
                    break;
                case 's':
                    if(m_pSnake->Dir!=UP) m_pSnake->Dir=DOWN;
                    break;
                case 'a':
                    if(m_pSnake->Dir!=RIGHT) m_pSnake->Dir=LEFT;
                    break;
                case 'd':
                    if(m_pSnake->Dir!=LEFT) m_pSnake->Dir=RIGHT;
                    break;
                default:
                    break;
            }
            erase();
            m_pSnake->Update();
            usleep(Delay);
            refresh();
        }
        else
        {
            erase();
            box(stdscr, ACS_VLINE, ACS_HLINE);
            move(LINES/2, COLS/2-5); /*move the cursor to the center*/
            waddstr(stdscr, "Game Over!");
            move(LINES/2+1, COLS/2-10);
            waddstr(stdscr, "Press R to restart");
            move(LINES-1, COLS-1);
            switch(k)
            {
                case 'r':
                    m_pSnake->Reset();
                    break;
                case 27:
                    endwin();
                    return 0;
                    break;
                default:
                    break;
            }
            usleep(Delay);
        }
       
    }
    endwin();
}

h_Snake.h:
代码:
#include <curses.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

enum Direction {UP,DOWN,RIGHT,LEFT};
enum Result {EAT,NORMAL,CRUSH};

class h_Point
{
    public:
        h_Point(void);
        ~h_Point(void);
        int x;
        int y;
};

class h_Snake
{
    h_Point m_Snake[1000];
    h_Point m_Food;
    int Length;
    public:
        h_Snake(void);
        ~h_Snake(void);
        void Update();
        Direction Dir;
        void Reset();
        bool IfCrush;
    private:
        void Draw();
        Result IfEat();
        void CreatFood();
};


h_Snake.cpp:
代码:
#include "h_Snake.h"

h_Snake::h_Snake(void)
{
    srand((int)time(0));
    Reset();
}

void h_Snake::Reset()
{
    Length=5;
    for(int i=0;i<=4;++i)
    {
        m_Snake[i].x=10-i;
        m_Snake[i].y=10;
    }
    Dir=RIGHT;
    m_Food.x=20;
    m_Food.y=10;
    IfCrush=0;
}

h_Snake::~h_Snake(void)
{
}

h_Point::h_Point(void)
{
}

h_Point::~h_Point(void)
{
}

void h_Snake::Update()
{
    Result R;
    R=IfEat();
    if(R==CRUSH)
    {
        IfCrush=1;
    }
    else if(R==EAT)
    {
        ++Length;
        h_Point lastP;
        lastP.x=m_Snake[0].x;
        lastP.y=m_Snake[0].y;
        for(int i=1;i<=Length-1;++i)
        {
            h_Point lastPx;
            lastPx.x=m_Snake[i].x;
            lastPx.y=m_Snake[i].y;
            m_Snake[i].y=lastP.y;
            m_Snake[i].x=lastP.x;
            lastP.x=lastPx.x;
            lastP.y=lastPx.y;
        }
        m_Snake[0].x=m_Food.x;
        m_Snake[0].y=m_Food.y;
        this->CreatFood();
    }
    else if(R==NORMAL)
    {
        h_Point lastP;
        lastP.x=m_Snake[0].x;
        lastP.y=m_Snake[0].y;
        for(int i=1;i<=Length-1;++i)
        {
            h_Point lastPx;
            lastPx.x=m_Snake[i].x;
            lastPx.y=m_Snake[i].y;
            m_Snake[i].y=lastP.y;
            m_Snake[i].x=lastP.x;
            lastP.x=lastPx.x;
            lastP.y=lastPx.y;
        }
        switch(Dir)
        {
            case UP:
                m_Snake[0].y-=1;
                break;
            case DOWN:
                m_Snake[0].y+=1;
                break;
            case LEFT:
                m_Snake[0].x-=1;
                break;
            case RIGHT:
                m_Snake[0].x+=1;
                break;
            default:
                break;   
        }
        if(m_Food.x>=COLS||m_Food.y>=LINES) this->CreatFood();
    }
    if(m_Snake[0].y>=LINES-1) m_Snake[0].y=1;
    if(m_Snake[0].y<=0) m_Snake[0].y=LINES-2;
    if(m_Snake[0].x>=COLS-1) m_Snake[0].x=1;
    if(m_Snake[0].x<=0) m_Snake[0].x=COLS-2;
    this->Draw();
}

void h_Snake::Draw()
{
    box(stdscr, ACS_VLINE, ACS_HLINE);
    mvprintw(1, 1, "L:%d C:%d Score:%d",LINES, COLS,Length-5) ;
    mvaddch(m_Food.y,m_Food.x, 'o');
    for(int i=0;i<=Length-1;++i) mvaddch(m_Snake[i].y,m_Snake[i].x, '0');
    move(LINES-1, COLS-1);
}

Result h_Snake::IfEat()
{
    switch(Dir)
        {
            case UP:
                for(int i=1;i<=Length-1;++i)
                {
                    if(m_Snake[0].y-1==m_Snake[i].y&&m_Snake[0].x==m_Snake[i].x)
                        return CRUSH;
                }
                if(m_Snake[0].y-1==m_Food.y&&m_Snake[0].x==m_Food.x) return EAT;
                else return NORMAL;
                break;
            case DOWN:
                for(int i=1;i<=Length-1;++i)
                {
                    if(m_Snake[0].y+1==m_Snake[i].y&&m_Snake[0].x==m_Snake[i].x)
                        return CRUSH;
                }
                if(m_Snake[0].y+1==m_Food.y&&m_Snake[0].x==m_Food.x) return EAT;
                else return NORMAL;
                break;
            case LEFT:
                for(int i=1;i<=Length-1;++i)
                {
                    if(m_Snake[0].y==m_Snake[i].y&&m_Snake[0].x-1==m_Snake[i].x)
                        return CRUSH;
                }
                if(m_Snake[0].y==m_Food.y&&m_Snake[0].x-1==m_Food.x) return EAT;
                else return NORMAL;
                break;
            case RIGHT:
                for(int i=1;i<=Length-1;++i)
                {
                    if(m_Snake[0].y==m_Snake[i].y&&m_Snake[0].x+1==m_Snake[i].x)
                        return CRUSH;
                }
                if(m_Snake[0].y==m_Food.y&&m_Snake[0].x+1==m_Food.x) return EAT;
                else return NORMAL;
                break;
            default:
                return NORMAL;
                break;   
        }
    return NORMAL;
}

void h_Snake::CreatFood()
{
    m_Food.x=(rand()%(COLS-2))+1;
    m_Food.y=(rand()%(LINES-2))+1;
    for(int i=0;i<=Length-1;++i)
    {
        while(m_Food.x==m_Snake[i].x||m_Food.y==m_Snake[i].y)
        {
            m_Food.x=(rand()%(COLS-2))+1;
            m_Food.y=(rand()%(LINES-2))+1;
        }
    }
}


附件:
文件注释: 源码
curses.tar.gz [8.92 KiB]
被下载 37 次

附件:
文件注释: 截图
Screenshot.png
Screenshot.png [ 298.74 KiB | 被浏览 690 次 ]


附件:
文件注释: 截图
Screenshot-1.png
Screenshot-1.png [ 292.43 KiB | 被浏览 690 次 ]


附件:
文件注释: 纯命令行下的
IMG_0216.JPG
IMG_0216.JPG [ 1.12 MiB | 被浏览 690 次 ]


附件:
文件注释: 纯命令行下的
IMG_0220.JPG
IMG_0220.JPG [ 1.31 MiB | 被浏览 690 次 ]



页首
 用户资料  
 
2 楼 
 文章标题 : Re: 基于curses库的在纯命令行下运行的贪食蛇
帖子发表于 : 2010-01-16 16:44 

注册: 2010-01-16 16:20
帖子: 16
送出感谢: 0 次
接收感谢: 0 次
w a s d控制方向,n m 可以调节小蛇的速度~ :em01
把 curses文件丢进终端直接运行


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 基于curses库的在纯命令行下运行的贪食蛇
帖子发表于 : 2010-07-16 18:15 
头像

注册: 2009-02-25 17:14
帖子: 107
地址: http://hi.baidu.com/jinzhanshi/
送出感谢: 1
接收感谢: 1
图形桌面的情况下,有没有让维护人员转移注意、放松大脑、消耗等待时间的小游戏?

谢谢!!!
哈哈,谢啦


_________________
黛玉道:“宝姐姐和你好你怎么样?宝姐姐不和你好你怎么样?宝姐姐前儿和你好,如今不和你好你怎么样?今儿和你好,后来不和你好你怎么样?你和他好他偏不和你好你怎么样?你不和他好他偏要和你好你怎么样?”
宝玉呆了半晌,忽然大笑道:“任凭弱水三千,我只取一瓢饮。”


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 基于curses库的在纯命令行下运行的贪食蛇
帖子发表于 : 2010-07-16 18:25 
头像

注册: 2007-02-02 18:14
帖子: 30702
系统: debian sid
送出感谢: 1
接收感谢: 34
收了~


_________________
醉了星星,醉月亮●●●●●The Long Way To Go(*^_^*)


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 4 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译