贪吃蛇
C实现程序(数组实现)// gcc snake.c -lpthread#include <stdio.h>#include <stdlib.h>#include <time.h>#include <signal.h>#include <termios.h>#i
·
C实现程序(数组实现)
// gcc snake.c -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#define KEYCODE_U 0x41 // 向上按键
#define KEYCODE_D 0x42 // 向下按键
#define KEYCODE_L 0x44 // 向左按键
#define KEYCODE_R 0x43 // 向右按键
#define LEN 17
int kfd = 0;
struct termios cooked, raw;
char dir = KEYCODE_U; // 当前蛇的移动方向
// 获取键盘响应:上、下、左、右键
void* get_dir(void *a)
{
while(1)
{
char c;
tcgetattr(kfd, &cooked); // 得到 termios 结构体保存,然后重新配置终端
memcpy(&raw, &cooked, sizeof(struct termios));
raw.c_lflag &=~ (ICANON | ECHO);
raw.c_cc[VEOL] = 1;
raw.c_cc[VEOF] = 2;
tcsetattr(kfd, TCSANOW, &raw);
if(read(kfd, &c, 1) < 0)
{
perror("read():");
exit(-1);
}
tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
dir = c;
}
}
unsigned char map[LEN][LEN] = {0}; // 游戏地图
unsigned char snake[100] = {133}; // 初始化蛇坐标,游戏开始的时候蛇在(8,5)这个位置
unsigned char food = 67; // 食物的坐标,游戏开始的时候在(4,3)这个位置
int len = 1; // 保存蛇的当前长度
unsigned char generate_food();
// 将 数字 转化为坐标
//行 ==> y
//列 ==> x
void num_to_xy(unsigned char num, unsigned char *x, unsigned char *y)
{
*x=num/16;
*y=num%16;
}
// 更新地图数据
void update_map()
{
//边界
int i,j;
for(j=0;j<LEN;j++)
{
map[0][j]='#';
map[LEN-1][j]='#';
}
for(i=1;i<LEN;i++)
{
map[i][0]='#';
map[i][LEN-1]='#';
}
for(i=1;i<LEN-1;i++)
{
for(j=1;j<LEN-1;j++)
{
map[i][j]=' ';
}
}
//蛇
//蛇头
unsigned char x,y;
num_to_xy(snake[0],&x,&y);
map[y][x]='@';
//蛇身
for(i=1;i<50;i++)
{
if(snake[i]>0)
{
num_to_xy(snake[i],&x,&y);
map[y][x]='*';
}
}
//食物
unsigned char x_food,y_food;
num_to_xy(food,&x_food,&y_food);
map[y_food][x_food]='$';
}
// 打印地图
void print_map()
{
//system("clear");
int i;
int j;
for(i=0;i<LEN;i++)
{
for(j=0;j<LEN;j++)
{
printf("%2c",map[i][j]);
}
printf("\n");
}
}
// 生成食物
unsigned char generate_food()
{
srand(time(NULL));
food=rand()%256;
//排除蛇身
int i;
for(i=0;i<100;i++)
{
while(food==snake[i])
food=rand()%256;
}
// 排除边界
unsigned char x_food,y_food;
num_to_xy(food,&x_food,&y_food);
while(0==x_food||0==y_food)
food=rand()%256;
return food;
//*x=rand()%18+1; // 1~18
//*y=rand()%18+1;
//printf("%d,%d\n",*x,*y);
//return 0;
}
// 移动蛇
void move_snake()
{
unsigned char x,y; // 蛇坐标
num_to_xy(snake[0], &x, &y); // 获取蛇头的坐标
unsigned char x_food,y_food; // 食物坐标
num_to_xy(food, &x_food, &y_food); // 获取食物的坐标
// 判断移动方向
switch (dir)
{
case KEYCODE_U: // 向上移动
if()
y--;
if(x==x_food&&y==y_food)
{
len++;
int i;
for(i=1;i<len;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
generate_food();
}
else
{
int i;
for(i=1;i<len+1;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
}
break;
case KEYCODE_D: // 向下移动
y++;
if(x==x_food&&y==y_food)
{
len++;
int i;
for(i=1;i<len;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
generate_food();
}
else
{
int i;
for(i=1;i<len+1;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
}
break;
case KEYCODE_L: // 向左移动
x--;
if(x==x_food&&y==y_food)
{
len++;
int i;
for(i=1;i<len;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
generate_food();
}
else
{
int i;
for(i=1;i<len+1;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
}
break;
case KEYCODE_R: // 向右移动
x++;
if(x==x_food&&y==y_food)
{
len++;
int i;
for(i=1;i<len;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
generate_food();
}
else
{
int i;
for(i=1;i<len+1;i++)
{
snake[len-i]=snake[len-i-1];
}
snake[0]=x*16+y;
}
break;
}
}
// 判断蛇是否应该存活,如果返回值是0代表应该存活,1代表不应该存活
int isalive()
{
unsigned char x,y; // 坐标
num_to_xy(snake[0], &x, &y); // 获取蛇头的坐标
//蛇头碰到蛇身
int i;
for(i=1;i<len;i++)
{
if(snake[0]==snake[i]);
return 1;
}
//蛇头碰到边界
if(0==x||0==y)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
// 开启一个线程用于获取键盘的上下左右键响应
pthread_t tid1;
pthread_create(&tid1, NULL, get_dir, NULL);
while(1)
{
// 更新地图数据
update_map();
// 打印地图
print_map();
// 移动蛇
move_snake();
if (isalive() == 1)
{
break;
}
if(len<5)
{
usleep(500000);
}
else
{
usleep(500000/(len-4));
}
system("clear");
}
tcsetattr(kfd, TCSANOW, &cooked);//在程序结束时在恢复原来的配置
printf ("Game Over!\n");
return 0;
}
更多推荐
已为社区贡献1条内容
所有评论(0)