1.1头文件

点击查看代码
#include<stdio.h>
#include<curses.h>  //包含curses插件
#include<stdlib.h>  //srand
#include<unistd.h>  //sleep头文件
#include<stdbool.h>  //bool条件判断
#include <pthread.h> //线程头文件
#include <time.h> //时间头文件

define WIDHT 20 //地图长度

define HEIGHT 20 //地图宽度

define MIN 0 //最小值宏定义

define UP 1 //蛇的方向上

define DOWN -1 //下

define LEFT 2 //左

define RIGHT -2 //右

//定义一个结构体snake_t
typedef struct snake
{
int row;
int col;
struct snake *next;
}snake_t;

typedef struct food
{
int row;
int col;
}food_t;

snake_t *snake_head = NULL; //蛇的头指针
snake_t *snake_tail= NULL; //蛇的尾巴
food_t food; //初始化一个食物
int dir; //方向 //捕获的方向
int key; //按键的值

void add_snake_body(); //添加一个蛇的身子函数
void food_init(); //初始化食物
void start_init(); //开始初始化
snake_t* create_snake(int row, int col); //创建一条蛇,row行,col列
int has_snake_body(int row, int col); //判断当前坐标是否有蛇的身子
void map_init(int witdh, int height); //刷新地图
void initscr_func(); //初始化scr函数
void head_delete_snake_body(); //删除蛇身子
void snake_move(); //蛇的移动函数
bool snake_need_init(); //判断蛇是否撞墙,或者咬到自己,需要重开
void turn_abs(int dirction); //取绝对值函数
int food_location(int row,int col); //判断当前坐标是否有食物
bool snake_bite_itself(); //判断蛇是否咬到了自己
void initscr_func(){
initscr();
keypad(stdscr,true);
noecho(); //不回显
}

//贪吃蛇创建
snake_t* create_snake(int row, int col){
snake_head = (snake_t*)malloc(sizeof(snake_t)); //蛇头分配内存
snake_head->row = row;
snake_head->col = col;
snake_head->next = NULL;
snake_tail=snake_head;
add_snake_body(); //添加蛇身体
add_snake_body();
dir=RIGHT; //初始方向为右
return snake_head;

}

void start_init(){
initscr_func();
create_snake(2,3); //创建蛇
food_init(); //初始化食物
map_init(WIDHT,HEIGHT);
refresh(); //刷新窗口

}

void food_init(){
srand(time(NULL));
food.row=rand()%(HEIGHT-2)+1;
food.col=rand()%(WIDHT-1)+1;
}

//判断是否蛇吃到了食物
int has_food(int row,int col){
if(snake_tail->rowrow&&snake_tail->colcol){
return 1;
}
else{
return 0;
}
}

//判断食物位置
int food_location(int row,int col){
if (rowfood.row&&colfood.col){
return 1;
}
else{
return 0;
}

}

//判断蛇是否撞到了自己
bool snake_bite_itself(){
snake_t *p=snake_tail;
snake_t *q=snake_head;
while(q->next!=NULL){
if(p->rowq->row&&p->colq->col){
return true;
}
q=q->next;
}

}
//添加贪吃蛇身体
void add_snake_body(){
snake_t snake_body = (snake_t)malloc(sizeof(snake_t)); //蛇身体分配内存
while (snake_tail->next!=NULL){
snake_tail=snake_tail->next; //找到尾节点
}
snake_body->next = NULL; //蛇身体的下一个节点为空

    //根据按键不同,蛇身体的位置不同
    switch (dir)
    {
        case UP:
             snake_body->row = snake_tail->row - 1;
             snake_body->col = snake_tail->col;
             break;
        case DOWN:
             snake_body->row = snake_tail->row + 1;
             snake_body->col = snake_tail->col;
             break;
        case LEFT:
             snake_body->row = snake_tail->row;
             snake_body->col = snake_tail->col - 1;
             break;
        case RIGHT:
             snake_body->row = snake_tail->row;
             snake_body->col = snake_tail->col + 1;
             break;
        default:
             break;
    }

    snake_tail->next = snake_body;  //尾节点的下一个节点指向蛇身体
    snake_tail=snake_body;  //更新尾节点

}

//delete snake body(head delete)
void head_delete_snake_body(){
snake_t *p;
if(snake_head!=NULL){
p=snake_head; //保存头节点
snake_head=snake_head->next; //头节点指向下一个节点
}
free(p); //释放头节点内存
}
//judge has snake body
int has_snake_body(int row, int col){
snake_t *p = snake_head;
while(p!=NULL){
if(p->rowrow&&p->colcol){
return 1;
}
p = p->next;
}
return 0;
}

bool snake_need_init(){
// if(snake_head->row0||snake_head->col0||snake_head->row20||snake_head->col20){
// return true;
// }
// else
if (snake_tail->rowMIN||snake_tail->colMIN||snake_tail->rowHEIGHT-1||snake_tail->colHEIGHT-1){
return true;
}

else{
    return false;
}

}

//right move
void snake_move(){

//判读是否需要重新开始游戏
if (snake_need_init()==true || snake_bite_itself()==true){
    snake_t *old_sanke_head =NULL;

    //游戏初始前,回收上一次蛇身子
    while(snake_head!=NULL){
    old_sanke_head = snake_head;
    snake_head = snake_head->next;
    free(old_sanke_head); 
    }
    
    create_snake(6,6); //创建蛇
    food.col=2;
    food.row=2;

    map_init(WIDHT,HEIGHT);
}

//不需要重新开始游戏
else{
    add_snake_body(); //添加蛇身体
    //吃到了食物
    if (has_food(food.row,food.col)){
        food_init(); //初始化食物
    }
    
    //没吃到食物
    else{
        head_delete_snake_body(); //删除蛇结点
    }
    
    
    map_init(WIDHT,WIDHT);
    refresh(); //刷新窗口  
}

}
//初始化地图
void map_init(int witdh, int height)
{
int row,col;

move(MIN,MIN); //复位光标

for (row = 0; row < witdh; row++){
    if(row==0){
        for (col = 0; col < height; col++){
            printw("--");

        }
        printw("\n");
    }
           
    else if(row>0&&row<witdh-1){
         for (col = 0; col <= height; col++){
                 if (col==0||col==height)
                 {
                     printw("|");
                 }
                 //判断食物位置,如果有则打印出来
                 else if(food_location(row,col)){
                    printw("##");
                 }

                 else if(has_snake_body(row,col)){
                   printw("[]");
                 }
                 else{
                     printw("  ");
                 }
             }
             printw("\n"); 
    }

    if(row==witdh-1){
         for (col = 0; col < height; col++){
    printw("--");
    }
    printw("\n");
    printw("Make buy guo,Key val:%d  food location:  %d,%d \n",key,food.row,food.col);
    
    }

}
refresh(); //刷新窗口  

}

//取绝对值函数
void turn_abs(int dirction){
if(abs(dir)!=abs(dirction)){
dir=dirction;
}
}

//按键处理函数
void key_handle(){
key = getch();
switch (key)
{
case KEY_UP:
turn_abs(UP);
break;

    case KEY_DOWN: 
    turn_abs(DOWN);
    break;
    
    case KEY_LEFT: 
    turn_abs(LEFT);
    break;

    case KEY_RIGHT: 
    turn_abs(RIGHT);
    break;

    default:
    break;
}

}

void *thread_func_1(void *arg){
while (1){
snake_move();
map_init(WIDHT,HEIGHT); //刷新地图
refresh(); //刷新窗口
usleep(200000); //延时100ms
}

}

void *thread_func_2(void *arg){
while (1){
key_handle(); //处理按键
}

}

//main
int main(int argc, char *argv[])
{
pthread_t thread1,thread2;
start_init();
pthread_create(&thread1,NULL,thread_func_1,NULL);
pthread_create(&thread2,NULL,thread_func_2,NULL);
while (1)
{

}

getch(); //等待用户输入   
endwin(); //关闭窗口

return 0;

}

编译环境,gcc交叉编译,ubantu18.04
使用命令: gcc -Wall -o 你的文件名 你的文件名.c -lcurses -lpthread
运行: ./curses
一两天做的,有点匆忙,不足欢迎批评指正

Posted on 2024-07-14 13:19  2022去植发  阅读(541)  评论(0)    收藏  举报