参考的别人的贪吃蛇程序,只做了少许的更改,惭愧。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; }