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
一两天做的,有点匆忙,不足欢迎批评指正