Valentin Moguérou
3 years ago
4 changed files with 456 additions and 0 deletions
@ -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 <https://www.gnu.org/licenses/> */
|
|||
|
|||
#include <stdlib.h> |
|||
#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); |
|||
} |
@ -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 <https://www.gnu.org/licenses/> */
|
|||
|
|||
#include <stdlib.h> |
|||
#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; i<gd->width; i++) |
|||
{ |
|||
if ((verif_in->x[i] != gd->hints->x[i]) || (verif_in->y[i] != gd->hints->y[i])) |
|||
{ |
|||
return 0; |
|||
} |
|||
} |
|||
return 1; |
|||
} |
@ -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 <https://www.gnu.org/licenses/> */
|
|||
|
|||
#include <stdlib.h> |
|||
#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; i<rt->width; 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); |
|||
} |
@ -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 <https://www.gnu.org/licenses/> */
|
|||
|
|||
#include <stdlib.h> |
|||
#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); |
|||
} |
|||
} |
Loading…
Reference in new issue