diff --git a/game.c b/game.c index f05dd1f..64fc881 100644 --- a/game.c +++ b/game.c @@ -39,16 +39,14 @@ int main(int argc, char *argv[]) {"input", required_argument, 0, 'i'}, {0, 0, 0, 0}}; - Snake snake; - snake.pos[0].x = 1; - snake.pos[0].y = 3; - snake.pos[1].x = 1; - snake.pos[1].y = 2; - snake.pos[2].x = 1; - snake.pos[2].y = 1; - snake.pos[3].x = 1; - snake.pos[3].y = 0; - snake.dir = RIGHT; + Snake *snake = new_snake(); + add_segment(snake, 1, 5); + add_segment(snake, 1, 4); + add_segment(snake, 1, 3); + add_segment(snake, 1, 2); + add_segment(snake, 1, 1); + add_segment(snake, 1, 0); + snake->dir = BOTTOM; while ((opt = getopt_long(argc, argv, "hi:", long_options, &option_index)) != -1) { @@ -123,7 +121,7 @@ int main(int argc, char *argv[]) free(buf); fclose(stream); - place_snake(g, &snake); + place_snake(g, snake); MLV_create_window("SNAKE", "3R-IN1B", width, height); MLV_change_frame_rate(24); @@ -142,7 +140,7 @@ int main(int argc, char *argv[]) loop_count = (loop_count + 1) % DIFFICULTY; if (loop_count == 0) { - result = move_snake(&snake, g); + result = move_snake(snake, g); if (result == WALL || result == SNAKE) { @@ -176,20 +174,20 @@ int main(int argc, char *argv[]) switch (touche) { case MLV_KEYBOARD_DOWN: - if (snake.dir != TOP) - snake.dir = BOTTOM; + if (snake->dir != TOP) + snake->dir = BOTTOM; break; case MLV_KEYBOARD_UP: - if (snake.dir != BOTTOM) - snake.dir = TOP; + if (snake->dir != BOTTOM) + snake->dir = TOP; break; case MLV_KEYBOARD_LEFT: - if (snake.dir != RIGHT) - snake.dir = LEFT; + if (snake->dir != RIGHT) + snake->dir = LEFT; break; case MLV_KEYBOARD_RIGHT: - if (snake.dir != LEFT) - snake.dir = RIGHT; + if (snake->dir != LEFT) + snake->dir = RIGHT; break; default: break; @@ -201,5 +199,6 @@ int main(int argc, char *argv[]) MLV_free_window(); free_grid(g); + free_snake(snake); return 0; } \ No newline at end of file diff --git a/grid.c b/grid.c index 322f021..e428984 100644 --- a/grid.c +++ b/grid.c @@ -23,7 +23,7 @@ Grid *allocate_grid(int n, int m) } for (i = 0; i < n; i++) { - g->grid[i] = calloc(m + 1, sizeof(char)); + g->grid[i] = calloc(m + 2, sizeof(char)); if (!g->grid[i]) { fprintf(stderr, "Error: could not allocate row.\n"); @@ -102,28 +102,33 @@ void draw_grid(Grid *g) void place_snake(Grid *g, struct SnakeStruct *snake) { - int i; - for (i = 0; i < SNAKE_SIZE; i++) + Position *current = snake->segments_list; + + while (current != NULL) { - Coord part = snake->pos[i]; - g->grid[part.y][part.x] = 's'; + g->grid[current->y][current->x] = SNAKE; + current = current->next; } } Element move_snake(struct SnakeStruct *snake, Grid *g) { - Coord tail = snake->pos[SNAKE_SIZE - 1]; - Coord head; + Position *tail = snake->segments_list; + Position *head; Element element_at_head; - g->grid[tail.y][tail.x] = EMPTY; + while (tail->next != NULL) { + tail = tail->next; + } + + g->grid[tail->y][tail->x] = EMPTY; crawl(snake, g); - head = snake->pos[0]; - element_at_head = g->grid[head.y][head.x]; + head = snake->segments_list; + element_at_head = g->grid[head->y][head->x]; - g->grid[head.y][head.x] = SNAKE; + g->grid[head->y][head->x] = SNAKE; return element_at_head; } diff --git a/levels/level1 b/levels/level1 new file mode 100644 index 0000000..da62ce8 --- /dev/null +++ b/levels/level1 @@ -0,0 +1,25 @@ +w w + + f + + f f + + + f + + + wwwwwwwwww + w w w + w f w + wwwwww w + w + w + f w + w + f f w + w + f w +w w + w + w + w diff --git a/snake.c b/snake.c index 30bc618..d942b02 100644 --- a/snake.c +++ b/snake.c @@ -1,30 +1,102 @@ +#include #include "grid.h" #include "snake.h" -void crawl(Snake *snake, Grid *g) +Snake *new_snake(void) { - int i; - Coord new_head = snake->pos[0]; + Snake *snake = (Snake *)malloc(sizeof(Snake)); + if (snake == NULL) + { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + snake->size = 0; + snake->segments_list = NULL; + + return snake; +} + +void add_segment(Snake *snake, int x, int y) +{ + Position *new_segment = (Position *)malloc(sizeof(Position)); + if (new_segment == NULL) + { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + new_segment->x = x; + new_segment->y = y; + new_segment->next = NULL; + + if (snake->segments_list == NULL) + { + snake->segments_list = new_segment; + } + else + { + Position *current = snake->segments_list; + while (current->next != NULL) + { + current = current->next; + } + current->next = new_segment; + } + + snake->size++; +} + +void free_snake(Snake *snake) +{ + Position *current = snake->segments_list; + while (current != NULL) + { + Position *next = current->next; + free(current); + current = next; + } + free(snake); +} + +void crawl(Snake *snake, struct GridStruct *g) +{ + Position *new_head = (Position *)malloc(sizeof(Position)); + Position *current; + if (new_head == NULL) + { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + new_head->x = snake->segments_list->x; + new_head->y = snake->segments_list->y; + switch (snake->dir) { case LEFT: - new_head.x = (new_head.x - 1 + g->nbc) % g->nbc; + new_head->x = (new_head->x - 1 + g->nbc) % g->nbc; break; case RIGHT: - new_head.x = (new_head.x + 1) % g->nbc; + new_head->x = (new_head->x + 1) % g->nbc; break; case TOP: - new_head.y = (new_head.y - 1 + g->nbl) % g->nbl; + new_head->y = (new_head->y - 1 + g->nbl) % g->nbl; break; case BOTTOM: - new_head.y = (new_head.y + 1) % g->nbl; + new_head->y = (new_head->y + 1) % g->nbl; break; } - for (i = SNAKE_SIZE - 1; i > 0; i--) + new_head->next = snake->segments_list; + snake->segments_list = new_head; + + current = snake->segments_list; + while (current->next != NULL && current->next->next != NULL) { - snake->pos[i] = snake->pos[i - 1]; + current = current->next; } - snake->pos[0] = new_head; -} \ No newline at end of file + free(current->next); + current->next = NULL; +} diff --git a/snake.h b/snake.h index 4a41d83..fcb1435 100644 --- a/snake.h +++ b/snake.h @@ -3,13 +3,12 @@ struct GridStruct; -#define SNAKE_SIZE 4 - -typedef struct +typedef struct Position { int x; int y; -} Coord; + struct Position *next; +} Position; typedef enum { @@ -21,12 +20,16 @@ typedef enum struct SnakeStruct { - Coord pos[SNAKE_SIZE]; + Position *segments_list; + int size; Direction dir; }; typedef struct SnakeStruct Snake; +Snake *new_snake(void); +void add_segment(Snake *snake, int x, int y); +void free_snake(Snake *snake); void crawl(Snake *snake, struct GridStruct *g); #endif /* SNAKE_H */ \ No newline at end of file