In this program, you will create a cellular automata called Brians Brain. This cellular automata consists of squares (cells) on a 2D grid that are
In this program, you will create a cellular automata called Brians Brain. This cellular automata consists of squares (cells) on a 2D grid that are in one of three possible states: ON, OFF, or DYING. At each step, squares change their states depending on their neighbors. This assignment will guide you through this process,
Proceed by moving from the first part to the last part, in order. You must modify the supplied code. You do not need to define functions, and only need to add code to implement certain functions throughout the code. These are marked with:
// TODO: complete this function
To assist with your programming, the following testing files have been provided: list_tester.c, cell_tester.c, and cell_grid_tester.c. You may use these to compile executables that will test your code and give you feedback. Note that incorrect implementations may make these tests crash.
Files to turn in:
brians_brain.c
brians_brain.h
cell_grid.c
cell_grid.h
Makefile
cell.c
cell.h
list.c
list.h
(code will be provided following the instructions pertaining to that part.)
Part 1: cell.c
The Cell type is defined as a struct in cell.h. This represents a single cell (box) on the 2-dimensional grid. Each Cell has three members: an x-coordinate, a y-coordinate, and a CellState (one of ON, OFF, or DYING). The x and y-coordinate specify the Cells position on the grid. Each cell has 8 neighbors, the 4 cells adjacent above, below, left and right of it, and the 4 cells adjacent diagonally.
1. Implement bool Cell_AreNeighbors(Cell C1, Cell C2).
cell.c:
#include "cell.h"
#include
#include
#include
#include
/*
* Input:
* int x, an x-Cell
* int y, a y-Cell
* Output:
* A Cell
* Summary:
* Initializes a Cell to (x,y)
*/
Cell Cell_Create(int x, int y, CellState s) {
Cell result;
result.x = x;
result.y = y;
result.s = s;
return result;
}
/*
* Input:
* Cell C1, a Cell
* Cell C2, another Cell
* Output:
* true if C2 is a neighbor of C1, false otherwise
* Summary:
* Checks if C1 and C2 are neighbors, that is, if they
* are in adjacent squares (including squares that are
* diagonally adjacent) and not equal
*/
bool Cell_AreNeighbors(Cell C1, Cell C2) {
// TODO: complete this function
}
/*
* Input:
* Cell* C, a pointer to a Cell
* Summary:
* Swaps the entries of the Cell pointed to by C
*/
void Cell_NextState(Cell* C) {
switch (C->s) {
case OFF:
C->s = ON;
break;
case ON:
C->s = DYING;
break;
case DYING:
C->s = OFF;
break;
}
return;
}
/*
* Input:
* FILE* fp, a file pointer pointing to a read-only open file
* Output:
* Returns a newly allocated list
* Summary:
* Creates a cell from the file data
*/
Cell Cell_ReadCell(char* str) {
char s = 'A';
int row, col;
if (sscanf(str, "%d %d %c", &row, &col, &s) != 3) {
fprintf(stderr, "Error reading cell ");
exit(0);
}
CellState state;
switch (s) {
case 'O':
state = ON;
break;
case 'D':
state = DYING;
break;
default:
fprintf(stderr, "Error: expected O or D for cell state ");
exit(0);
}
return Cell_Create(row, col, state);
}
/*
* Input;
* Cell C
* Ouptut:
* true if C has the corresponding CellState
*/
bool Cell_IsOff(Cell C) {
return C.s == OFF;
}
bool Cell_IsOn(Cell C) {
return C.s == ON;
}
bool Cell_IsDying(Cell C) {
return C.s == DYING;
}
cell.h:
/*
* cell.h
* Name / StudentID
* A data structure modeling 2D integer Cartesian Cells
*/
#ifndef _COORDINATE_H_
#define _COORDINATE_H_
#include
#include
typedef enum {OFF, ON, DYING} CellState;
typedef struct {
int x, y;
CellState s;
} Cell;
/*
* Input:
* int x, an x-Cell
* int y, a y-Cell
* Output:
* A Cell
* Summary:
* Initializes a Cell to (x,y)
*/
Cell Cell_Create(int x, int y, CellState s);
/*
* Input:
* Cell C1, a Cell
* Cell C2, another Cell
* Output:
* true if C2 is a neighbor of C1, false otherwise
* Summary:
* Checks if C1 and C2 are neighbors, that is, if they
* are in adjacent squares (including squares that are
* diagonally adjacent) and not equal
*/
bool Cell_AreNeighbors(Cell C1, Cell C2);
/*
* Input:
* Cell* C, a pointer to a Cell
* Summary:
* Changes the Cell state of C to the next state.
* OFF -> ON -> DYING -> OFF
*/
void Cell_NextState(Cell* C);
/*
* Input:
* char* str, a string to read the cell from
* Output:
* Returns a newly allocated list
* Summary:
* Creates a cell from the file data
*/
Cell Cell_ReadCell(char* str);
/*
* Input;
* Cell C
* Ouptut:
* true if C has the corresponding CellState
*/
bool Cell_IsOff(Cell C);
bool Cell_IsOn(Cell C);
bool Cell_IsDying(Cell C);
#endif /* _COORDINATE_H_ */
cell_tester.c:
/*
* cell_tester.c
* Name / StudentID
* A tester for cell.h
* Tests the various Cell functions prototyped in cell.h and implemented in cell.c
*/
#include
#include
#include
#include "cell.h"
#define MAX_BUFFER_SIZE 64
int main() {
char buffer[MAX_BUFFER_SIZE];
bool error = false;
Cell C, D;
/* Test Cell_Create */
printf("Testing Cell_Create. Enter a Cell: ");
fgets(buffer, MAX_BUFFER_SIZE, stdin);
C = Cell_ReadCell(buffer);
printf("The distance from the origin to your Cell is %lf ", sqrt(C.x*C.x + C.y*C.y));
printf("Done testing Cell_Create. ");
/* Test Cell_AreNeighbors */
printf("Testing Cell_AreNeighbors. ");
if (Cell_AreNeighbors(C, C)) {
/* A Cell is not its own neighbor */
printf("Error in Cell_AreNeighbors: a Cell is not its own neighbor. ");
error = true;
}
if (Cell_AreNeighbors(Cell_Create(0, 0, OFF), Cell_Create(2, 2, OFF))) {
/* These Cells are too far */
printf("Error in Cell_AreNeighbors: (0,0) and (2,2) are not neighbors. ");
error = true;
}
if (!Cell_AreNeighbors(Cell_Create(0, 0, OFF), Cell_Create(0, 1, OFF))) {
/* Test neighbors */
printf("Error in Cell_AreNeighbors: (0,0) and (0,1) are neighbors. ");
error = true;
}
if (!Cell_AreNeighbors(Cell_Create(0, 0, OFF), Cell_Create(1, 1, OFF))) {
/* Test diagonal neighbors */
printf("Error in Cell_AreNeighbors: (0,0) and (1,1) are neighbors. ");
error = true;
}
printf("Done testing Cell_AreNeighbors. ");
printf("Testing Cell_NextState. ");
D = Cell_Create(C.x, C.y, OFF);
Cell_NextState(&D);
if (Cell_IsOff(D)) {
printf("Error in Cell_NextState, check your results. ");
error = true;
}
printf("Done testing Cell_NextState. ");
if (!error) {
printf("No errors found. This does not gaurantee a full score, but you have passed all the tests in cell_tester. Congratulations! ");
}
return 0;
}
Part 2: list.c
1. Implement void List_Print(List* list).
Hints: use a for loop to iterate through the nodes of the list. Use the List member head for the setup of your for loop, the ListNode member next for the increment of your for loop, and you should compare with NULL for the test case of your for loop.
list.c
#include "list.h"
#include
#include
#include "cell.h"
#define MAX_BUFFER_SIZE 64
/*
* Output:
* Returns a newly allocated List
* Summary:
* Allocates space for an empty new List and returns it
*/
List* List_Create() {
List* result = malloc(sizeof(List));
if (result != NULL) {
result->head = NULL;
result->size = 0;
}
return result;
}
/*
* Input:
* FILE* fp, a file pointer pointing to a read-only open file
* Output:
* Returns a newly allocated list
* Summary:
* Reads Cells from a file and puts them in a new List
*/
List* List_Read(FILE* fp) {
char buffer[MAX_BUFFER_SIZE];
List* result;
if (fp == NULL) {
printf("List_Read Error: NULL parameter passed. ");
exit(0);
}
result = List_Create();
while (fgets(buffer, MAX_BUFFER_SIZE, fp)) {
Cell C = Cell_ReadCell(buffer);
List_PushFront(result, C);
}
return result;
}
/*
* Input:
* List* list, the List to delete
* Summary:
* Calls free on every node to deallocate memory
* used by the nodes of the List, then deallocates
* the list itself
*/
void List_Delete(List* list) {
ListNode* currentNode = list->head;
while (currentNode != NULL) {
ListNode* nextNode = currentNode->next;
free(currentNode);
currentNode = nextNode;
}
free(list);
return;
}
/*
* Input:
* List* list, a List to add data to
* Cell data, data to add to the list
* Output:
* Returns the size of list after adding data
* Summary:
* Adds a data to the front of list
*/
int List_PushFront(List* list, Cell data) {
ListNode* newNode = ListNode_Create(data, list->head);
if (newNode != NULL) {
list->head = newNode;
list->size++;
}
return list->size;
}
/*
* Input:
* List* list, a List to print
* Summary:
* Prints elements from list, starting with the head
*/
void List_Print(List* list) {
// TODO: complete this function
}
/*
* Input:
* Cell data, data for the ListNode
* ListNode* node, the next node after the ListNode
* Output:
* Returns a ListNode* to a newly allocated ListNode
* Summary:
* Allocates space for a ListNode and initializes its
* data and node members
*/
ListNode* ListNode_Create(Cell data, ListNode* node) {
ListNode* listNode = (ListNode*) malloc(sizeof(ListNode));
if (listNode != NULL) {
listNode->data = data;
listNode->next = node;
}
return listNode;
}
list.h:
/*
* list.h
* Name / StudentID
* An implementation of a Linked List containg Cells
*/
#ifndef _LIST_H_
#define _LIST_H_
#include "cell.h"
#include
struct ListNode;
typedef struct {
struct ListNode* head;
int size;
} List;
typedef struct ListNode {
Cell data;
struct ListNode* next;
} ListNode;
/*
* Output:
* Returns a newly allocated List
* Summary:
* Allocates space for an empty new List and returns it
*/
List* List_Create();
/*
* Input:
* Cell data, data for the ListNode
* ListNode* node, the next node after the ListNode
* Output:
* A ListNode* to a newly allocated ListNode
* Summary:
* Allocates space for a ListNode and initializes its
* data and node members
*/
ListNode* ListNode_Create(Cell data, ListNode* node);
/*
* Input:
* FILE* fp, a file pointer pointing to a read-only open file
* Output:
* Returns a newly allocated list
* Summary:
* Reads Cells from a file and puts them in a new List
*/
List* List_Read(FILE* fp);
/*
* Input:
* List* list, the List to delete
* Summary:
* Calls free on every node to deallocate memory
* used by the nodes of the List, then deallocates
* the list itself
*/
void List_Delete(List* list);
/*
* Input:
* List* list, a List to add data to
* Cell data, data to add to the list
* Output:
* The size of list after adding data
* Summary:
* Adds data to the front of list
*/
int List_PushFront(List* list, Cell data);
/*
* Input:
* List* list, a List to print
* Summary:
* Prints elements from list, starting with the head
*/
void List_Print(List* list);
#endif /* _LIST_H_ */
list_tester.c:
/*
* list_tester.c
* Name / StudentID
* A tester for list.h
* Reads Cells from stdin into a List and prints them out
*/
#include
#include
#include "cell.h"
#include "list.h"
#define MAX_BUFFER_SIZE 64
void flushStdin();
int main() {
char buffer[MAX_BUFFER_SIZE];
char action;
List* list = List_Create();
do {
printf("Type 'c' to enter a cell or 'q' to quit: ");
action = getchar();
flushStdin();
if (action != 'c' && action != 'q') {
printf("Invalid command. ");
} else if (action == 'c') {
printf("Enter a cell: ");
fgets(buffer, MAX_BUFFER_SIZE, stdin);
List_PushFront(list, Cell_ReadCell(buffer));
}
} while(action != 'q');
List_Print(list);
List_Delete(list);
return 0;
}
void flushStdin() {
char c;
while ((c = getchar()) != EOF && c != ' ') {};
}
Part 3: cell_grid.c
The CellGrid type is defined as a struct in cell_grid.h. This represents the 2- dimensional grid of cells. At each phase (generation) of the simulation, all Cells in the CellGrid will be in one of the three states ON, OFF, or DYING. In Part 4, we use the current generations (current CellGrid) states to compute the next generation (a new CellGrid).
1. ImplementCellGrid* CellGrid_Create(int numRows, int numCols).Thisshould use malloc to allocate a CellGrid.
2. Implement void CellGrid_Delete(CellGrid* G). This should use free to de- allocate a CellGrid.
3. Implement CellState CellGrid_GetState(const CellGrid* G, int row, int col). This function returns the state of the cell specified by the input row and column.
4. Implement void CellGrid_SetCell(CellGrid* G, Cell C). This function sets C as a Cell of G. Note that C has x and y-coordinates that need to be used to specify which square of G to modify.
5. Implement bool CellGrid_Inbounds(const CellGrid* G, int row, int col). This checks whether or not the input row and column is in the grid G.
6. Implement void CellGrid_Print(const CellGrid* G, FILE* fp). This prints all of the cells according to their CellState. To begin, print the state of cell (0,0) first (in the top left corner) and then the rest of that row (all cells (0,j) where j is in bounds) before printing a new line and then proceed with the remaining lines.
cell_grid.c:
#include "cell_grid.h"
#include
#include
/*
* Input:
* int numRows, number of rows for new CellGrid
* int numCols, number of cols for new CellGrid
* Output:
* A CellGrid* pointing to a newly allocated CellGrid
* Summary:
* Allocates a new CellGrid with numRows rows and
* numCols cols and returns a pointer to it
*/
CellGrid* CellGrid_Create(int numRows, int numCols) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to delete
* Summary:
* De-allocates G, including grid, row by row
*/
void CellGrid_Delete(CellGrid* G) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to delete
* int row, an index for a row of *M
* int col, an index for a column of *M
* Output:
* The CellState in location row, col
*/
CellState CellGrid_GetState(const CellGrid* G, int row, int col) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to update
* Cell C, the cell to set in G
* Summary:
* Updates the (C.x, C.y) entry of G to be C
*/
void CellGrid_SetCell(CellGrid* G, Cell C) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to update
* int row, an index for a row of *M
* int col, an index for a column of *M
* Summary:
* Updates the (row,col) entry of G
*/
void CellGrid_Update(CellGrid* G, int row, int col) {
if (!CellGrid_Inbounds(G, row, col)) {
printf("Error in CellGrid_Update: index out of bounds ");
exit(0);
}
Cell_NextState(&(G->grid[row][col]));
return;
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid
* int row, an index for a row of *G
* int col, an index for a column of *G
* Summary:
* Checks if (row,col) is a Cell in G
*/
bool CellGrid_Inbounds(const CellGrid* G, int row, int col) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to print
* FILE* fp, a file opened for writing
* Summary:
* Prints entries of the CellGrid pointed to by G
* as O's for ONs and # for DYINGs
*/
void CellGrid_Print(const CellGrid* G, FILE* fp) {
// TODO: complete this function
}
cell_grid.h:
/*
* cell_grid.h
* Name / StudentID
* An implementation of a 2D Grid of Cells
*/
#ifndef _CELL_GRID_H_
#define _CELL_GRID_H_
#include "cell.h"
typedef struct {
Cell** grid; /* The grid */
int numRows; /* number of rows in grid */
int numCols; /* number of columns in grid */
} CellGrid;
/*
* Input:
* int numRows, number of rows for new CellGrid
* int numCols, number of cols for new CellGrid
* Output:
* A CellGrid* pointing to a newly allocated CellGrid
* Summary:
* Allocates a new CellGrid with numRows rows and
* numCols cols and returns a pointer to it
*/
CellGrid* CellGrid_Create(int numRows, int numCols);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to delete
* Summary:
* De-allocates G, including grid, row by row
*/
void CellGrid_Delete(CellGrid* G);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to delete
* int row, an index for a row of *M
* int col, an index for a column of *M
* Output:
* The CellState in location row, col
*/
CellState CellGrid_GetState(const CellGrid* G, int row, int col);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to update
* Cell C, the cell to set in G
* Summary:
* Updates the (C.x, C.y) entry of G to be C
*/
void CellGrid_SetCell(CellGrid* G, Cell C);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to update
* int row, an index for a row of *M
* int col, an index for a column of *M
* Summary:
* Updates the (row,col) entry of the CellGrid pointed to
* by G with the entry element
*/
void CellGrid_Update(CellGrid* G, int row, int col);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid
* int row, an index for a row of *G
* int col, an index for a column of *G
* Summary:
* Checks if (row,col) is a Cell in G
*/
bool CellGrid_Inbounds(const CellGrid* G, int row, int col);
/*
* Input:
* CellGrid* G, a pointer to a CellGrid to print
* FILE* fp, a file opened for writing
* Summary:
* Prints entries of the CellGrid pointed to by G
* as O's for ONs and # for DYINGs
*/
void CellGrid_Print(const CellGrid* G, FILE* fp);
#endif /* _CELL_GRID_H_ */
cell_grid_tester.c:
/*
* cell_grid_tester.c
* Name / StudentID
* A tester for cell_grid.h
* Reads a CellGrid from stdin and prints it out
*/
#include
#include
#include "cell_grid.h"
void flushStdin();
int main() {
int numRows, numCols, row, col;
char action;
CellGrid* G;
printf("Testing CellGrid_Create and CellGrid_Print ");
printf("Enter the number of rows & columns: ");
scanf("%d %d", &numRows, &numCols);
flushStdin();
G = CellGrid_Create(numRows, numCols);
do {
printf("Type 'c' to enter a cell or 'q' to quit: ");
action = getchar();
if (action != 'c' && action != 'q') {
printf("Invalid command. ");
} else if (action == 'c') {
printf("Enter a row and index to update: ");
int result = scanf("%d %d", &row, &col);
flushStdin();
if (result == 2) {
CellGrid_SetCell(G, Cell_Create(row, col, ON));
}
}
} while(action != 'q');
printf("Your grid: ");
CellGrid_Print(G, stdin);
printf("Done testing CellGrid_Create and CellGrid_Print ");
printf("Testing CellGrid_Update ");
CellState currentState = G->grid[0][0].s;
CellState newValue = (CellState) (((int) currentState) + 1) % 3;
CellGrid_Update(G, 0, 0);
if (G->grid[0][0].s != newValue) {
printf("Error testing CellGrid_Update: value has not changed ");
}
printf("Done testing CellGrid_Update. ");
printf("Testing CellGrid_Inbounds ");
if (CellGrid_Inbounds(G, numRows, numCols)) {
/* Testing out of bounds */
printf("Error testing CellGrid_Inbounds: (%d,%d) should be out of bounds ", numRows, numCols);
}
if (!CellGrid_Inbounds(G, 0, 0)) {
/* Testing in bounds */
printf("Error testing CellGrid_Inbounds: (0,0) should be in bounds ");
}
printf("Done testing CellGrid_Inbounds. ");
printf("Testing CellGrid_Delete ");
CellGrid_Delete(G);
printf("Done testing CellGrid_Delete. ");
printf("Done running cell_grid_tester. This does not gaurantee full points or that your code is bug-free. ");
return 0;
}
void flushStdin() {
char c;
while ((c = getchar()) != EOF && c != ' ') {};
}
part 4: brians_brain.c
Brians brain runs for a finite number of generations. Each generation t completely determines the states for the Cells in generation t + 1 according to the following rules:
If a Cell is ON in generation t, then it is DYING in generation t + 1.
If a Cell is DYING in generation t, then it is OFF in generation t + 1.
If a Cell is OFF in generation t and has exactly 2 neighbors that are On in generation t, then it is ON in generation t + 1.
1. Implement CellGrid* NextGeneration(CellGrid* generation). This calculates a new generation from generation using the rules described above.
2. ImplementList* GetNeighboringCells(Cell cell, CellGrid* generation).This should return a list of all cells that are adjacent to cell, except for cell itself. Use List_Create to allocate your List and use List_PushFront to add elements to your List.
brians_brain.c:
#include "brians_brain.h"
#include
#include
#include
#include
#include "cell_grid.h"
#include "cell.h"
/*
* Input:
* int numRows, the number of rows in the game
* int numCols, the number of cols in the game
* Output:
* Returns a CellGrid* that corresponds to the
* first generation game state
* Summary:
* Returns the game state of the first generation
*/
CellGrid* FirstGeneration(int numRows, int numCols, List* seedCells) {
CellGrid* result = CellGrid_Create(numRows, numCols);
ListNode* currentNode;
for (currentNode = seedCells->head; currentNode != NULL; currentNode = currentNode->next) {
CellGrid_SetCell(result, currentNode->data);
}
return result;
}
/*
* Input:
* CellGrid* generation, a pointer to a game state
* Output:
* Returns a CellGrid*, a pointer to a game state
* Summary:
* Calculates the game state of the generation directly
* after *generation and returns it
*/
CellGrid* NextGeneration(CellGrid* generation) {
// TODO: complete this function
}
/*
* Input:
* CellGrid* generation, a pointer to a game state
* Cell coord, a Cell of the game state
* Output:
* Returns true if the Cell is CellIsOn
* Summary:
* Checks if coord is a valid index of *generation and
* its corresponding Cell is CellIsOn
*/
bool CellIsOn(CellGrid* generation, int row, int col) {
if (!CellGrid_Inbounds(generation, row, col)) {
printf("CellIsOn Error: invalid Cell ");
exit(0);
}
return generation->grid[row][col].s == ON;
}
/*
* Input:
* Cell coord, a Cell of the game state
* CellGrid* generation, a pointer to a game state
* Output:
* Returns a List* to a List of neighboring Cells
* Summary:
* Calculates neighboring Cells of *generation at coord and
* returns them as a List
*/
List* GetNeighboringCells(Cell cell, CellGrid* generation) {
// TODO: complete this function
// Hint: Use List_Create to instantiate the list and List_PushFront to add elements to the list
}
/*
* Input:
* CellGrid* generation, a pointer to a game state
* List* neighbors, a List of neighbors of a Cell
* Output:
* Returns the number of neighboring Cells that are on
* Summary:
* Counts the number of Cells in *neighbors that
* correspond to live Cells in *generation
*/
int CountOnNeighborCells(CellGrid* generation, List* neighbors) {
ListNode* ptr;
int result = 0;
if (generation == NULL || neighbors == NULL) {
printf("Error in CountOnNeighborCells: NULL parameter passed ");
exit(0);
}
for (ptr = neighbors->head; ptr != NULL; ptr = ptr->next) {
if (Cell_IsOn(ptr->data)) {
result++;
}
}
return result;
}
brians_brain.h:
/*
* brians_brain.h
* Name / StudentID
* An implementation of Conway's Game of Life
*/
#ifndef _BRIANS_BRAIN_H_
#define _BRIANS_BRAIN_H_
#include
#include "cell_grid.h"
#include "cell.h"
#include "list.h"
/*
* Input:
* int numRows, the number of rows in the game
* int numCols, the number of cols in the game
* Output:
* Returns a CellGrid* that corresponds to the
* first generation game state
* Summary:
* Returns the game state of the first generation
*/
CellGrid* FirstGeneration(int numRows, int numCols, List* seedCells);
/*
* Input:
* CellGrid* generation, a pointer to a game state
* Output:
* Returns a CellGrid*, a pointer to a game state
* Summary:
* Calculates the game state of the generation directly
* after *generation and returns it
*/
CellGrid* NextGeneration(CellGrid* generation);
/*
* Input:
* CellGrid* generation, a pointer to a game state
* Cell coord, a Cell of the game state
* Output:
* Returns true if the Cell is CellIsOn
* Summary:
* Checks if coord is a valid index of *generation and
* its corresponding Cell is CellIsOn
*/
bool CellIsOn(CellGrid* generation, int row, int col);
/*
* Input:
* Cell coord, a Cell of the game state
* CellGrid* generation, a pointer to a game state
* Output:
* Returns a List* to a List of neighboring Cells
* Summary:
* Calculates neighboring Cells of *generation at coord and
* returns them as a List
*/
List* GetNeighboringCells(Cell coord, CellGrid* generation);
/*
* Input:
* CellGrid* generation, a pointer to a game state
* List* neighbors, a List of neighbors of a Cell
* Output:
* Returns the number of neighboring Cells that are on
* Summary:
* Counts the number of Cells in *neighbors that
* correspond to live Cells in *generation
*/
int CountOnNeighborCells(CellGrid* generation, List* neighbors);
#endif /* _BRIANS_BRAIN_H_ */
part 5: Makefile
Create a Makefile to create your project. Your makefile should have the following targets.
cell.o Builds the cell.o object file from cell.c.
list.o Builds the list_tester object file from list.c.
cell_grid.o Builds the cell_grid.o object file from cell_grid.c.
brians_brain.o Builds the brians_brain.o object file from brians_brain.c.
cell_tester Builds the cell_tester executable.
list_tester Builds the list_tester executable.
cell_grid_tester Builds the cell_grid_tester executable.
brians_brain_cellular_automata Builds the brians_brain_cellular_automata exe- cutable.
all Createsthetesterexecutablesandthemainprogram,brians_brain_cellular_automata. clean Deletes all *.o object files and executable files .
(hopefully the instructions help and the files provided make sense, i really need help with this one.)
Step by Step Solution
There are 3 Steps involved in it
Step: 1
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started