Code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ncurses.h>
#include <term.h>
#define WIDTH 80
#define HEIGHT 24
#define MAX_LENGTH 1000
#define START_LENGTH 3
#define B_SNAKE 'O'
#define B_FOOD '*'
#define D_UP 0
#define D_DOWN 1
#define D_LEFT 2
#define D_RIGHT 3
typedef struct SnakeBlock_ {
int x;
int y;
} SnakeBlock;
void init_game(void);
void terminate_game(void);
void remove_tail(SnakeBlock snake[], int length);
void append_head(int x, int y, SnakeBlock snake[]);
void move_back_blocks(SnakeBlock snake[], int length);
void draw_map(int fx, int fy, SnakeBlock snake[], int length);
void place_food(int *x, int *y, SnakeBlock snake[], int length);
void grow(SnakeBlock snake[], int length);
_Bool is_empty(int x, int y, SnakeBlock snake[], int length);
int main(void)
{
SnakeBlock snake[MAX_LENGTH];
WINDOW *key_detecter;
struct timespec sleep_time;
int i;
int x, y;
int dir;
int running;
int length;
int c;
int fx, fy;
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = 90000000;
init_game();
key_detecter = newwin(HEIGHT, WIDTH, 0, 0);
nodelay(key_detecter, TRUE);
running = 1;
dir = D_UP;
x = WIDTH / 2;
y = HEIGHT - START_LENGTH;
for (i = 0; i < START_LENGTH; i++) {
snake[i].x = x;
snake[i].y = y + i;
}
length = START_LENGTH;
place_food(&fx, &fy, snake, length);
while(running) {
c = wgetch(key_detecter);
switch (c) {
case 'w':
if (dir != D_DOWN) {
dir = D_UP;
}
break;
case 's':
if (dir != D_UP) {
dir = D_DOWN;
}
break;
case 'a':
if (dir != D_RIGHT) {
dir = D_LEFT;
}
break;
case 'd':
if (dir != D_LEFT) {
dir = D_RIGHT;
}
break;
case 'q':
running = 0;
break;
}
switch (dir) {
case D_UP:
y--;
break;
case D_DOWN:
y++;
break;
case D_LEFT:
x--;
break;
case D_RIGHT:
x++;
break;
}
if (x == fx && y == fy) {
grow(snake, length);
length++;
place_food(&x, &y, snake, length);
}
else {
remove_tail(snake, length);
}
move_back_blocks(snake, length);
append_head(x, y, snake);
draw_map(fx, fy, snake, length);
refresh();
nanosleep(&sleep_time, NULL);
}
terminate_game();
return 0;
}
void init_game(void)
{
initscr();
noecho();
curs_set(0);
}
void terminate_game(void)
{
curs_set(1);
clear();
endwin();
}
void append_head(int x, int y, SnakeBlock snake[])
{
snake[0].x = x;
snake[0].y = y;
}
void remove_tail(SnakeBlock snake[], int length)
{
mvaddch(snake[length - 1].y, snake[length - 1].x, ' ');
snake[length - 1].x = -1;
snake[length - 1].y = -1;
}
void move_back_blocks(SnakeBlock snake[], int length)
{
int i;
SnakeBlock temp;
for (i = length; i > 0; i--) {
temp = snake[i - 1];
snake[i] = temp;init_game();
}
}
void draw_map(int fx, int fy, SnakeBlock snake[], int length)
{
int i;
for (i = 0; i < length; i++) {
if (snake[i].y != -1 && snake[i].x != -1) {
mvaddch(snake[i].y, snake[i].x, B_SNAKE);
}
}
mvaddch(fy, fx, B_FOOD);
}
void place_food(int *x, int *y, SnakeBlock snake[], int length)
{
do {
*x = nrand(0, WIDTH);
*y = nrand(0, HEIGHT);
}
while (!is_empty(*x, *y, snake, length));
}
_Bool is_empty(int x, int y, SnakeBlock snake[], int length)
{
int i;
for (i = 0; i < length; i++) {
if (snake[i].x == x && snake[i].y == y) {
return FALSE;
}
}
return TRUE;
}
int nrand(int lower, int upper)
{
int dif = upper - lower;
srand((unsigned int) time((time_t *) NULL));
return (int)((double)rand() / ((double)RAND_MAX + 1) * dif);
}
void grow(SnakeBlock snake[], int length)
{
snake[length].x = snake[length - 1].x;
snake[length].y = snake[length - 1].y;
}
Any suggestions.