Initial commit
This commit is contained in:
		
							
								
								
									
										80
									
								
								src/directions.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/directions.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
|  | } | ||||||
							
								
								
									
										108
									
								
								src/grid.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/grid.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								src/indicators.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/indicators.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
|  | } | ||||||
							
								
								
									
										210
									
								
								src/route.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								src/route.c
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user