#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));
}