diff --git a/game.c b/game.c index d5b8275..0c558b5 100644 --- a/game.c +++ b/game.c @@ -157,54 +157,84 @@ #include #include #include +#include #include #include "grid.h" #include "snake.h" +#define DIFFICULTY 6 + void print_help() { printf("Usage: snake2025 [OPTIONS]\n"); printf("Options:\n"); printf(" -h, --help Display this help message\n"); + printf(" -i, --input FILE Load initial grid configuration from FILE\n"); printf("\n"); printf("This is a simple snake game. Use the arrow keys to control the snake.\n"); printf("Press ESC to exit the game.\n"); } +int read_grid_from_file(const char *filename, char grid[NBL][NBC + 1]) +{ + int i, j, nb_fruit = 0; + FILE *file = fopen(filename, "r"); + if (!file) + { + fprintf(stderr, "Error: Could not open file %s\n", filename); + exit(EXIT_FAILURE); + } + + for (i = 0; i < NBL; i++) + { + if (!fgets(grid[i], NBC + 2, file)) + { + fprintf(stderr, "Error: File %s does not contain enough lines\n", filename); + fclose(file); + exit(EXIT_FAILURE); + } + grid[i][strcspn(grid[i], "\n")] = '\0'; + + for (j = 0; j < NBC; j++) + { + if (grid[i][j] == FRUIT) + { + nb_fruit++; + } + } + } + + fclose(file); + return nb_fruit; +} + +int count_fruits(char grid[NBL][NBC + 1]) +{ + int i, j, nb_fruit = 0; + for (i = 0; i < NBL; i++) + { + for (j = 0; j < NBC; j++) + { + if (grid[i][j] == FRUIT) + { + nb_fruit++; + } + } + } + return nb_fruit; +} + int main(int argc, char *argv[]) { - int opt; - int option_index = 0; - + int opt, option_index = 0, loop_count = 0, nb_fruit = 0; + char *input_file = NULL; MLV_Keyboard_button touche = MLV_KEYBOARD_NONE; int width = 640, height = 480; - - char grid[NBL][NBC + 1] = { - "w w", - " ", - " f ", - " ", - " f f ", - " ", - " ", - " f ", - " ", - " ", - " wwwwwwwwww ", - " ", - " ", - " ", - " ", - " ", - " f ", - " ", - " f f ", - " ", - " f ", - "w w"}; + char grid[NBL][NBC + 1] = {0}; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, + {"input", required_argument, 0, 'i'}, {0, 0, 0, 0}}; Snake snake; @@ -218,19 +248,39 @@ int main(int argc, char *argv[]) snake.pos[3].y = 0; snake.dir = RIGHT; - while ((opt = getopt_long(argc, argv, "h", long_options, &option_index)) != -1) + while ((opt = getopt_long(argc, argv, "hi:", long_options, &option_index)) != -1) { switch (opt) { case 'h': print_help(); return 0; + case 'i': + input_file = optarg; + break; default: fprintf(stderr, "Unknown option. Use -h or --help for usage information.\n"); return 1; } } + if (input_file) + { + nb_fruit = read_grid_from_file(input_file, grid); + } + else + { + int i, j; + for (i = 0; i < NBL; i++) + { + for (j = 0; j < NBC; j++) + { + grid[i][j] = EMPTY; + } + } + nb_fruit = count_fruits(grid); + } + place_snake(grid, &snake); MLV_create_window("SNAKE", "3R-IN1B", width, height); @@ -244,14 +294,65 @@ int main(int argc, char *argv[]) NULL) == MLV_NONE || touche != MLV_KEYBOARD_ESCAPE) { + Element result; MLV_clear_window(MLV_COLOR_BROWN); + loop_count = (loop_count + 1) % DIFFICULTY; + if (loop_count == 0) + { + result = move_snake(&snake, grid); + + if (result == WALL || result == SNAKE) + { + MLV_draw_text( + width / 2 - 50, height / 2, + "Game Over! You hit something.", + MLV_COLOR_RED); + MLV_actualise_window(); + MLV_wait_seconds(3); + break; + } + else if (result == FRUIT) + { + nb_fruit--; + if (nb_fruit == 0) + { + MLV_draw_text( + width / 2 - 50, height / 2, + "You Win! All fruits collected.", + MLV_COLOR_GREEN); + MLV_actualise_window(); + MLV_wait_seconds(3); + break; + } + } + } + draw_grid(grid); - - move_snake(&snake, grid); - MLV_actualise_window(); + switch (touche) + { + case MLV_KEYBOARD_DOWN: + if (snake.dir != TOP) + snake.dir = BOTTOM; + break; + case MLV_KEYBOARD_UP: + if (snake.dir != BOTTOM) + snake.dir = TOP; + break; + case MLV_KEYBOARD_LEFT: + if (snake.dir != RIGHT) + snake.dir = LEFT; + break; + case MLV_KEYBOARD_RIGHT: + if (snake.dir != LEFT) + snake.dir = RIGHT; + break; + default: + break; + } + touche = MLV_KEYBOARD_NONE; MLV_delay_according_to_frame_rate(); } diff --git a/grid.c b/grid.c index b8e695e..953e5a1 100644 --- a/grid.c +++ b/grid.c @@ -67,15 +67,19 @@ void place_snake(char grid[NBL][NBC + 1], Snake *snake) } } -void move_snake(Snake *snake, char grid[NBL][NBC + 1]) -{ +Element move_snake(Snake *snake, char grid[NBL][NBC + 1]) { Coord tail = snake->pos[SNAKE_SIZE - 1]; Coord head; + Element element_at_head; grid[tail.y][tail.x] = EMPTY; crawl(snake); head = snake->pos[0]; + element_at_head = grid[head.y][head.x]; + grid[head.y][head.x] = SNAKE; + + return element_at_head; } \ No newline at end of file diff --git a/grid.h b/grid.h index e25583b..8ac366c 100644 --- a/grid.h +++ b/grid.h @@ -18,6 +18,6 @@ void debug(char grid[NBL][NBC + 1]); int compute_size(int w, int h); void draw_grid(char grid[NBL][NBC + 1]); void place_snake(char grid[NBL][NBC + 1], Snake *snake); -void move_snake(Snake* snake, char grid[NBL][NBC+1]); +Element move_snake(Snake* snake, char grid[NBL][NBC+1]); #endif /* GRID_H */ \ No newline at end of file diff --git a/grids/1 b/grids/1 new file mode 100644 index 0000000..1fdbdf2 --- /dev/null +++ b/grids/1 @@ -0,0 +1,22 @@ +w w + + f + + f f + + + f + + + wwwwwwwwww + + + + + + f + + f f + + f +w w \ No newline at end of file