#include
#include
#include
// 用于调整蛇移动方向,防止蛇移动不合理
#define UP 1
#define DOWN -1
#define LEFT -2
#define RIGHT 2
struct Snake{
int hang; //行
int lie; //列
struct Snake *next; //节点指针
};
struct Snake *head = NULL; //头节点
struct Snake *wei = NULL; //尾巴节点
int direction; // 方向
int key; // 接受方向键的指令
struct Snake food; //控制食物
int cnt =0; //进食分数
1.初始化界面
void initcurses()
{
initscr();
keypad(stdscr,1);
noecho();
}
2.相关函数使用
3.使用到curses中的宏建
//该地图是20行20列地图
void Map()
{
int hang;
int lie;
move(0,0); //刷新地图,覆盖旧地图
for(hang=0 ; hang<20 ; hang++)
{
if(hang==0)
{
for(lie=0 ;lie<20;lie++)
{
printw("--");
}
printw("\n");
}
else if(hang>0 && hang <19)
{
for(lie=0 ;lie<=20;lie++)
{
if(lie ==0 || lie==20)
{
printw("|");
}
else if(calcSnake(hang,lie)) //生成蛇的身体
{
printw("[]");
}
else if(Eatfood(hang,lie) ) //生成蛇的食物
{
printw("$$");
}
else{
printw(" ");
}
}
printw("\n");
}
else
{
for(lie=0 ; lie<20 ; lie++)
{
printw("--");
}
// 调试信息如下,可以设计添加其他
printw("\n");
printw("The Map is by LiuZheng sir make\n"); // 地图制作者
printw("The food hang = %d,food lie = %d\n",food.hang,food.lie); //记录蛇食物坐标
printw("Alway eat food score = %d\n",cnt); // 记录蛇吃了多少食物
}
}
}
//用于在initsnake中指定方向生成贪吃蛇身体
int calcSnake(int h,int l)
{
struct Snake *p;
p = head;
while(p != NULL)
{
if(p->hang ==h &&p->lie == l)
{
return 1;
}
p = p->next;
}
return 0;
}
//贪吃蛇身体初始化
void initsnake()
{
struct Snake *p;
direction = RIGHT; //规定刚开始蛇朝着右方向移动
if(head !=NULL) //用于清除蛇死亡后残留的数据,清理内存
{
p = head;
head = head->next;
free(p);
}
createfood(); //生成食物
head = (struct Snake*)malloc(sizeof(struct Snake));
head->hang = 2;
head->lie = 2;
head->next = NULL;
wei = head;
//生成蛇的身子
AddNode();
AddNode();
}
//贪吃蛇身子节点的添加
void AddNode()
{
struct Snake *new;
new = (struct Snake*)malloc(sizeof(struct Snake));
switch(direction)//控制方向上移动
{
case DOWN:
new->hang = wei->hang+1;
new->lie = wei->lie;
break;
case UP:
new->hang = wei->hang-1;
new->lie = wei->lie;
break;
case LEFT:
new->hang = wei->hang;
new->lie = wei->lie-1;
break;
case RIGHT:
new->hang = wei->hang;
new->lie = wei->lie+1;
break;
}
//让新的节点代替之前的尾巴,成为新的尾巴
new->next = NULL;
wei->next = new;
wei = new;
}
//删除贪吃蛇身体节点
void DeleteNode()
{
struct Snake *p =head;
head = head->next;
free(p);
}
//控制贪吃蛇移动的函数
void moveSnake()
{
AddNode();
if(Eatfood(wei->hang,wei->lie) == 1) //如果吃到食物,就重新生成新的食物
{
createfood();
cnt++; //统计贪吃蛇进食分数情况
}
else
{
DeleteNode();
}
if(ifsnakedeath()) //检查移动中贪吃蛇是否撞墙或者自己吃自己,导致死亡
{
initsnake(); //死亡之后需要重新生成贪吃蛇
cnt=0;
}
}
//查看贪吃蛇是否撞墙死亡 / 自己吃自己
int ifsnakedeath()
{
struct Snake *p =head;
if(wei->hang == 0||wei->lie ==0||wei->hang ==19||wei->lie== 19) //检查撞墙
{
return 1;
}
while(p->next != NULL)
{
if(p->hang == wei->hang && p->lie ==wei->lie) // 检查是否自杀
{
return 1;
}
p = p->next;
}
return 0;
}
//用于确定在随机生成的食物坐标中,在地图上打印该食物
int Eatfood(int h,int l)
{
if(food.hang == h && food.lie ==l)
{
return 1;
}
return 0;
}
void createfood()
{
int x = rand()%20; //使用rand()函数随机生成一个坐标值
int y = rand()%20; //使用rand()函数随机生成一个坐标值
if(x==0 || x==19 || y==0 || y==19) //防止食物生成到地图边缘或者离开地图
{
x = rand()%20;
y = rand()%20;
}
food.hang = x;
food.lie = y;
}
由于需要地图的刷新,贪吃蛇方向的移动和改变、食物的生成,系统一个线程是忙不过来的,因此我们需要引进线程的概念,创建多个线程来分布执行这些命令操作
//创建线程 t1、t2
pthread_t t1;
pthread_t t2;
pthread_create(&t1,NULL,refreshSnake,NULL); //t1进程实现贪吃蛇移动
pthread_create(&t2,NULL,Changedirection,NULL); //t2进程实现贪吃蛇改变方向位置
//用该进程进行贪吃蛇移动
void refreshSnake()
{
while(1)
{
moveSnake();
Map();
refresh(); //刷新界面
usleep(40000); //控制贪吃蛇移动速度,这里是微秒单位
}
}
//防止贪吃蛇位置移动不合理
void Turndirection(int dir)
{
if(abs(direction) != abs(dir))
{
direction = dir;
}
}
void Changedirection()
{
while(1)
{
key = getch();//获取方向键控制贪吃蛇移动指令
switch(key) //发送贪吃蛇方向移动指令
{
case KEY_DOWN: //向上
Turndirection(DOWN);
break;
case KEY_UP: //向下
Turndirection(UP);
break;
case KEY_LEFT: //向左
Turndirection(LEFT);
break;
case KEY_RIGHT: //向右
Turndirection(RIGHT);
break;
}
}
}
int main()
{
pthread_t t1; //建立线程t1
pthread_t t2; //建立线程t2
initcurses();
initsnake();
Map();
pthread_create(&t1,NULL,refreshSnake,NULL);
pthread_create(&t2,NULL,Changedirection,NULL);
while(1); //防止该进程不退出
getch();
endwin();
return 0;
}
#include
#include
#include
#define UP 1
#define DOWN -1
#define LEFT -2
#define RIGHT 2
void initcurses()
{
initscr();
keypad(stdscr,1);
noecho();
}
struct Snake{
int hang;
int lie;
struct Snake *next;
};
struct Snake *head = NULL;
struct Snake *wei = NULL;
int direction;
int key;
struct Snake food;
int cnt =0;
int calcSnake(int h,int l)
{
struct Snake *p;
p = head;
while(p != NULL)
{
if(p->hang ==h &&p->lie == l)
{
return 1;
}
p = p->next;
}
return 0;
}
int Eatfood(int h,int l)
{
if(food.hang == h && food.lie ==l)
{
return 1;
}
return 0;
}
void createfood()
{
int x = rand()%20;
int y = rand()%20;
if(x==0 || x==19 || y==0 || y==19)
{
x = rand()%20;
y = rand()%20;
}
food.hang = x;
food.lie = y;
}
void Map()
{
int hang;
int lie;
move(0,0);
for(hang=0 ; hang<20 ; hang++)
{
if(hang==0)
{
for(lie=0 ;lie<20;lie++)
{
printw("--");
}
printw("\n");
}
else if(hang>0 && hang <19)
{
for(lie=0 ;lie<=20;lie++)
{
if(lie ==0 || lie==20)
{
printw("|");
}
else if(calcSnake(hang,lie))
{
printw("[]");
}
else if(Eatfood(hang,lie) )
{
printw("$$");
}
else{
printw(" ");
}
}
printw("\n");
}
else
{
for(lie=0 ; lie<20 ; lie++)
{
printw("--");
}
printw("\n");
printw("The Map is by LiuZheng sir make\n");
printw("The food hang = %d,food lie = %d\n",food.hang,food.lie);
printw("Alway eat food score = %d\n",cnt);
}
}
}
void AddNode()
{
struct Snake *new;
new = (struct Snake*)malloc(sizeof(struct Snake));
switch(direction)
{
case DOWN:
new->hang = wei->hang+1;
new->lie = wei->lie;
break;
case UP:
new->hang = wei->hang-1;
new->lie = wei->lie;
break;
case LEFT:
new->hang = wei->hang;
new->lie = wei->lie-1;
break;
case RIGHT:
new->hang = wei->hang;
new->lie = wei->lie+1;
break;
}
new->next = NULL;
wei->next = new;
wei = new;
}
void DeleteNode()
{
struct Snake *p =head;
head = head->next;
free(p);
}
void initsnake()
{
struct Snake *p;
direction = RIGHT;
if(head !=NULL)
{
p = head;
head = head->next;
free(p);
}
createfood();
head = (struct Snake*)malloc(sizeof(struct Snake));
head->hang = 2;
head->lie = 2;
head->next = NULL;
wei = head;
AddNode();
AddNode();
}
void moveSnake()
{
AddNode();
if(Eatfood(wei->hang,wei->lie) == 1)
{
createfood();
cnt++;
}
else
{
DeleteNode();
}
if(ifsnakedeath())
{
initsnake();
cnt=0;
}
}
int ifsnakedeath()
{
struct Snake *p =head;
if(wei->hang == 0||wei->lie ==0||wei->hang ==19||wei->lie== 19)
{
return 1;
}
while(p->next != NULL)
{
if(p->hang == wei->hang && p->lie ==wei->lie)
{
return 1;
}
p = p->next;
}
return 0;
}
void refreshSnake()
{
while(1)
{
moveSnake();
Map();
refresh();
usleep(40000);
}
}
void Turndirection(int dir)
{
if(abs(direction) != abs(dir))
{
direction = dir;
}
}
void Changedirection()
{
while(1)
{
key = getch();
switch(key)
{
case KEY_DOWN:
Turndirection(DOWN);
break;
case KEY_UP:
Turndirection(UP);
break;
case KEY_LEFT:
Turndirection(LEFT);
break;
case KEY_RIGHT:
Turndirection(RIGHT);
break;
}
}
}
int main()
{
pthread_t t1;
pthread_t t2;
initcurses();
initsnake();
Map();
pthread_create(&t1,NULL,refreshSnake,NULL);
pthread_create(&t2,NULL,Changedirection,NULL);
while(1);
getch();
endwin();
return 0;
}