Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92450594
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: C/C++

2008-04-17 20:09:09

作者:chjcpu1  

/* gcc snake.c -l curses -g -o snake  */

/*
 snake.c
 by Chenhongjiang
 */

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include


#define L 20
#define N 12
#define LEVEL 1
#define SNAKE_LONG 3
#define SNAKE_HEAD_N 3
#define SNAKE_HEAD_L 5

int head_n, head_l, rear_n, rear_l;
int food_n, food_l;
int snake_speed, per_level_time;
int level, score;
int is_game_over;
char snake_box[N+2][L+2];
char move_box[N+2][L+2];
char current_way;
char ch_score[6];
char one[6][6] =  {"  0","  0","  0","  0","  0"};
char two[6][6] =  {"00000","    0", "00000", "0", "00000"};
char three[6][6] = {"00000","    0","00000","    0","00000"};
char four[6][6] = {"0 0","0 0","00000","  0","  0"};
char five[6][6] = {"00000","0","00000","    0","00000"};
char six[6][6] = {"00000","0","00000","0   0","00000"};
char seven[6][6] = {"00000","    0","    0","    0","    0"};
char eight[6][6] = {"00000","0   0","00000","0   0","00000"};
char nine[6][6] = {"00000","0   0","00000","    0","00000"};
char zero[6][6] = {"00000","0   0","0   0","0   0","00000"};

void handler(int signo);
int snake_refresh(void);
int create_snake(int i, int j);
int create_food();
void initial();
unsigned char my_random(void);
void init_sigaction(void);
void init_time();
void snake_log();

 


int main(void)
{
 int ch, last_ch; // in case snake run too quick
 int i, j, l, n;
 int snake_head, snake_rear;
 
 is_game_over = 1;
 level = LEVEL;
 score = 0;
 l = L + 2;
 n = N + 2;
 
 /* init move_box */
 for (i=0; i  for (j=0; j   move_box[i][j] = 'l';
  }

 /* init snake_box */
 for (i=0; i  for (j=0; j   if (i == 0 || j == 0) {
    snake_box[i][j] = 1;
   } else if (i == n-1 || j == l-1) {
    snake_box[i][j] = 1;
   } else {
    snake_box[i][j] = 0;
   }
  }

 head_n = SNAKE_HEAD_N;
 head_l = SNAKE_HEAD_L;
 rear_n = SNAKE_HEAD_N;
 rear_l = SNAKE_HEAD_L - SNAKE_LONG + 1;
 current_way = 'r';
 
 /* create a snke */
 create_snake(head_n, head_l);

 /* create a food ($ ^_^) */
 create_food();

 /* set time */
 snake_speed = 500000 - level*50000;
 per_level_time = 0;
 init_sigaction(); /* SIGNAL */
 init_time();  /* SIGNAL */

 initial();
 snake_refresh();
 signal(SIGALRM, handler);
 last_ch = 'a';
 while (is_game_over) {
  ch = getch();
  if (last_ch == ch) { /* in case input lot of the same key */
   continue;
  }
  switch (ch) {
      case KEY_RIGHT:
        if (current_way == 'l') { break;}
        current_way = 'r';
        snake_refresh();
        break;
      case KEY_DOWN:
        if (current_way == 'u') { break;}
        current_way = 'd';
        snake_refresh();
        break;
      case KEY_LEFT:
        if (current_way == 'r') { break;}
        current_way = 'l';
        snake_refresh();
        break;
      case KEY_UP:
        if (current_way == 'd') { break;}
        current_way = 'u';
        snake_refresh();
        break;
      default:
        break;
  } 
  last_ch = ch;
  sleep(1);
 }
 endwin();
 snake_log();  /* log to score.txt */
 exit(1);
}

void handler(int signo)
{
 per_level_time += snake_speed/100000;
 if (per_level_time >= 300) {  /* 10 is 1 sec */
  if (level <= 9) {
   level += 1;
   snake_speed = 500000 - level*50000;
   init_sigaction(); /* SIGNAL */
   init_time();  /* SIGNAL */
   per_level_time = 0;
  }
 }

 if (current_way == 'r') {
  snake_right();
 } else if (current_way == 'd') {
  snake_down();
 } else if (current_way == 'l') {
  snake_left();
 } else if (current_way == 'u') {
  snake_up();
 }
 snake_refresh();
 mvprintw(20, 20, "Level: %d\n", level);
}

void init_sigaction(void)
{
 struct sigaction act;
 act.sa_handler=handler;
 act.sa_flags=0;
 sigemptyset(&act.sa_mask);
 sigaction(SIGPROF,&act,NULL);
}

void init_time()
{
 struct itimerval value;
 value.it_value.tv_sec=0;
 value.it_value.tv_usec=snake_speed;
 value.it_interval=value.it_value;
 setitimer(ITIMER_REAL,&value,NULL);
}

int snake_refresh(void)
{
 int x, y;
 int  i, j, l, n;
 int score_len, length;
 l = L + 2;
 n = N + 2;

 x = 5, y = 5;
 for (i=0; i  for (j=0; j   if (snake_box[i][j] == 0) {
    mvprintw(x, y, " ");
   } else if (snake_box[i][j] == 1) {
    mvprintw(x, y, "@ ");
   } else if (snake_box[i][j] == 2) { /* food */
    mvprintw(x, y, "$");
   }
   y+=2;
   if (j == l-1) {
    mvprintw(x, y, "\n");
    x++;
    y = 5;
   }
  }
 x = 6; y = 50;
 mvprintw(x++, y, "00000 00000 00000 00000 00000\n");
 mvprintw(x++, y, "0     0     0   0 0   0 0   \n");
 mvprintw(x++, y, "00000 0     0   0 00000 00000\n");
 mvprintw(x++, y, "    0 0     0   0 0  0  0   \n");
 mvprintw(x, y  , "00000 00000 00000 0   0 00000\n");

 attron(A_BOLD);  
 sprintf(ch_score, "%d", score);
 score_len = strlen(ch_score);
 i = 0;
 n = 0;
 length = 0;
 x = 60;
 y = 13;
 while (i < score_len) {
  if (ch_score[i] == '0')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(zero+n));
    n++;
    y++;
   }
  if (ch_score[i] == '1')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(one+n));
    n++;
    y++;
   }
  if (ch_score[i] == '2')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(two+n));
    n++;
    y++;
   }
  if (ch_score[i] == '3')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(three+n));
    n++;
    y++;
   }
  if (ch_score[i] == '4')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(four+n));
    n++;
    y++;
   }
  if (ch_score[i] == '5')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(five+n));
    n++;
    y++;
   }
  if (ch_score[i] == '6')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(six+n));
    n++;
    y++;
   }
  if (ch_score[i] == '7')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(seven+n));
    n++;
    y++;
   }
  if (ch_score[i] == '8')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(eight+n));
    n++;
    y++;
   }
  if (ch_score[i] == '9')
   while (n<=4) {
    mvprintw(y, x+length, "%s", *(nine+n));
    n++;
    y++;
   }
  n = 0;
  y = 13;
  i++;
  length += 6;
 }
 attroff(A_BOLD);
 refresh();
}

int create_snake(int i, int j)
{
 int m;

 for (m=SNAKE_LONG-1; m>=0; m--) {
  snake_box[i][j-m] = 1;
  move_box[i][j-m] = 'r';
 }
}
int create_food(void)
{
 int tmp_n, tmp_l;
 do { 
  tmp_n = random_food(1, N-2);
  tmp_l = random_food(1, L-2);
 } while (snake_box[tmp_n][tmp_l] != 0);
 food_n = tmp_n;
 food_l = tmp_l;
 snake_box[food_n][food_l] = 2;
}

void initial()                       /* .... curses ..               */
{
 initscr();
 cbreak();
 nl();
 noecho();
 curs_set(0); // set off _
 intrflush(stdscr,FALSE);
 keypad(stdscr,TRUE);
 refresh();
}

int snake_right()
{
 current_way = 'r';
 if (snake_box[head_n][head_l+1] == 1) {
  is_game_over = 0;
  return(0);
 }
 if (snake_box[head_n][head_l+1] == 2) { // food
  snake_box[head_n][head_l+1] = 1;
  move_box[head_n][head_l] = 'r';
  head_l++;
  score += level*2;
  create_food();
  return(1);
 }
 
 snake_box[rear_n][rear_l] = 0;
 snake_box[head_n][head_l+1] = 1;
 move_box[head_n][head_l] = 'r';
 head_l++; // head + 1
 
 if (move_box[rear_n][rear_l] == 'r') {
  rear_l++;
 } else if (move_box[rear_n][rear_l] == 'd') {
  rear_n++;
 } else if (move_box[rear_n][rear_l] == 'l') {
  rear_l--;
 } else if (move_box[rear_n][rear_l] == 'u') {
  rear_n--;
 }
}

int snake_down()
{
 current_way = 'd';
 if (snake_box[head_n+1][head_l] == 1) {
  is_game_over = 0;
  return(0);
 }
 if (snake_box[head_n+1][head_l] == 2) { // food
  snake_box[head_n+1][head_l] = 1;
  move_box[head_n][head_l] = 'd';
  head_n++;
  score += level*2;
  create_food();
  return(1);
 }
 snake_box[rear_n][rear_l] = 0;
 snake_box[head_n+1][head_l] = 1;
 move_box[head_n][head_l] = 'd';

 head_n++;
 if (move_box[rear_n][rear_l] == 'r') {
  rear_l++;
 } else if (move_box[rear_n][rear_l] == 'd') {
  rear_n++;
 } else if (move_box[rear_n][rear_l] == 'l') {
  rear_l--;
 } else if (move_box[rear_n][rear_l] == 'u') {
  rear_n--;
 }
}

int snake_left()
{
 current_way = 'l';
 if (snake_box[head_n][head_l-1] == 1) {
  is_game_over = 0;
  return(0);
 }
 if (snake_box[head_n][head_l-1] == 2) { // food
  snake_box[head_n][head_l-1] = 1;
  move_box[head_n][head_l] = 'l';
  head_l--;
  score += level*2;
  create_food();
  return(1);
 }
 snake_box[rear_n][rear_l] = 0;
 snake_box[head_n][head_l-1] = 1;
 move_box[head_n][head_l] = 'l';

 head_l--;
 if (move_box[rear_n][rear_l] == 'r') {
  rear_l++;
 } else if (move_box[rear_n][rear_l] == 'd') {
  rear_n++;
 } else if (move_box[rear_n][rear_l] == 'l') {
  rear_l--;
 } else if (move_box[rear_n][rear_l] == 'u') {
  rear_n--;
 }
}

int snake_up()
{
 current_way = 'u';
 if (snake_box[head_n-1][head_l] == 1) {
  is_game_over = 0;
  return(0);
 }
 
 if (snake_box[head_n-1][head_l] == 2) { // food
  snake_box[head_n-1][head_l] = 1;
  move_box[head_n][head_l] = 'u';
  head_n--;
  score += level*2;
  create_food();
  return(1);
 }
 snake_box[rear_n][rear_l] = 0;
 snake_box[head_n-1][head_l] = 1;
 move_box[head_n][head_l] = 'u';

 head_n--;
 if (move_box[rear_n][rear_l] == 'r') {
  rear_l++;
 } else if (move_box[rear_n][rear_l] == 'd') {
  rear_n++;
 } else if (move_box[rear_n][rear_l] == 'l') {
  rear_l--;
 } else if (move_box[rear_n][rear_l] == 'u') {
  rear_n--;
 }
}

unsigned char my_random(void)
{
 static int seeded;
 unsigned int uint_res;
 unsigned char c1, c2, c3, c4;
 if (!seeded)
 {
  struct timeval tv;
  int retval = gettimeofday(&tv, NULL);
  if (retval != 0)
  {
   perror("gettimeofday");
   exit(0);
  }
  srand((unsigned)tv.tv_usec);
  seeded = 1;
 }
 uint_res = rand();
 c1 = uint_res & 0x000000ff;
 c2 = (uint_res >> 8) & 0x000000ff;
 c3 = (uint_res >> 16) & 0x000000ff;
 c4 = (uint_res >> 24) & 0x000000ff;
 return c1 ^ c2 ^ c3 ^ c4;   
}

int random_food(int min, int max)
{
 int scaled_value;
 int value = my_random();
 value <<= 8;
 value != my_random();
 scaled_value = (double)min;
 scaled_value += ((double)value / (double)65536)*
     ((double)max - min + 1);
 value = (unsigned short)scaled_value;
 return(value);
}

void snake_log()
{
 int openfd;
 char buf[128];
 struct timeval tv;
 struct tm* ptm;
 int retval = gettimeofday(&tv, NULL);
 
 ptm = (struct tm*)localtime(&tv, NULL);
 if ((openfd= open("score.txt", O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|
       S_IWUSR | S_IRGRP |
       S_IWGRP | S_IROTH)) == -1) {
  perror("snake log error");
  exit(0);
 }
 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S   ", ptm);
 write(openfd, buf, strlen(buf));
 sprintf(buf, "%s\n", ch_score);
 write(openfd, buf, strlen(buf));


}

阅读(454) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~