参考的别人的贪吃蛇程序,只做了少许的更改,惭愧。http://bbs.csdn.net/topics/350080780
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <curses.h>
#include <sys/time.h>
struct Dir {
int dx;
int dy;
};
struct Node {
int nx;
int ny;
struct Node *prev;
struct Node *next;
};
struct Node *head, *tail;
struct Dir dir, food;
int hour, minute, second;
int length, ctrltime;
void init_game();
void dis_first_line();
void game_over(int);
void rand_food();
void dis_snake();
void set_timeval(int, struct timeval *);
void free_last_node();
void insert_after_head(int, int);
void free_link();
void display();
void deal_cmd();
void init_game()
{
cbreak();
noecho();
curs_set(0);
keypad(stdscr, true);
hour = minute = second = ctrltime = 0;
length = 1;
food.dx = 19;
food.dy = 9;
dir.dx = 1;
dir.dy = 0;
head = (struct Node *)malloc(sizeof(struct Node));
tail = (struct Node *)malloc(sizeof(struct Node));
head->next = tail;
head->prev = NULL;
tail->next = NULL;
tail->prev = head;
tail->nx = 17;
tail->ny = 7;
move(1, 0);
int i;
for(i = 0; i < COLS; ++i)
addstr("-");
}
void dis_first_line()
{
ctrltime += 200;
if(ctrltime % 1000 != 200)
return;
if(ctrltime > 7000000)
ctrltime = 0;
move(0, 3);
printw("time = %d:%d:%d", hour, minute, second);
++second;
if(second > 59) {
second = 0;
++minute;
}
if(minute > 59) {
minute = 0;
++hour;
}
if(hour > 23) {
game_over(4);
}
move(0, COLS / 2 - 7);
printw("length = %d", length);
move(0, COLS / 2 + 25);
printw("level = %d", length / 17 + 1);
}
void game_over(int x)
{
move(1, 0);
switch(x) {
case 1: printw("crash the wall, game over!");break;
case 2: printw("crash snake itself, game over!");break;
case 3: printw("congratulations, you just won.");break;
case 4: printw("you have played the whole day, now exit.");
free_link();
endwin();
exit(0);
case 5: printw("ok, exit now.");
sleep(2);
free_link();
endwin();
exit(0);
}
move(2, 0);
printw("press anykey to exit the game.");
int ch = getch();
endwin();
free_link();
exit(0);
}
void rand_food()
{
int x, y;
while(1) {
srand(time(0));
x = rand() % COLS;
y = rand() % (LINES - 2) + 2;
if(x == 0 && y == 0)
continue;
struct Node *pnode = head->next;
int flag = 1;
while(pnode) {
if(pnode->nx == x && pnode->ny == y) {
flag = 0;
break;
}
pnode = pnode->next;
}
if(flag) break;
}
food.dx = x;
food.dy = y;
}
void dis_snake()
{
struct Node *pnode = head->next;
if( COLS-1==pnode->nx && 1==dir.dx \
|| 0==pnode->nx && -1==dir.dx \
|| LINES-1==pnode->ny && 1==dir.dy \
|| 2==pnode->ny && -1==dir.dy)
game_over(1);
if('*' == mvinch(pnode->ny + dir.dy, pnode->nx + dir.dx))
game_over(2);
move(food.dy, food.dx);
printw("@");
insert_after_head(pnode->nx + dir.dx, pnode->ny + dir.dy);
move(pnode->ny + dir.dy, pnode->nx + dir.dx);
printw("*");
if(pnode->nx + dir.dx == food.dx && pnode->ny + dir.dy == food.dy) {
++length;
if(length > 137)
game_over(3);
rand_food();
} else {
move(tail->ny, tail->nx);
printw(" ");
free_last_node();
}
}
void set_timeval(int n, struct timeval *ptv)
{
ptv->tv_sec = n / 1000;
ptv->tv_usec = n % 1000 * 1000;
}
void free_last_node()
{
struct Node *pnode = tail;
tail = tail->prev;
tail->next = NULL;
free(pnode);
}
void insert_after_head(int x, int y)
{
struct Node *pnode = (struct Node *)malloc(sizeof(struct Node));
pnode->nx = x;
pnode->ny = y;
pnode->next = head->next;
pnode->prev = head;
head->next->prev = pnode;
head->next = pnode;
}
void free_link()
{
while(head->next)
free_last_node();
free(head);
}
void display()
{
dis_first_line();
dis_snake();
refresh();
}
void deal_cmd()
{
int cmd;
while(1) {
cmd = getch();
if(KEY_LEFT == cmd) {
dir.dx = -1;
dir.dy = 0;
} else if(KEY_RIGHT == cmd) {
dir.dx = 1;
dir.dy = 0;
} else if(KEY_DOWN ==cmd) {
dir.dx = 0;
dir.dy = 1;
} else if(KEY_UP == cmd) {
dir.dx = 0;
dir.dy = -1;
} else if('q' == cmd) {
game_over(5);
}
}
}
int main(void)
{
initscr();
init_game();
struct itimerval itv;
set_timeval(1, &itv.it_value);
set_timeval(200, &itv.it_interval);
setitimer(ITIMER_REAL, &itv, NULL);
signal(SIGALRM, display);
deal_cmd();
endwin();
return 0;
}