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   2022去植发  阅读(391)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示