diff --git a/src/directions.c b/src/directions.c new file mode 100644 index 0000000..572c520 --- /dev/null +++ b/src/directions.c @@ -0,0 +1,80 @@ +/* CATWALK - Test your logic + Copyright (C) 2021 Valentin Moguerou + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + +#include +#include "../inc/directions.h" +#include "../inc/route.h" + +#define RANDINT(MAX) (rand() % MAX) + +directions *init_directions(route *rt) +{ + directions *dirs = malloc(sizeof(*dirs)); + if (dirs==NULL) + { + exit(EXIT_FAILURE); + } + + dirs->rt = rt; + dirs->count = 0; + + return dirs; +} + +int evaluate_directions(directions *dirs) +{ + int width = dirs->rt->width; + element *last = dirs->rt->last; + + int count = 0; + if (last->x != 0 && is_free(dirs->rt, last->x-1, last->y)) + { + dirs->cells[count][0] = last->x-1; + dirs->cells[count][1] = last->y; + count++; + } + if (last->x != (width-1) && is_free(dirs->rt, last->x+1, last->y)) + { + dirs->cells[count][0] = last->x+1; + dirs->cells[count][1] = last->y; + count++; + } + if (last->y != 0 && is_free(dirs->rt, last->x, last->y-1)) + { + dirs->cells[count][0] = last->x; + dirs->cells[count][1] = last->y-1; + count++; + } + if (last->y != (width-1) && is_free(dirs->rt, last->x, last->y+1)) + { + dirs->cells[count][0] = last->x; + dirs->cells[count][1] = last->y+1; + count++; + } + dirs->count = count; + return count; +} + +void push_choose(route *rt, directions *dirs) +{ + int nb = RANDINT(dirs->count); + push_back(rt, dirs->cells[nb][0], dirs->cells[nb][1]); +} + +void delete_directions(directions *dirs) +{ + free(dirs); +} \ No newline at end of file diff --git a/src/grid.c b/src/grid.c new file mode 100644 index 0000000..adc4f27 --- /dev/null +++ b/src/grid.c @@ -0,0 +1,108 @@ +/* CATWALK - Test your logic + Copyright (C) 2021 Valentin Moguerou + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + +#include +#include "../inc/grid.h" +#include "../inc/indicators.h" +#include "../inc/route.h" + +#define RANDINT(MAX) (rand() % MAX) + +grid *init_grid(int width) +{ + grid *gd = malloc(sizeof(grid)); + if (gd == NULL) + { + exit(EXIT_FAILURE); + } + + gd->width = width; + gd->hints = init_indicators(width); + gd->player_route = NULL; + + return gd; +} + +void random_grid(grid *gd, int seed) +{ + srand(seed); + random_start(gd); + refresh_grid(gd); +} + +void random_start(grid *gd) +{ + gd->start[0] = RANDINT(gd->width); + gd->start[1] = RANDINT(gd->width); +} + +void refresh_grid(grid *gd) +{ + route *rt = init_route(gd->width, gd->start[0], gd->start[1]); + + generate(rt); + setup_indicators(gd->hints, rt); + + element *last = rt->last; + gd->end[0] = last->x; + gd->end[1] = last->y; + + delete_route(rt); +} + +void init_player_route(grid *gd) +{ + route *player_rt = malloc(sizeof(*player_rt)); + if (player_rt == NULL) + { + exit(EXIT_FAILURE); + } + + player_rt = init_route(gd->width, gd->start[0], gd->start[1]); + + gd->player_route = player_rt; +} + +void reset_player_route(grid *gd) +{ + delete_route(gd->player_route); + init_player_route(gd); +} + +void delete_grid(grid *gd) +{ + delete_indicators(gd->hints); + if (gd->player_route) + { + delete_route(gd->player_route); + } + free(gd); +} + +int verify(grid *gd) +{ + indicators *verif_in = init_indicators(gd->width); + setup_indicators(verif_in, gd->player_route); + + for (int i=0; iwidth; i++) + { + if ((verif_in->x[i] != gd->hints->x[i]) || (verif_in->y[i] != gd->hints->y[i])) + { + return 0; + } + } + return 1; +} \ No newline at end of file diff --git a/src/indicators.c b/src/indicators.c new file mode 100644 index 0000000..4c1ba24 --- /dev/null +++ b/src/indicators.c @@ -0,0 +1,58 @@ +/* CATWALK - Test your logic + Copyright (C) 2021 Valentin Moguerou + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + +#include +#include "../inc/indicators.h" +#include "../inc/route.h" + +indicators *init_indicators(int width) +{ + indicators *in = malloc(sizeof(*in)); + if (in == NULL) + { + exit(EXIT_FAILURE); + } + + in->x = calloc(width, sizeof(int)); + in->y = calloc(width, sizeof(int)); + if (in->x==NULL || in->y==NULL) + { + exit(EXIT_FAILURE); + } + + return in; +} + +void setup_indicators(indicators *in, route *rt) +{ + for (int i=0; iwidth; i++) + { + in->x[i] = 0; + in->y[i] = 0; + } + for (element *el=rt->first; el; el=el->next) + { + in->x[el->x]++; + in->y[el->y]++; + } +} + +void delete_indicators(indicators *hints) +{ + free(hints->x); + free(hints->y); + free(hints); +} diff --git a/src/route.c b/src/route.c new file mode 100644 index 0000000..4b0249e --- /dev/null +++ b/src/route.c @@ -0,0 +1,210 @@ +/* CATWALK - Test your logic + Copyright (C) 2021 Valentin Moguerou + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULIAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see */ + +#include +#include "../inc/directions.h" +#include "../inc/route.h" + +#define RANDINT(MIN, MAX) ((rand()%(MAX-MIN)) + MIN) + +int is_left(element *first, element *second) +{ + return first->x-1 == second->x; +} + +int is_right(element *first, element *second) +{ + return first->x+1 == second->x; +} + +int is_up(element *first, element *second) +{ + return first->y-1 == second->y; +} + +int is_down(element *first, element *second) +{ + return first->y+1 == second->y; +} + +int move_left(route *rt) +{ + element *last = rt->last; + if (last->x == 0) + { + return 1; + } + else if (!is_free(rt, last->x-1, last->y)) + { + return 2; + } + else + { + push_back(rt, last->x-1, last->y); + return 0; + } +} + +int move_right(route *rt) +{ + element *last = rt->last; + if (last->x == rt->width-1) + { + return 1; + } + else if (!is_free(rt, last->x+1, last->y)) + { + return 2; + } + else + { + push_back(rt, last->x+1, last->y); + return 0; + } +} + +int move_up(route *rt) +{ + element *last = rt->last; + if (last->y == 0) + { + return 1; + } + else if (!is_free(rt, last->x, last->y-1)) + { + return 2; + } + else + { + push_back(rt, last->x, last->y-1); + return 0; + } +} + +int move_down(route *rt) +{ + element *last = rt->last; + if (last->y == (rt->width-1)) + { + return 1; + } + else if (!is_free(rt, last->x, last->y+1)) + { + return 2; + } + else + { + push_back(rt, last->x, last->y+1); + return 0; + } +} + +route *init_route(int width, int startx, int starty) +{ + route *rt = malloc(sizeof(*rt)); + element *el = malloc(sizeof(*el)); + + if (rt == NULL || el == NULL) + { + exit(EXIT_FAILURE); // memory allocation failed + } + + el->previous = NULL; + el->next = NULL; + + el->x = startx; + el->y = starty; + + rt->width = width; + rt->first = el; + rt->last = el; + + return rt; +} + +void delete_element(element *el) +{ + if (el->next) + { + delete_element(el->next); + } + free(el); +} + +void delete_route(route *rt) +{ + delete_element(rt->first); + free(rt); +} + +void push_back(route *rt, int x, int y) +{ + element *new_el = malloc(sizeof(*new_el)); + if (new_el == NULL) + { + exit(EXIT_FAILURE); + } + + new_el->x = x; + new_el->y = y; + new_el->previous = rt->last; + new_el->next = NULL; + + rt->last->next = new_el; + rt->last = new_el; +} + +void pop_back(route *rt) +{ + element *last = rt->last; + rt->last = rt->last->previous; + rt->last->next = NULL; + free(last); +} + +element *find_coordinates(route *rt, int x, int y) +{ + for (element *el=rt->first; el; el=el->next) + { + if (el->x == x && el->y == y) + { + return el; + } + } + return NULL; +} + +int is_free(route *rt, int x, int y) +{ + for (element *el=rt->first; el; el=el->next) + { + if (x==el->x && y==el->y) + { + return 0; + } + } + return 1; +} + +void generate(route *rt) +{ + directions *dirs = init_directions(rt); + + for (int i=0; i < RANDINT(1, rt->width*rt->width) && evaluate_directions(dirs); i++) + { + push_choose(rt, dirs); + } +} \ No newline at end of file