#include #include #include #include #include #include #include #define MIN_Y 2 double DELAY = 0.1; enum {LEFT=1, UP, RIGHT, DOWN, STOP_GAME=KEY_F(10)}; enum {MAX_TAIL_SIZE=100, START_TAIL_SIZE=3, MAX_FOOD_SIZE=20, FOOD_EXPIRE_SECONDS=10,SEED_NUMBER=3}; // Здесь храним коды управления змейкой struct control_buttons { int down; int up; int left; int right; }control_buttons; struct control_buttons default_controls = {KEY_DOWN, KEY_UP, KEY_LEFT, KEY_RIGHT}; /* Голова змейки содержит в себе x,y - координаты текущей позиции direction - направление движения tsize - размер хвоста *tail - ссылка на хвост */ typedef struct snake_t { int x; int y; int direction; size_t tsize; struct tail_t *tail; struct control_buttons controls; } snake_t; /* Хвост это массив состоящий из координат x,y */ typedef struct tail_t { int x; int y; } tail_t; /* Еда — это массив точек, состоящий из координат x,y, времени, когда данная точка была установлена, и поля, сигнализирующего, была ли данная точка съедена. */ struct food { int x; int y; time_t put_time; char point; uint8_t enable; } food[MAX_FOOD_SIZE]; void initFood(struct food f[], size_t size) { struct food init = {0,0,0,0,0}; for(size_t i=0; iy, fp->x, " "); fp->x = rand() % (max_x - 1); fp->y = rand() % (max_y - 2) + 1; //Не занимаем верхнюю строку fp->put_time = time(NULL); fp->point = '$'; fp->enable = 1; spoint[0] = fp->point; mvprintw(fp->y, fp->x, "%s", spoint); } /* Разместить еду на поле */ void putFood(struct food f[], size_t number_seeds) { for(size_t i=0; i FOOD_EXPIRE_SECONDS ) { putFoodSeed(&f[i]); } } } } void initTail(struct tail_t t[], size_t size) { struct tail_t init_t={0,0}; for(size_t i=0; ix = x; head->y = y; head->direction = RIGHT; } void initSnake(snake_t *head, size_t size, int x, int y) { tail_t* tail = (tail_t*) malloc(MAX_TAIL_SIZE*sizeof(tail_t)); initTail(tail, MAX_TAIL_SIZE); initHead(head, x, y); head->tail = tail; // прикрепляем к голове хвост head->tsize = size+1; head->controls = default_controls; } /* Движение головы с учетом текущего направления движения */ void go(struct snake_t *head) { char ch = '@'; int max_x=0, max_y=0; getmaxyx(stdscr, max_y, max_x); // macro - размер терминала mvprintw(head->y, head->x, " "); // очищаем один символ switch (head->direction) { case LEFT: if(head->x <= 0) // Циклическое движение, чтобы не // уходить за пределы экрана head->x = max_x; mvprintw(head->y, --(head->x), "%c", ch); break; case RIGHT: mvprintw(head->y, ++(head->x), "%c", ch); break; case UP: mvprintw(--(head->y), head->x, "%c", ch); break; case DOWN: mvprintw(++(head->y), head->x, "%c", ch); break; default: break; } refresh(); } void changeDirection(struct snake_t* snake, const int32_t key) { if (key == snake->controls.down) snake->direction = DOWN; else if (key == snake->controls.up) snake->direction = UP; else if (key == snake->controls.right) snake->direction = RIGHT; else if (key == snake->controls.left) snake->direction = LEFT; } /* Движение хвоста с учетом движения головы */ void goTail(struct snake_t *head) { char ch = '*'; mvprintw(head->tail[head->tsize-1].y, head->tail[head->tsize-1].x, " "); for(size_t i = head->tsize-1; i>0; i--) { head->tail[i] = head->tail[i-1]; if( head->tail[i].y || head->tail[i].x) mvprintw(head->tail[i].y, head->tail[i].x, "%c", ch); } head->tail[0].x = head->x; head->tail[0].y = head->y; } //======================================================================== //Проверка того, является ли какое-то из зерен съеденным, _Bool haveEat(struct snake_t *head, struct food f[]) { //...нужно написать код...// return 0; } /* Увеличение хвоста на 1 элемент */ void addTail(struct snake_t *head) { //...нужно написать код...// } //======================================================================== int checkDirection(snake_t* snake, int32_t key) { //...нужно написать код...// return 1; } //Вынести тело цикла while из int main() в отдельную функцию update //и посмотреть, как изменится профилирование void update(struct snake_t *head, struct food f[], const int32_t key) { clock_t begin = clock(); go(head); goTail(head); if (checkDirection(head,key)) { changeDirection(head, key); } refreshFood(food, SEED_NUMBER);// Обновляем еду if (haveEat(head,food)) { addTail(head); } refresh();//Обновление экрана, вывели кадр анимации while ((double)(clock() - begin)/CLOCKS_PER_SECtail); free(snake); endwin(); // Завершаем режим curses mod return 0; }