| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Created by snapshot112 on 2/10/2025 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | #include "grid.h"
 | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |  * The grid type this program is build around. | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | typedef struct grid_data { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     char *locations; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     int height; | 
					
						
							|  |  |  |     int width; | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     state state; | 
					
						
							|  |  |  | } grid; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Translate x and y coordinates to a location index on the grid. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | static int internal_location(const grid *gp, const int x, const int y) { | 
					
						
							|  |  |  |     return y * (gp->width + 1) + x; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | grid *grid_create_from_string(const char* input) { | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |     int width = 0; | 
					
						
							|  |  |  |     int height = 0; | 
					
						
							|  |  |  |     const size_t len = strlen(input) / sizeof(char); | 
					
						
							|  |  |  |     if (input == NULL || len == 0) { | 
					
						
							| 
									
										
										
										
											2025-10-17 11:15:53 +02:00
										 |  |  |         printf("invalid input\n"); | 
					
						
							| 
									
										
										
										
											2025-10-16 01:10:09 +02:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; input[i] != '\n'; i++) { | 
					
						
							|  |  |  |         width++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     height = (int)len / (width + 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 0; i < height; i = i + width + 1) { | 
					
						
							|  |  |  |         if ((int)strcspn(&input[i], "\n") != width) { | 
					
						
							| 
									
										
										
										
											2025-10-17 11:15:53 +02:00
										 |  |  |             printf("line %d was not %d wide\n", i, width); | 
					
						
							| 
									
										
										
										
											2025-10-16 01:10:09 +02:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const int grid_size = (width + 1) * height + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     grid *gp = malloc(sizeof(grid)); | 
					
						
							| 
									
										
										
										
											2025-10-16 01:10:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     if (gp == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-16 01:10:09 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     gp->locations = malloc(grid_size * sizeof(char)); | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     gp->height = height; | 
					
						
							|  |  |  |     gp->width = width; | 
					
						
							|  |  |  |     gp->state = STATE_BEGIN; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     strcpy(gp->locations, input); | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     return gp; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Sets a grids width and height | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Input: | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |  * fh: The stream to read the grid from. | 
					
						
							|  |  |  |  * gp: A pointer to the grid whose width and height you want to set. | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Side effects: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |  * the grid gets its width and height set | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Output: | 
					
						
							|  |  |  |  * 1 if the file width and height seem to match with its size | 
					
						
							|  |  |  |  * 0 otherwise | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | static int get_grid_sizes(FILE *fh, grid *gp) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     while (getc(fh) != '\n') { | 
					
						
							|  |  |  |         if (feof(fh)) { | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |         gp->width++; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp->width == 0) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fseek(fh, 0, SEEK_END); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Get file size (- 1 for the blank newline and EOF at the end)
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (ftell(fh) % (gp->width + 1) != 0) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         // Not all lines are the same width
 | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     gp->height = (int)ftell(fh) / (int)sizeof(char) / (gp->width + 1); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     fseek(fh, 0, SEEK_SET); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | grid *grid_create_from_file(FILE *fh) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     if (fh == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     grid temp_grid = { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         NULL, | 
					
						
							|  |  |  |         0, | 
					
						
							|  |  |  |         0, | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |         STATE_BEGIN | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     // Sets the width and height of the grid.
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (get_grid_sizes(fh, &temp_grid) != 1) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         // Unlogical file structure.
 | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     const int grid_size = (temp_grid.width + 1) * temp_grid.height + 1; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     temp_grid.locations = malloc(grid_size * sizeof(char)); | 
					
						
							|  |  |  |     if (temp_grid.locations == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // This makes the strncat() work.
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     temp_grid.locations[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     char *line = malloc((temp_grid.width + 2) * sizeof(char)); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     if (line == NULL) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     for (int i = 0; i < temp_grid.height; i++) { | 
					
						
							|  |  |  |         if (fgets(line, temp_grid.width + 2, fh) == NULL) { | 
					
						
							|  |  |  |             free(temp_grid.locations); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |             free(line); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Validate that the line length is correct
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |         if ((int)strcspn(line, "\n") != temp_grid.width) { | 
					
						
							|  |  |  |             free(temp_grid.locations); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |             free(line); | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Width is without the newline at the end.
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |         strncat(temp_grid.locations, line, temp_grid.width + 1); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     free(line); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     grid *return_grid = malloc(sizeof(temp_grid)); | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     if (return_grid == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     memcpy(return_grid, &temp_grid, sizeof(temp_grid)); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     return return_grid; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | state grid_fetch_state(const grid *gp) { | 
					
						
							|  |  |  |     if (gp != NULL) { | 
					
						
							|  |  |  |         return gp->state; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |     return STATE_VERLOREN; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | void grid_put_state(grid *gp, const state t) { | 
					
						
							|  |  |  |     if (gp != NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         switch (t) { | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |             case STATE_BEGIN: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |                 gp->state = STATE_BEGIN; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             case STATE_AAN_HET_SPELEN: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |                 gp->state = STATE_AAN_HET_SPELEN; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |             case STATE_GEWONNEN: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |                 gp->state = STATE_GEWONNEN; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |             case STATE_VERLOREN: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |                 gp->state = STATE_VERLOREN; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2025-10-14 13:58:22 +02:00
										 |  |  |             case STATE_QUIT: | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |                 gp->state = STATE_QUIT; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | void grid_cleanup(grid *gp) { | 
					
						
							|  |  |  |     if (gp != NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |         if (gp->locations != NULL) | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |             free(gp->locations); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |         free(gp); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | int grid_width(const grid *gp) { | 
					
						
							|  |  |  |     if (gp == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     return gp->width; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | int grid_height(const grid *gp) { | 
					
						
							|  |  |  |     if (gp == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     return gp->height; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | int grid_contains(const grid *gp, const int x, const int y) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp != NULL && gp->locations != NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |         if (x >= 0 && y >= 0 && x < gp->width && y < gp->height) | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         { | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | char grid_fetch(const grid *gp, const int x, const int y) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { | 
					
						
							|  |  |  |         return gp->locations[internal_location(gp, x, y)]; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return '\0'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | int grid_put(grid *gp, const int x, const int y, const char c) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp != NULL && gp->locations != NULL && grid_contains(gp, x, y) == 1) { | 
					
						
							|  |  |  |         gp->locations[internal_location(gp, x, y)] = c; | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | char *grid_fetch_row(const grid *gp, const int y) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | 	if (gp != NULL && gp->locations != NULL && grid_contains(gp, 0, y) == 1) { | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 	    // we're going to remove the newline so this is long enough
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 		char *row = malloc((gp->width + 1) * sizeof(char)); | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | 		memcpy(row, &gp->locations[internal_location(gp, 0, y)], gp->width * sizeof(char)); | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 	    row[gp->width] = '\0'; | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 		return row; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | grid *grid_copy(const grid *gp) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | 	if (gp != NULL && gp->locations != NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 	    const size_t grid_memory = ((gp->width + 1) * gp->height + 1) * sizeof(char); | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |         char *locations = malloc(grid_memory); | 
					
						
							|  |  |  |         if (locations == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 	    grid *new_grid = malloc(sizeof(*gp)); | 
					
						
							|  |  |  | 	    if (new_grid == NULL) { | 
					
						
							|  |  |  | 	        return NULL; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | 	    memcpy(locations, gp->locations, grid_memory); | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 	    memcpy(new_grid, gp, sizeof(*gp)); | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  | 	    new_grid->locations = locations; | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | 	    return new_grid; | 
					
						
							| 
									
										
										
										
											2025-10-13 19:58:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  | void grid_find(const grid *gp, const char c, int *x, int *y) { | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp == NULL || gp->locations == NULL) { | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |         *x = -1; | 
					
						
							|  |  |  |         *y = -1; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char search[2] = {c}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     const int char_index = (int)strcspn(gp->locations, search); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 21:35:01 +02:00
										 |  |  |     if (gp->locations[char_index] == '\0') | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  |     { | 
					
						
							|  |  |  |         *x = -1; | 
					
						
							|  |  |  |         *y = -1; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-18 18:56:28 +02:00
										 |  |  |     *x = char_index % (gp->width + 1); | 
					
						
							|  |  |  |     *y = char_index / (gp->width + 1); | 
					
						
							| 
									
										
										
										
											2025-10-13 15:29:56 +02:00
										 |  |  | } |