贪吃蛇游戏

#include<curses.h>
#include<stdlib.h>
#include <pthread.h>

#define UP         1//上
#define DOWN     -1//下
#define LEFT     2//左
#define RIGHT     -2//右

struct Snake
{
    int hang;
    int lie;
    struct Snake *next;
};

int key;
int dir;
struct Snake *head=NULL;
struct Snake *tail=NULL;
struct Snake food;

void initFood(int a)
{
    struct Snake *p=&food;
    
    
    while(a!=0){
    struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
    new->next=NULL;
    p->next=new;
    
    int x = rand()%40;
    int y = rand()%40;
    new->hang=x;
    new->lie=y;
    
    p=p->next;
    a--;
    }
    
}

void initNcurse()
{
    initscr();
    keypad(stdscr,1);//接受功能性按键,1表示接受
    noecho();
}

int hasSnakeNode(int i,int j)  //判断蛇的节点在哪些位置
{
    struct Snake *p=head;
    
    while(p!=NULL)
    {
        if(p->hang == i && p->lie == j)
        {return 1;}
        p=p->next;
    }
    return 0;
}

int hasFood(int i,int j)  //判断食物的节点在哪些位置
{
    struct Snake *p=&food;
    while(p!=NULL){

        if(p->hang == i && p->lie == j)
        {return 1;}
        p=p->next;
    }
    
    return 0;
}


void gamepic()  //pic:编程控制器,贪吃蛇地图20行20列
{
    int hang;
    int lie;
    
    move(0,0);//每次使用此函数,将光标移到0,0处
    for(hang=0;hang<40;hang++)
    {
        if(hang==0)
        {
            for(lie=0;lie<40;lie++)
            {
                printw("--");
            }
            printw("\n");
        }
        
        
        if(hang>=0&&hang<=39)
        {    
            for(lie=0;lie<42;lie++)
            {
                if(lie==0||lie==41)
                {
                    printw("|");
                }
                else if(hasSnakeNode(hang,lie))
                {printw("[]");}
                else if(hasFood(hang,lie)){printw("##");}
                else {printw("  ");}
            }
            printw("\n");
        }
        if(hang==39)
        {
            
            for(lie=0;lie<60;lie++)
            {
                printw("--");
            }
            printw("\n");
            printw("By zhangliao,key=%d,food.hang=%d,food.lie=%d\n",key,food.hang,food.lie);
            
        }
        
    }
}

void addNode()//在各个方向的蛇尾巴tail加新节点
{
    struct Snake *new=(struct Snake*)malloc(sizeof(struct Snake));
    
    new->next=NULL;
    
    switch(dir)
    {
        case UP:
            new->hang=tail->hang-1;
            new->lie=tail->lie;
            break;
        case DOWN:
            new->hang=tail->hang+1;
            new->lie=tail->lie;
            break;
        case LEFT:
            new->hang=tail->hang;
            new->lie=tail->lie-1;
            break;
        case RIGHT:
            new->hang=tail->hang;
            new->lie=tail->lie+1;    
            break;
    }
    
    tail->next=new;
    tail=new;
}


void initSnake()    //动态设置头节点,并调用addNode来加新节点(尾插法)
{
    struct Snake *p;
    struct Snake *pp;
    dir=RIGHT;
    
    while(head!=NULL)
    {
        p=head;
        head=head->next;
        free(p);
    }
    
    int x = rand()%40;
    int y = rand()%40;
    food.hang=x;
    food.lie=y;
    
    int a=4;
    initFood(a);
    
    
    head=(struct Snake *)malloc(sizeof(struct Snake));
    head->hang=1;
    head->lie=1;
    head->next=NULL;
    
    tail=head;
    
    addNode();
    addNode();
    addNode();
    addNode();
    
}

void deleNode()    //删除蛇头节点
{
    struct Snake *p;
    p=head;
    head=head->next;
    free(p);
}

int ifSnakeDir()
{
    struct Snake *p;
    p=head;
    
    if(tail->hang<0||tail->hang>39||tail->lie==0||tail->lie>39)//撞墙死
    {return 1;}
    
    while(p->next!=NULL){
        if(p->hang == tail->hang && p->lie == tail->lie)//装自己死
        {return 1;}
        p=p->next;
    }
    return 0;
}


void moveSnake()    //蛇身子的移动,删除头节点,加一个尾节点,碰到墙重新设置蛇的最初
{
    addNode();
    if(hasFood(tail->hang,tail->lie))
    {
        int a=5;
        initFood(a);
    }
    else{
        deleNode();
    }
    if(ifSnakeDir())
        {
            initSnake();
        }

}

void turn(int dira)//abs是绝对值,新旧绝对值不等才换dir
{
    if(abs(dir)!=abs(dira))
    {
        dir=dira;
    }
}

void *changeDir()//按键输入上下左右
{

    while(1)
    {
        key=getch();
        switch(key)
        {
            case KEY_DOWN:
                turn(DOWN);
                break;
            case KEY_UP:
                turn(UP);
                break;
            case KEY_LEFT:
                turn(LEFT);
                break;
            case KEY_RIGHT:
                turn(RIGHT);
                break;    
        }
    }
}

void *refrsh()//不间断的移动,不断刷新和显示
    {
        while(1)
        {    moveSnake();
            gamepic();
            refresh();            //刷新一次界面
            usleep(100000);     //蛇每100毫秒走一次
        }        
    }


int main()
{        
    pthread_t t1;
    pthread_t t2;
    
    
    initNcurse();
    initSnake();
    
    gamepic();
    pthread_create(&t1,NULL,refrsh,NULL);//双线程同时进行
    pthread_create(&t2,NULL,changeDir,NULL);
    
    while(1);
    getch();
    endwin;    
    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值