Added multi level support, dynamic snake location from level
This commit is contained in:
BIN
assets/fruit.png
Normal file
BIN
assets/fruit.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 311 KiB |
BIN
assets/grass.png
Normal file
BIN
assets/grass.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 683 KiB |
BIN
assets/wall.png
Normal file
BIN
assets/wall.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
297
game.c
297
game.c
@@ -27,11 +27,14 @@ int main(int argc, char *argv[])
|
||||
size_t size_buf = 0;
|
||||
int nbl, nbc, i;
|
||||
int opt, option_index = 0;
|
||||
int loop_count = 0, nb_fruit = 0;
|
||||
int loop_count = 0, nb_fruit = 0, total_fruits = 0;
|
||||
char *input_file = NULL;
|
||||
int width = 640, height = 480;
|
||||
MLV_Keyboard_button touche = MLV_KEYBOARD_NONE;
|
||||
int initial_size = 0;
|
||||
int current_level = 1;
|
||||
int global_score = 0;
|
||||
int previous_score = 0;
|
||||
|
||||
Grid *g;
|
||||
|
||||
@@ -40,17 +43,6 @@ int main(int argc, char *argv[])
|
||||
{"input", required_argument, 0, 'i'},
|
||||
{0, 0, 0, 0}};
|
||||
|
||||
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;
|
||||
|
||||
initial_size += snake->size;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "hi:", long_options, &option_index)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
@@ -67,155 +59,194 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (input_file == NULL)
|
||||
while (1)
|
||||
{
|
||||
input_file = "levels/default";
|
||||
}
|
||||
stream = fopen(input_file, "r");
|
||||
if (!stream)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to open file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
Snake *snake = new_snake();
|
||||
|
||||
nbl = count_nb_lines(stream);
|
||||
rewind(stream);
|
||||
nbc = getline(&buf, &size_buf, stream);
|
||||
if (nbc == -1)
|
||||
{
|
||||
fprintf(stderr, "Error: malformed file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
nbc--;
|
||||
previous_score = global_score;
|
||||
|
||||
g = allocate_grid(nbl, nbc);
|
||||
input_file = NULL;
|
||||
|
||||
copy(buf, g->grid[0]);
|
||||
for (i = 1; i < nbl; i++)
|
||||
{
|
||||
int size_tmp = getline(&buf, &size_buf, stream);
|
||||
if (size_tmp != nbc + 1)
|
||||
if (input_file == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: inconsistent line length\n");
|
||||
char level_file[256];
|
||||
snprintf(level_file, sizeof(level_file), "levels/level%d", current_level);
|
||||
input_file = level_file;
|
||||
}
|
||||
|
||||
stream = fopen(input_file, "r");
|
||||
if (!stream)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to open file for level %d\n", current_level);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nbl = count_nb_lines(stream);
|
||||
rewind(stream);
|
||||
nbc = getline(&buf, &size_buf, stream);
|
||||
if (nbc == -1)
|
||||
{
|
||||
fprintf(stderr, "Error: malformed file\n");
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
copy(buf, g->grid[i]);
|
||||
}
|
||||
nbc--;
|
||||
|
||||
rewind(stream);
|
||||
nb_fruit = count_fruits(stream, g);
|
||||
if (nb_fruit == 0)
|
||||
{
|
||||
fprintf(stderr, "Error: no fruits in the grid\n");
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (nb_fruit == -1)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to count fruits\n");
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g = allocate_grid(nbl, nbc);
|
||||
|
||||
free(buf);
|
||||
fclose(stream);
|
||||
|
||||
place_snake(g, snake);
|
||||
|
||||
MLV_create_window("SNAKE", "3R-IN1B", width, height);
|
||||
MLV_change_frame_rate(24);
|
||||
|
||||
while (
|
||||
MLV_get_event(
|
||||
&touche, NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL) == MLV_NONE ||
|
||||
touche != MLV_KEYBOARD_ESCAPE)
|
||||
{
|
||||
Element result;
|
||||
MLV_clear_window(MLV_COLOR_BLACK);
|
||||
|
||||
loop_count = (loop_count + 1) % DIFFICULTY;
|
||||
if (loop_count == 0)
|
||||
copy(buf, g->grid[0]);
|
||||
for (i = 1; i < nbl; i++)
|
||||
{
|
||||
result = move_snake(snake, g);
|
||||
|
||||
if (result == WALL || result == SNAKE)
|
||||
int size_tmp = getline(&buf, &size_buf, stream);
|
||||
if (size_tmp != nbc + 1)
|
||||
{
|
||||
if (result == WALL)
|
||||
{
|
||||
MLV_draw_text(width / 2 - 75, height / 2, "Game Over! You hit a wall.", MLV_COLOR_RED);
|
||||
}
|
||||
else if (result == SNAKE)
|
||||
{
|
||||
MLV_draw_text(width / 2 - 75, height / 2, "Game Over! You hit yourself.", MLV_COLOR_RED);
|
||||
}
|
||||
MLV_actualise_window();
|
||||
MLV_wait_seconds(3);
|
||||
break;
|
||||
fprintf(stderr, "Error: inconsistent line length\n");
|
||||
free(buf);
|
||||
free_grid(g);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if (result == FRUIT)
|
||||
copy(buf, g->grid[i]);
|
||||
}
|
||||
|
||||
rewind(stream);
|
||||
nb_fruit = count_fruits(stream, g);
|
||||
total_fruits = nb_fruit;
|
||||
if (nb_fruit == 0)
|
||||
{
|
||||
fprintf(stderr, "Error: no fruits in the grid\n");
|
||||
free(buf);
|
||||
free_grid(g);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (nb_fruit == -1)
|
||||
{
|
||||
fprintf(stderr, "Error: unable to count fruits\n");
|
||||
free(buf);
|
||||
free_grid(g);
|
||||
fclose(stream);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
fclose(stream);
|
||||
|
||||
read_snake_from_grid(g, snake);
|
||||
initial_size = snake->size;
|
||||
|
||||
MLV_create_window("SNAKE", "3R-IN1B", width, height);
|
||||
MLV_change_frame_rate(24);
|
||||
|
||||
while (
|
||||
MLV_get_event(
|
||||
&touche, NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL) == MLV_NONE ||
|
||||
touche != MLV_KEYBOARD_ESCAPE)
|
||||
{
|
||||
Element result;
|
||||
char stats[256];
|
||||
MLV_clear_window(MLV_COLOR_BLACK);
|
||||
|
||||
loop_count = (loop_count + 1) % DIFFICULTY;
|
||||
if (loop_count == 0)
|
||||
{
|
||||
Position *tail = snake->segments_list;
|
||||
Position *prev = NULL;
|
||||
while (tail->next != NULL)
|
||||
result = move_snake(snake, g);
|
||||
|
||||
if (result == WALL || result == SNAKE)
|
||||
{
|
||||
prev = tail;
|
||||
tail = tail->next;
|
||||
}
|
||||
int dx = tail->x - (prev ? prev->x : tail->x);
|
||||
int dy = tail->y - (prev ? prev->y : tail->y);
|
||||
add_segment(snake, tail->x + dx, tail->y + dy);
|
||||
place_snake(g, snake);
|
||||
if (snake->size == initial_size + nb_fruit)
|
||||
{
|
||||
MLV_draw_text(
|
||||
width / 2 - 75, height / 2,
|
||||
"You Win! All fruits collected.",
|
||||
MLV_COLOR_GREEN);
|
||||
if (result == WALL)
|
||||
{
|
||||
MLV_draw_text(width / 2 - 80, height / 2, "Game Over! You hit a wall.", MLV_COLOR_RED);
|
||||
}
|
||||
else if (result == SNAKE)
|
||||
{
|
||||
MLV_draw_text(width / 2 - 80, height / 2, "Game Over! You hit yourself.", MLV_COLOR_RED);
|
||||
}
|
||||
MLV_actualise_window();
|
||||
MLV_wait_seconds(3);
|
||||
|
||||
global_score = previous_score;
|
||||
break;
|
||||
}
|
||||
else if (result == FRUIT)
|
||||
{
|
||||
Position *tail = snake->segments_list;
|
||||
Position *prev = NULL;
|
||||
int dx, dy;
|
||||
while (tail->next != NULL)
|
||||
{
|
||||
prev = tail;
|
||||
tail = tail->next;
|
||||
}
|
||||
dx = tail->x - (prev ? prev->x : tail->x);
|
||||
dy = tail->y - (prev ? prev->y : tail->y);
|
||||
add_segment(snake, tail->x + dx, tail->y + dy);
|
||||
place_snake(g, snake);
|
||||
nb_fruit--;
|
||||
global_score++;
|
||||
if (snake->size == initial_size + total_fruits)
|
||||
{
|
||||
MLV_draw_text(
|
||||
width / 2 - 200, height / 2,
|
||||
"You Win! All fruits collected. Proceeding to the next level.",
|
||||
MLV_COLOR_GREEN);
|
||||
MLV_actualise_window();
|
||||
MLV_wait_seconds(3);
|
||||
current_level++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_grid(g);
|
||||
|
||||
snprintf(stats, sizeof(stats),
|
||||
"Level: %d | Fruits Left: %d/%d | Score: %d | Snake Size: %d",
|
||||
current_level, nb_fruit, total_fruits, global_score, snake->size);
|
||||
MLV_draw_text(10, height - 20, stats, MLV_COLOR_WHITE);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
draw_grid(g);
|
||||
MLV_actualise_window();
|
||||
MLV_free_window();
|
||||
free_grid(g);
|
||||
free_snake(snake);
|
||||
|
||||
switch (touche)
|
||||
if (touche == MLV_KEYBOARD_ESCAPE)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
MLV_free_window();
|
||||
free_grid(g);
|
||||
free_snake(snake);
|
||||
return 0;
|
||||
}
|
||||
197
grid.c
197
grid.c
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <MLV/MLV_all.h>
|
||||
#include "grid.h"
|
||||
#include "snake.h"
|
||||
@@ -46,7 +47,7 @@ void free_grid(Grid *g)
|
||||
free(g);
|
||||
}
|
||||
|
||||
void debug(Grid *g)
|
||||
void debug_grid(Grid *g)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
@@ -68,6 +69,27 @@ void draw_grid(Grid *g)
|
||||
int window_width = MLV_get_window_width();
|
||||
int window_height = MLV_get_window_height();
|
||||
int cell_size = compute_size(g, window_width, window_height);
|
||||
MLV_Image *image_wall, *image_fruit, *image_snake, *image_empty;
|
||||
image_wall = MLV_load_image("./assets/wall.png");
|
||||
image_fruit = MLV_load_image("./assets/fruit.png");
|
||||
image_snake = MLV_load_image("./assets/snake.png");
|
||||
image_empty = MLV_load_image("./assets/grass.png");
|
||||
if (image_wall != NULL)
|
||||
{
|
||||
MLV_resize_image_with_proportions(image_wall, cell_size, cell_size);
|
||||
}
|
||||
if (image_fruit != NULL)
|
||||
{
|
||||
MLV_resize_image_with_proportions(image_fruit, cell_size, cell_size);
|
||||
}
|
||||
if (image_snake != NULL)
|
||||
{
|
||||
MLV_resize_image_with_proportions(image_snake, cell_size, cell_size);
|
||||
}
|
||||
if (image_empty != NULL)
|
||||
{
|
||||
MLV_resize_image_with_proportions(image_empty, cell_size, cell_size);
|
||||
}
|
||||
|
||||
MLV_draw_filled_rectangle(0, 0, window_width, window_height, MLV_COLOR_BLACK);
|
||||
|
||||
@@ -81,16 +103,55 @@ void draw_grid(Grid *g)
|
||||
switch (g->grid[i][j])
|
||||
{
|
||||
case WALL:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_BROWN);
|
||||
if (image_wall == NULL)
|
||||
{
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_BROWN);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLV_draw_image(image_wall, x, y);
|
||||
}
|
||||
break;
|
||||
case EMPTY:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_WHITE);
|
||||
if (image_empty != NULL)
|
||||
{
|
||||
MLV_draw_image(image_empty, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_WHITE);
|
||||
}
|
||||
|
||||
break;
|
||||
case FRUIT:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_RED);
|
||||
if (image_fruit == NULL)
|
||||
{
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLV_draw_image(image_fruit, x, y);
|
||||
}
|
||||
break;
|
||||
case SNAKE:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_GREEN);
|
||||
if (image_snake == NULL)
|
||||
{
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLV_draw_image(image_snake, x, y);
|
||||
}
|
||||
break;
|
||||
case SNAKEHEAD:
|
||||
if (image_snake == NULL)
|
||||
{
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_GREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
MLV_draw_image(image_snake, x, y);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MLV_draw_filled_rectangle(x, y, cell_size, cell_size, MLV_COLOR_BLACK);
|
||||
@@ -104,6 +165,12 @@ void place_snake(Grid *g, struct SnakeStruct *snake)
|
||||
{
|
||||
Position *current = snake->segments_list;
|
||||
|
||||
if (current != NULL)
|
||||
{
|
||||
g->grid[current->y][current->x] = SNAKEHEAD;
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
while (current != NULL)
|
||||
{
|
||||
g->grid[current->y][current->x] = SNAKE;
|
||||
@@ -117,7 +184,8 @@ Element move_snake(struct SnakeStruct *snake, Grid *g)
|
||||
Position *head;
|
||||
Element element_at_head;
|
||||
|
||||
while (tail->next != NULL) {
|
||||
while (tail->next != NULL)
|
||||
{
|
||||
tail = tail->next;
|
||||
}
|
||||
|
||||
@@ -128,7 +196,12 @@ Element move_snake(struct SnakeStruct *snake, Grid *g)
|
||||
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] = SNAKEHEAD;
|
||||
|
||||
if (head->next != NULL)
|
||||
{
|
||||
g->grid[head->next->y][head->next->x] = SNAKE;
|
||||
}
|
||||
|
||||
return element_at_head;
|
||||
}
|
||||
@@ -179,4 +252,114 @@ void copy(const char *src, char *dst)
|
||||
i++;
|
||||
}
|
||||
dst[i] = '\0';
|
||||
}
|
||||
|
||||
static bool are_adjacent(Position *a, Position *b)
|
||||
{
|
||||
return (a->x == b->x && abs(a->y - b->y) == 1) ||
|
||||
(a->y == b->y && abs(a->x - b->x) == 1);
|
||||
}
|
||||
|
||||
int is_snake_connected(struct SnakeStruct *snake)
|
||||
{
|
||||
Position *current = snake->segments_list;
|
||||
while (current && current->next)
|
||||
{
|
||||
if (!are_adjacent(current, current->next))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void read_snake_from_grid(Grid *g, struct SnakeStruct *snake)
|
||||
{
|
||||
Position *positions = malloc(g->nbl * g->nbc * sizeof(Position));
|
||||
int positions_count = 0;
|
||||
Position *head = NULL;
|
||||
Position *current;
|
||||
int i;
|
||||
int *used = NULL;
|
||||
|
||||
for (i = 0; i < g->nbl; i++)
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < g->nbc; j++)
|
||||
{
|
||||
if (g->grid[i][j] == SNAKE || g->grid[i][j] == SNAKEHEAD)
|
||||
{
|
||||
positions[positions_count].x = j;
|
||||
positions[positions_count].y = i;
|
||||
positions[positions_count].next = NULL;
|
||||
|
||||
if (g->grid[i][j] == SNAKEHEAD)
|
||||
{
|
||||
head = &positions[positions_count];
|
||||
}
|
||||
|
||||
positions_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (head == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: Snake head (S) not found in the grid.\n");
|
||||
free(positions);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
used = malloc(positions_count * sizeof(int));
|
||||
if (!used) {
|
||||
fprintf(stderr, "Error: Could not allocate memory for used array.\n");
|
||||
free(positions);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (i = 0; i < positions_count; i++)
|
||||
{
|
||||
used[i] = 0;
|
||||
}
|
||||
|
||||
add_segment(snake, head->x, head->y);
|
||||
used[head - positions] = 1;
|
||||
|
||||
current = head;
|
||||
while (1)
|
||||
{
|
||||
int found = 0;
|
||||
int j;
|
||||
for (j = 0; j < positions_count; j++)
|
||||
{
|
||||
if (!used[j] && are_adjacent(current, &positions[j]))
|
||||
{
|
||||
add_segment(snake, positions[j].x, positions[j].y);
|
||||
used[j] = 1;
|
||||
current = &positions[j];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < positions_count; i++)
|
||||
{
|
||||
if (!used[i])
|
||||
{
|
||||
fprintf(stderr, "Error: Snake is not fully connected in the grid.\n");
|
||||
free(positions);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
snake->dir = determine_initial_direction(g, snake->segments_list);
|
||||
|
||||
free(positions);
|
||||
free(used);
|
||||
}
|
||||
10
grid.h
10
grid.h
@@ -19,12 +19,14 @@ typedef enum
|
||||
WALL = 'w',
|
||||
EMPTY = ' ',
|
||||
FRUIT = 'f',
|
||||
SNAKE = 's'
|
||||
SNAKE = 's',
|
||||
SNAKEHEAD = 'S',
|
||||
SNAKETAIL = 't'
|
||||
} Element;
|
||||
|
||||
Grid* allocate_grid(int n, int m);
|
||||
Grid *allocate_grid(int n, int m);
|
||||
void free_grid(Grid *g);
|
||||
void debug(Grid *g);
|
||||
void debug_grid(Grid *g);
|
||||
int compute_size(Grid *g, int w, int h);
|
||||
void draw_grid(Grid *g);
|
||||
void place_snake(Grid *g, struct SnakeStruct *snake);
|
||||
@@ -32,5 +34,7 @@ Element move_snake(struct SnakeStruct *snake, Grid *g);
|
||||
int count_nb_lines(FILE *stream);
|
||||
int count_fruits(FILE *stream, Grid *g);
|
||||
void copy(const char *src, char *dst);
|
||||
int is_snake_connected(struct SnakeStruct *snake);
|
||||
void read_snake_from_grid(Grid *g, struct SnakeStruct *snake);
|
||||
|
||||
#endif /* GRID_H */
|
||||
@@ -1,22 +0,0 @@
|
||||
w w
|
||||
|
||||
f
|
||||
|
||||
f f
|
||||
|
||||
|
||||
f
|
||||
|
||||
|
||||
wwwwwwwwww
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
f
|
||||
|
||||
f f
|
||||
|
||||
f
|
||||
w w
|
||||
@@ -1,7 +1,7 @@
|
||||
w w
|
||||
|
||||
f
|
||||
|
||||
ssssS
|
||||
f f
|
||||
|
||||
|
||||
@@ -9,17 +9,14 @@ w w
|
||||
|
||||
|
||||
wwwwwwwwww
|
||||
w w w
|
||||
w f w
|
||||
wwwwww w
|
||||
w
|
||||
w
|
||||
f w
|
||||
w
|
||||
f f w
|
||||
w
|
||||
f w
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
f
|
||||
|
||||
f f
|
||||
|
||||
f
|
||||
w w
|
||||
w
|
||||
w
|
||||
w
|
||||
|
||||
25
levels/level2
Normal file
25
levels/level2
Normal file
@@ -0,0 +1,25 @@
|
||||
w w
|
||||
|
||||
f
|
||||
|
||||
f f
|
||||
|
||||
|
||||
f
|
||||
|
||||
|
||||
wwwwwwwwww
|
||||
Sssssw w w
|
||||
w f w
|
||||
wwwwww w
|
||||
w
|
||||
w
|
||||
f w
|
||||
w
|
||||
f f w
|
||||
w
|
||||
f w
|
||||
w w
|
||||
w
|
||||
w
|
||||
w
|
||||
45
snake.c
45
snake.c
@@ -13,6 +13,7 @@ Snake *new_snake(void)
|
||||
|
||||
snake->size = 0;
|
||||
snake->segments_list = NULL;
|
||||
snake->dir = RIGHT;
|
||||
|
||||
return snake;
|
||||
}
|
||||
@@ -59,6 +60,18 @@ void free_snake(Snake *snake)
|
||||
free(snake);
|
||||
}
|
||||
|
||||
void debug_snake(Snake *snake)
|
||||
{
|
||||
Position *current = snake->segments_list;
|
||||
printf("Snake segments:\n");
|
||||
while (current != NULL)
|
||||
{
|
||||
printf(" (%d, %d)\n", current->x, current->y);
|
||||
current = current->next;
|
||||
}
|
||||
printf("Snake size: %d\n", snake->size);
|
||||
}
|
||||
|
||||
void crawl(Snake *snake, struct GridStruct *g)
|
||||
{
|
||||
Position *new_head = (Position *)malloc(sizeof(Position));
|
||||
@@ -100,3 +113,35 @@ void crawl(Snake *snake, struct GridStruct *g)
|
||||
free(current->next);
|
||||
current->next = NULL;
|
||||
}
|
||||
|
||||
Direction determine_initial_direction(struct GridStruct *g, Position *head)
|
||||
{
|
||||
int x = head->x;
|
||||
int y = head->y;
|
||||
|
||||
printf("Determining initial direction from position (%d, %d)\n", x, y);
|
||||
|
||||
if (x + 1 < g->nbc && g->grid[y][x + 1] != WALL && g->grid[y][x + 1] != SNAKE)
|
||||
{
|
||||
printf("Direction: RIGHT\n");
|
||||
return RIGHT;
|
||||
}
|
||||
if (y + 1 < g->nbl && g->grid[y + 1][x] != WALL && g->grid[y + 1][x] != SNAKE)
|
||||
{
|
||||
printf("Direction: BOTTOM\n");
|
||||
return BOTTOM;
|
||||
}
|
||||
if (x - 1 >= 0 && g->grid[y][x - 1] != WALL && g->grid[y][x - 1] != SNAKE)
|
||||
{
|
||||
printf("Direction: LEFT\n");
|
||||
return LEFT;
|
||||
}
|
||||
if (y - 1 >= 0 && g->grid[y - 1][x] != WALL && g->grid[y - 1][x] != SNAKE)
|
||||
{
|
||||
printf("Direction: TOP\n");
|
||||
return TOP;
|
||||
}
|
||||
|
||||
printf("Default direction: BOTTOM\n");
|
||||
return BOTTOM;
|
||||
}
|
||||
2
snake.h
2
snake.h
@@ -30,6 +30,8 @@ typedef struct SnakeStruct Snake;
|
||||
Snake *new_snake(void);
|
||||
void add_segment(Snake *snake, int x, int y);
|
||||
void free_snake(Snake *snake);
|
||||
void debug_snake(Snake *snake);
|
||||
void crawl(Snake *snake, struct GridStruct *g);
|
||||
Direction determine_initial_direction(struct GridStruct *g, Position *head);
|
||||
|
||||
#endif /* SNAKE_H */
|
||||
Reference in New Issue
Block a user