#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define MAP_X 20
#define MAP_Y 20
#define SNAKE_MAX MAP_X*MAP_Y

int snake_x[SNAKE_MAX];
int snake_y[SNAKE_MAX];
int snake_head=0;
int snake_tail=0;
int snake_dir=0;

char map[MAP_Y][MAP_X];

void init(){
    int i,j;
    for(i=0;i<MAP_Y;i++)for(j=0;j<MAP_X;j++)map[i][j]='-';
    for(i=0;i<MAP_Y;i++)map[i][0]=map[i][MAP_X-1]='@';
    for(i=0;i<MAP_X;i++)map[0][i]=map[MAP_Y-1][i]='@';
    snake_head=0;
    snake_tail=0;
    snake_x[0]=MAP_X/2;
    snake_y[0]=MAP_Y/2;
    snake_dir=0;
    map[MAP_Y/2][MAP_X/2]='@';
}

void print_map(){
    int i,j;
    for(i=0;i<MAP_Y;i++){
        for(j=0;j<MAP_X;j++)printf("%c",map[i][j]);
        printf("\n");
    }
}

int step_snake(int grow){
    static const int dir_d[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
    int pre_head,next_x,next_y;
    pre_head = snake_head;
    snake_head++;
    snake_head%=SNAKE_MAX;
    snake_x[snake_head]=next_x=(snake_x[pre_head]+dir_d[snake_dir][1])%MAP_X;
    snake_y[snake_head]=next_y=(snake_y[pre_head]+dir_d[snake_dir][0])%MAP_Y;
    if(map[next_y][next_x]=='@'){
        return -1;
    }
    map[next_y][next_x]='@';
    if(!grow){
        map[snake_y[snake_tail]][snake_x[snake_tail]]=' ';
        snake_tail++;
        snake_tail%=SNAKE_MAX;
    }
    return 0;
}

void change_dir(int dir){
    if( 0<=dir && dir<=3 && (dir+2)%4!=snake_dir ){
        snake_dir=dir;
    }
}

int wait_input(){
    fd_set rfds;
    struct timeval tv;
    int retval;
    char buf[10];
    int ret = -1;

    FD_ZERO(&rfds);
    FD_SET(0, &rfds);

    /* 1 秒間監視する。*/
    tv.tv_sec = 1;
    tv.tv_usec = 0;

    retval = select(1, &rfds, NULL, NULL, &tv);

    if (retval == -1){
        perror("select()");
    }else if (retval){
        read(0,buf,10);
        switch(buf[0]){
            case 'a':
            ret=2;
            break;
            case 's':
            ret=1;
            break;
            case 'd':
            ret=0;
            break;
            case 'w':
            ret=3;
            break;
        }
    }
    return ret;
}

int main(){
    int input;
    int game = 0;
    int turn = 0;
    init();
    while(game>=0){
        printf("turn %d\n",turn);
        print_map();
        input = wait_input();
        change_dir(input);
        game = step_snake(turn%4==0);
        turn++;
    }
    return 0;
}