Your job is to create the Game of Life in C. The initial state of the game will be read in from a file. The file must adhere to the following convention:
This means that for an M x N size grid the size of the file should be ( MXN) + 2 bytes. So that the grid may be printed on a terminal screen we will limit our size to 30x30. The file name must be passed to the program as a command-line parameter, such that the program will be started with the syntax:
./life starter_file
Once the program has started, the board from the starter file will be read. If that is not possible the program should print a message and exit.
If the file is valid, the current state of the board will be displayed followed by a menu with the following options:
Any user errors should be caught, and a message provided that informs the user of correct usage.
The program must be divided into three parts.
1. A generic file library - Files exist as a collection of bytes on a disk (not characters). You will need to read and write files in C in several classes at GV; this code should be generic enough to save any byte array to disk. The code will therefore not be specific to saving and reading a "grid", and conversions may be necessary depending on how you choose to write your board data structure.
2. A library of common functions used in Life - Board creation and printing functions, mutation function, and (possibly) other helper functions.
3. A main file - This file will provide the core logic of the Life game, making use of the functions from the other libraries.
The following files with the following functions must exist. Functions in bold text need to be completed, the others will be provided to you. The functions MAY NOT BE MODIFIED (though additional functions may be added if needed):
life.h
#ifndef #define
H LIFE H LIFE
char** get_grid(int x, int y); void print grid (int x, int y, char** grid);
char** mutate (int x, int y, char** grid); int get_neighbors (int i, int i, int x, int y, char** grid);
#endif
life.c
Implementation of above functions such that:
char** get_grid(int x, int y) - Creates a new x by y grid, allocating all memory through malloc. Checks for errors and exits gracefully with appropriate return message if memory cannot be allocated. Returns the grid.
void print_grid(int x, int y, char** grid) - Prints a human-readable grid.
char** mutate (int x, int y, char** grid) - Given a grid, returns a new grid with Conway's rules applied to each cell. This function will need to create a new grid; the old grid should not be modified while being examined.
int get_neighbors (int i, int j, int x, int y, char** grid) - Given a coordinate ()) and a grid, determine how many neighbors the cell has. Return -1 if the cell can't exist in the grid. Correctly handle grid boundaries.
file_utilies.h
#ifndef
#define
H FILE LIBRARY __H_FILE LIBRARY
#include < stdio.h>
size_t read_file(char* file_name, char** contents); size_t write_file(char* file_name, char* contents, size_t size);
#endif
files_utilities.c
Implementation of above functions such that:
size_t read_file(char* file_name, char** contents) - Reads in the bytes of a file into an array of character bytes pointed to by contents. Uses malloc to create the memory for the string. Returns the number of bytes read. The calling function must have access to all data read in via the variable passed to contents.
size_t write_file(char* file_name, char* contents, size_t size) - Writes a byte array to the file name provided. Note, the signature is correct.
main.c
Implementation of above functions such that:
Main program logic. This entire file is given to you.
Tips