這個小遊戲,無聊時敲得。
1.運行環境ubuntu版本c89下,基本能兼容。
2.實現了非堵塞的輸入。
3.每次吃一個,都會變長
4.採用鏈表完成
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termio.h>
#define TTY_PATH "/dev/tty"
#define STTY_ON "stty raw -echo -F"
#define STTY_OFF "stty -raw echo -F"
char map[10][10];
char direct = 'a';
typedef struct node
{
int x;
int y;
struct node* next;
}Node;
typedef struct food
{
int x;
int y;
}Food;
Node* head;
Food* food;
void init_map()//初始化地圖
{
int i,j;
for(i = 0; i < 10; i++)
for(j = 0; j < 10; j++)
{
if(i==0||i==9||j==0||j==9)
{
map[i][j] = '*';
}
else
{
map[i][j] = ' ';
}
}
}
void print()//打印地圖
{
int i,j;
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
printf(" %c ",map[i][j]);
}
printf("\n");
}
}
void init_snake(int n)//初始化n個長度的貪吃蛇
{
int i = 0;
Node* pre;
Node* node;
node = (Node*)malloc(sizeof(Node));
node -> x = 4;
node -> y = 5;
node -> next = NULL;
map[node->x][node->y] = '*';
pre = node;
head = pre;
for( i = 1; i < n; i++)
{
Node* node_next;
node_next = (Node*)malloc(sizeof(Node));
node_next -> x = 4;
node_next -> y = i+5;
node_next -> next = NULL;
map[node_next->x][node_next->y] = '*';
pre -> next = node_next;
pre = pre -> next;
}
}
void init_food()//初始化食物
{
if(food == NULL)
{
Food* f = (Food*)malloc(sizeof(Food));
food=f;
}
food -> x = rand()%8 + 1;
food -> y = rand()%8 + 1;
if(map[food->x][food->y] == '*')
init_food();
else
map[food->x][food->y]='@';
}
void eat_food(int x, int y)//吃掉食物後,生成一個新的食物
{
Node* pre;
Node* add_node = (Node*)malloc(sizeof(Node));
add_node -> x = x;
add_node -> y = y;
add_node -> next = NULL;
map[x][y] = '*';
pre = head;
while( pre->next )
pre = pre -> next;
pre -> next = add_node;
}
int is_over(int x,int y)//判斷是否撞牆,撞尾
{
if(map[x][y] == '*')
{
return 1;
}
return 0;
}
void gameover()//遊戲結算,清空動態分配空間
{
Node *pre, *last;
pre = last = head;
while (pre)
{
pre = pre -> next;
free(last);
last = pre;
}
free(food);
food = NULL;
head = NULL;
}
void move(char ch)//移動
{
if(direct == ch)
return;
if(ch == 'a'|| ch=='s'|| ch=='d' || ch=='w')
if( !((direct=='a' && ch=='d')||
(direct=='d' && ch=='a')||
(direct=='s' && ch=='w')||
(direct=='w' && ch=='s')))
direct = ch;
if( !head )
exit(-1);
Node *pre,*last;
pre = head;
int is_eat = 0;
int last_x;
int last_y;
int x1 = pre -> x;
int y1 = pre -> y;
switch(direct)
{
case 'a':
y1--;
break;
case 'w':
x1--;
break;
case 's':
x1++;
break;
case 'd':
y1++;
break;
}
if(is_over(x1,y1))
{
gameover();
printf("game over!!!!!\n");
exit(0);
}
if(map[x1][y1] == '@')
{
is_eat = 1;
init_food();
}
map[x1][y1] = '*';
int x2 = pre -> x;
int y2 = pre -> y;
while( pre )//通過記錄兩個點,實現貪吃蛇移動
{
pre -> x = x1;
pre -> y = y1;
if(!pre->next)
{
last_x = x2;
last_y = y2;
map[x2][y2] = ' ';
break;
}
pre = pre -> next;
x1 = pre -> x;
y1 = pre -> y;
pre -> x = x2;
pre -> y = y2;
if(!pre->next)
{
last_x = x1;
last_y = y1;
map[x1][y1] = ' ';
break;
}
x2 = pre -> next -> x;
y2 = pre -> next -> y;
pre = pre -> next;
}
if(is_eat)
eat_food( last_x , last_y);
}
char in_direct()//非堵塞鍵盤輸入
{
fd_set fd;
struct timeval tv;
char ch;
FD_ZERO(&fd);
FD_SET(0, &fd);
tv.tv_sec = 0;
tv.tv_usec = 10;
if(select(1, &fd ,NULL, NULL, &tv) > 0)
{
ch = getchar();
}
return ch;
}
int main()
{
srand(time(NULL));
init_map();
init_snake(3);
init_food();
int i = 0;
char ch;
for(i = 0;; i++)
{
usleep(500000);
system("clear");
system(STTY_ON TTY_PATH);
ch = in_direct();
system(STTY_OFF TTY_PATH);
move(ch);
print();
fflush(stdout);
}
return 0;
}