rendered paste body#include <stdio.h>#include <stdlib.h>#include <time.h>#define LIVE_MIN 3#define LIVE_MAX 3#define STAY_ALIVE_MIN 2#define STAY_ALIVE_MAX 3#define FILE_DEAD '0'#define FILE_ALIVE '1'#define PRNT_DEAD ' '#define PRNT_ALIVE 'Q'#define CLR_SCR_LINES 0/* 0.5s sleep*//* #define SLEEP {0, 100000000} */#define MAP_CELL_TYPE int/*typedef MAP_CELL_TYPE* Map;*/typedef struct { MAP_CELL_TYPE* map; int width; int height; char live_char; char dead_char;} Map;typedef enum { DEAD, ALIVE} State;typedef enum { SUCCESS, ERROR} Result;State live(int neighbours, State state);Result load_map(Map*, FILE*);State next_state(Map* map);int count_neighbours(Map map, int width, int height);void print_map(Map);void destroy_map(Map);State get_state(char file_state);MAP_CELL_TYPE* getxy(Map, int width, int height);MAP_CELL_TYPE getxy_value(Map, int width, int height);int main(int argc, char *argv[]){ int i, STEPS; double SLEEP_TIME; FILE * file; Map map; map.live_char = PRNT_ALIVE; map.dead_char = PRNT_DEAD; map.width = 0; map.height = 0; map.map = NULL; struct timespec slp; if (argc != 4) { fprintf(stderr, "Usage: life <input file> <steps (0 for inf)> <sleep time in seconds>\n"); return 1; } file = fopen(argv[1], "r"); if (file == NULL) { fprintf(stderr, "Could not open %s.\n", argv[1]); return 1; } STEPS = atoi(argv[2]); SLEEP_TIME = atof(argv[3]); slp.tv_sec = (long)SLEEP_TIME; slp.tv_nsec = (SLEEP_TIME-slp.tv_sec)*1e9; if (load_map(&map, file) == ERROR) { /* destroy_map(map); */ fclose(file); return 1; } i=0; while (1) { print_map(map); if (DEAD == next_state(&map)) { print_map(map); break; } if (STEPS && ++i>STEPS) break; nanosleep(&slp, NULL); } fclose(file); destroy_map(map); return 0;}State live(int neighbours, State state){ switch (state) { case DEAD: if (neighbours >= LIVE_MIN && neighbours <= LIVE_MAX) return ALIVE; return DEAD; case ALIVE: if (neighbours >= STAY_ALIVE_MIN && neighbours <= STAY_ALIVE_MAX) return ALIVE; return DEAD; } return DEAD; /* just in case.. */}Result load_map(Map* map, FILE* file){ int width, height, c, tmp; map->map = NULL; if (file == NULL) return ERROR; width=0; c = fgetc(file); while (c!='\n' && c!=EOF) { ++width; c = fgetc(file); } map->width = width; fseek(file, 0, SEEK_SET); height = 0; tmp = -1; do { ++tmp; c = fgetc(file); if (c == '\n' || c == EOF) { ++height; /*printf("width: %d, tmp: %d\n", width, tmp);*/ if (tmp != width) { --height; break; } if (c == EOF) { break; } tmp = -1; } if (tmp > width) { /* TODO: check if needed */ break; } } while (c!=EOF); map->height = height; printf("PUZZLE: %dx%d\n", map->width, map->height); map->map = malloc(sizeof(MAP_CELL_TYPE)*height*width); if (map->map == NULL) return ERROR; fseek(file, 0, SEEK_SET); for (height=0; height < map->height; ++height) { for (width=0; width < map->width; ++width) { *getxy(*map, width, height) = get_state(fgetc(file)); /* map[height*map->width + width] = get_state(fgetc(file)); */ } if (fgetc(file) != '\n') fprintf(stderr, "map[%d][%d]!=\\n\n", height, width); } return SUCCESS;}State next_state(Map* map){ int width, height; State main_state = DEAD; Map map_tmp; /* make a temp map */ map_tmp.map = map->map; /* swap maps */ map_tmp.width = map->width; map_tmp.height = map->height; map_tmp.live_char = map->live_char; map_tmp.dead_char = map->dead_char; map->map = malloc(sizeof(MAP_CELL_TYPE) * map->width * map->height); if (map->map == NULL) { fprintf(stderr, "Unable to allocate memory(next_state)\n"); map->map = map_tmp.map; return DEAD; } for (height=0; height < map->height; ++height) { for (width=0; width < map->width; ++width) { if (live(count_neighbours(map_tmp,width,height), *getxy(map_tmp,width, height)) == ALIVE) { main_state = ALIVE; *getxy(*map,width,height) = ALIVE; } else { *getxy(*map,width,height) = DEAD; } } } free(map_tmp.map); return main_state;}int count_neighbours(Map map, int width, int height){ int s=0; s+=(getxy_value(map,width-1, height-1)==ALIVE?1:0); s+=(getxy_value(map,width+0, height-1)==ALIVE?1:0); s+=(getxy_value(map,width+1, height-1)==ALIVE?1:0); s+=(getxy_value(map,width-1, height+0)==ALIVE?1:0); s+=(getxy_value(map,width+1, height+0)==ALIVE?1:0); s+=(getxy_value(map,width-1, height+1)==ALIVE?1:0); s+=(getxy_value(map,width+0, height+1)==ALIVE?1:0); s+=(getxy_value(map,width+1, height+1)==ALIVE?1:0); return s;}void print_map(Map map){ int width, height; for (height=CLR_SCR_LINES;height; --height) printf("\n"); printf("----%dx%d----\n", map.width, map.height); for (height=0; height < map.height; ++height) { for (width=0; width < map.width; ++width) { if (*getxy(map, width, height) == DEAD) printf("%c", map.dead_char); else printf("%c", map.live_char); /* map[height*map.width + width] = get_state(fgetc(file)); */ } printf("\n"); }}void destroy_map(Map map){ if (map.map == NULL) return; free(map.map);}State get_state(char file_state){ if (file_state == FILE_DEAD) return DEAD; else return ALIVE;}MAP_CELL_TYPE* getxy(Map map, int width, int height){ return &(map.map[height*map.width + width]);}MAP_CELL_TYPE getxy_value(Map map, int width, int height){ if (width < 0 || height < 0 || width >= map.width || height >= map.height) return 0; else return *getxy(map,width,height);}