贪吃蛇 Linux C语言 第二次小练手

/**********************
* 项目名称:贪吃蛇
*    项目要求:在GCC 下 完成贪吃蛇的游戏
*    项目采用的知识:
*    1.链表(贪吃蛇,食物)
*    2.构图(边框,贪吃蛇,食物,背景)
*    3.随机数(食物)
*    4.判断条件(蛇不能回头,不能碰尾巴,不能碰边框)
*    5.积分
**********************/


#include<stdio.h>
#include<assert.h>
#include<time.h>
#include<stdlib.h>
#include <unistd.h>  
#include <termios.h>
#include <fcntl.h>  


int map[30][60] = {'0'};   //0 背景 1 蛇 2 食物 3 边框
int direct = 3;            //1 上 2下 3 左 4 右
int score = 0 ;            //分数
int level = 1 ;            //游戏速度级别
      
typedef struct snake{
int x;
int y;
struct snake *next;
}Snake;


typedef struct food{
int x;
int y;
}Food;


Food f;
//初始化地图
void print_map(int map[30][60]);


//打印所有信息
void print_all(int map[30][60]);


//创建头节点
Snake *creat_head();


//创建蛇链表
Snake *init_snake(Snake *head);


//画蛇
void draw_snake(Snake *head);


//随即食物产生
void food_get();




//四个方向移动坐标
void move_left(Snake *head);
void move_right(Snake *head);
void move_up(Snake *head);
void move_down(Snake *head);


//及时响应输入
void get_key();


//蛇身的控制函数
void snake_move(Snake *head,int direct);


//检验食物是否被吃掉
int check_food();


//吃一口食物增加身体
void add_snake(Snake *head);


//检验是否碰到墙壁
int wall_check();


//检验是否碰到身体
int body_check(Snake *head);


//游戏速度控制
void speed_level();


void game_snake(void)
{
srand(time(NULL));
Snake *head = creat_head();
print_map(map);                                          //初始化地图
init_snake(head);                                        //初始化蛇
draw_snake(head);                                        //画出来   (也可以不画出来)
print_all(map);
food_get();                                              //随即给食物 (不可以去掉,因为需要判断食物是否吃掉)
while(1){
speed_level();
get_key();
system("clear");
snake_move(head,direct);      
printf("\t\t\t简易贪吃蛇\n");                         //view 界面
printf("\t\t\t作者:钱蓓杰\n");
printf("\t\t\t指导老师:汪大佬\n");
printf("\t\t\tw a s d 移动  撞墙或者碰撞身体结束\n");
printf("\t\t\t您的得分 : %d\n",score);
printf("\t\t\t当前的游戏级别是 %d\n",level);
print_all(map);
if(check_food()){                                               
food_get();
add_snake(head);
score += 10;
level++;
}
if(wall_check() || body_check(head)){                    
printf("game over\n");
break;
}
get_key();
}
printf("游戏结束,您的游戏分数为 %d\n",score);
Snake *p = head;
Snake *q = NULL;
while(p->next != head){
q = p->next;
p->next = p->next->next;
free(q);
}
free(head);
}


//游戏速度控制
void speed_level()
{
switch(level){
case 1: usleep(1000000);
break;
case 2: usleep(1000000/2);
break;
case 3: usleep(1000000/4);
break;
case 4: usleep(1000000/8);
break;
case 5: usleep(1000000/16);
break;
case 6: usleep(1000000/32);
break;
default:
break;
}
}
//检测是否碰到蛇身体
int body_check(Snake *head)
{
assert(head);
Snake *p = head->next;
p = p->next;
while(p != head){
if(p->x == head->next->x && p->y == head->next->y){
return 1;
}
p = p->next;
}
return 0;
}
//检查是否碰到边框
int wall_check()
{
int i = 0;
for(i = 0;i < 30;i++){
if(map[i][0] != 3 || map[i][59] != 3){
return 1;
}
}
for(i = 0;i <60 ;i++){
if(map[0][i] != 3 || map[29][i] != 3){
return 1;
}
}
return 0;
}
//检查是否吃到食物
int check_food()
{
if(map[f.x][f.y] != 2){
return 1;
}else{
return 0;
}
}


//吃到食物后添加蛇尾巴    //蛇头比较敏感,修改为蛇尾
void add_snake(Snake *head)
{
assert(head);
Snake *tail = head->next;
while(tail->next != head){
tail = tail->next;
}
//Snake * p = NULL ;
Snake *new = (Snake *)calloc(1,sizeof(Snake));
if(direct == 1){
new->x = tail->x - 1;
new->y = tail->y;
}else if(direct == 2){
new->x = tail->x + 1;
new->y = tail->y;
}else if(direct == 3){
new->x = tail->x;
new->y = tail->y + 1;
}else {
new->x = tail->x;
new->y = tail->y - 1;
}
new->next = head;
tail->next = new;  
             
}
//蛇身体移动
void snake_move(Snake *head,int direct)
{
assert(head);
switch(direct){
case 1:
move_up(head);draw_snake(head);
break;
case 2:
move_down(head);draw_snake(head);  
break;
case 3:
move_left(head);draw_snake(head);
break;
case 4:
move_right(head);draw_snake(head);
break;
default :
break;
}
}


//左移动     //横坐标-1,移动一次
void move_left(Snake *head)
{
assert(head);
Snake *tail = head->next;
Snake * p = NULL ;
Snake *new = (Snake *)calloc(1,sizeof(Snake));
new->x = tail->x;
new->y = tail->y - 1;
new->next = tail;
head->next = new;                 //添加头节点

while(tail->next->next != head){
tail = tail->next;
}
map[tail->next->x][tail->next->y] = 0;
p = tail->next;
tail->next = tail->next->next;   //释放尾节点
free(p);
p = NULL;
}
//右移动     //横坐标+1,移动一次
void move_right(Snake *head)
{
assert(head);
Snake *tail = head->next;
Snake * p = NULL ;
Snake *new = (Snake *)calloc(1,sizeof(Snake));
new->x = tail->x;
new->y = tail->y + 1;
new->next = tail;
head->next = new;                 //添加头节点

while(tail->next->next != head){
tail = tail->next;
}
map[tail->next->x][tail->next->y] = 0;
p = tail->next;
tail->next = tail->next->next;   //释放尾节点
free(p);
p = NULL;
}
//上移动     //纵坐标+1,移动一次
void move_up(Snake *head)
{
assert(head);
Snake *tail = head->next;
Snake * p = NULL ;
Snake *new = (Snake *)calloc(1,sizeof(Snake));
new->x = tail->x - 1;
new->y = tail->y;
new->next = tail;
head->next = new;                 //添加头节点

while(tail->next->next != head){
tail = tail->next;
}
map[tail->next->x][tail->next->y] = 0;
p = tail->next;
tail->next = tail->next->next;   //释放尾节点
free(p);
p = NULL;
}
//下移动     //纵坐标-1,移动一次
void move_down(Snake *head)
{
assert(head);
Snake *tail = head->next;
Snake * p = NULL ;
Snake *new = (Snake *)calloc(1,sizeof(Snake));
new->x = tail->x + 1;
new->y = tail->y;
new->next = tail;
head->next = new;                 //添加头节点

while(tail->next->next != head){
tail = tail->next;
}
map[tail->next->x][tail->next->y] = 0;
p = tail->next;
tail->next = tail->next->next;   //释放尾节点
free(p);
p = NULL;
}




//随即食物产生
void food_get()
{
int x = 0;
int y = 0;
while(1){
x = rand() % 29;
y = rand() % 59;
f.x = x;
f.y = y;
if(map[x][y] == 1 || map[x][y] == 3){
continue;
}else{
map[x][y] = 2;
break;
}
}
}
//创建头节点
Snake *creat_head()
{
Snake *head = (Snake *)calloc(1,sizeof(Snake));
assert(head);
head->next = head;
return head;



//创建蛇链表
Snake *init_snake(Snake *head)
{
assert(head);
int i = 0;
Snake *tail = (Snake *)calloc(1,sizeof(Snake));
head->next = tail;
tail->next = head;
tail->x = 15;
tail->y = 15;
for(i = 0;i<5;i++){
Snake *new = (Snake *)calloc(1,sizeof(Snake));
new->x = tail->x-1;
new->y = tail->y;
tail->next = new;
new->next = head;
tail = new ;
}
return head;
}


//画蛇
void draw_snake(Snake *head)
{
assert(head);
Snake *p = head->next;
while(p != head){
map[p->x][p->y] = 1;
p = p->next; 
}
}


//初始化地图
void print_map(int map[30][60])
{
int i = 0;
int j = 0;
for(i = 0;i < 30;i++){
map[i][0] = 3;
map[i][59] = 3;
}
for(j = 0;j < 60;j++){
map[0][j] = 3;
map[29][j] = 3;
}

}


//打印所有信息
void print_all(int map[30][60])
{
int i = 0;
int j = 0;
for(i = 0;i < 30;i++){
for(j = 0 ;j < 60;j++){
if(map[i][j] == 0){
printf(" ");
}else if(map[i][j] == 3){
printf("#");
}else if(map[i][j] == 1){ 
printf("*");
}else if(map[i][j] == 2){
printf("&");
}
}
printf("\n");
}
}


int kbhit(void)  
{  
struct termios oldt, newt;  
int ch = 0;  
int oldf = 0;  
tcgetattr(STDIN_FILENO, &oldt);  
newt = oldt;  
newt.c_lflag &= ~(ICANON | ECHO);  
tcsetattr(STDIN_FILENO, TCSANOW, &newt);  
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);  
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);  
ch = getchar();  
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);  
fcntl(STDIN_FILENO, F_SETFL, oldf);  
if(ch != EOF)  
{  
ungetc(ch, stdin);  
return 1;  
}  
return 0;  
}  


void get_key() 
{
char key = '\0';
if(kbhit()){
key = getchar();
}
switch (key) {
case 'w'://用户按 上 键
if(direct != 2){
direct = 1;
}
break;
case 's'://用户按 下 键
if (direct != 1){
direct = 2;
}
break;
case 'a'://用户按 左 键
if (direct != 4){
direct = 3;
}
break;
case 'd'://用户按 右 键
if (direct != 3)
direct = 4;
break;
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值