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