Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Programmeringsteknik med C och Matlab
- * Fall 17
- * Assignment 3
- * File: ou3.c
- * Description: A simple implementation of Conway's Game of Life.
- * Author: William Fransson
- * CS username: c17wfn
- * Date: 2017-10-16
- * Input: Choice of initial configuration and then instruction to step
- * or exit.
- * Output: Prints the game field in each step.
- * Limitations: No validation of input.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- /* Constants, representation of states */
- #define ALIVE 'X'
- #define DEAD '.'
- /* Declaration of data structure */
- typedef struct{
- char current;
- char next;
- } cell;
- /* Declaration of functions */
- void initField(const int rows, const int cols, cell field[rows][cols]);
- void loadGlider(const int rows, const int cols, cell field[rows][cols]);
- void loadSemaphore(const int rows, const int cols, cell field[rows][cols]);
- void loadRandom(const int rows, const int cols, cell field[rows][cols]);
- void loadCustom(const int rows, const int cols, cell field[rows][cols]);
- void printField(const int rows, const int cols, cell field[rows][cols]);
- int optionSelect();
- void updateField(const int rows, const int cols, cell field[rows][cols]);
- void determineState(int r, int c, const int rows, const int cols, cell field[rows][cols]);
- int checkNrOfNeighbours(int r, int c, const int rows, const int cols, cell field[rows][cols]);
- /* Function: main
- * Description: Start and run games, interact with the user.
- * Input: About what initial structure and whether to step or exit.
- * Output: Information to the user, and the game field in each step.
- */
- int main(void) {
- const int rows = 20;
- const int cols = 20;
- int option = 1;
- cell field[rows][cols];
- initField(rows, cols, field);
- do{
- printField(rows, cols, field);
- updateField(rows, cols, field);
- option = optionSelect();
- }while(option);
- return 0;
- }
- /* Function: initField
- * Description: Initialize all the cells to dead, then asks the user about
- * which structure to load, and finally load the structure.
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void initField(const int rows, const int cols, cell field[rows][cols]) {
- for (int r = 0 ; r < rows ; r++) {
- for (int c = 0 ; c < cols ; c++) {
- field[r][c].current = DEAD;
- }
- }
- printf("Select field spec to load ([G]lider, [S]emaphore, [R]andom ");
- printf("or [C]ustom): ");
- int ch = getchar();
- switch (ch) {
- case 'g':
- case 'G':
- loadGlider(rows, cols, field);
- break;
- case 's':
- case 'S':
- loadSemaphore(rows, cols, field);
- break;
- case 'r':
- case 'R':
- loadRandom(rows, cols, field);
- break;
- case 'c':
- case 'C':
- default:
- loadCustom(rows, cols, field);
- break;
- }
- /* Ignore following newline */
- if (ch != '\n') {
- getchar();
- }
- }
- /* Function: loadGlider
- * Description: Inserts a glider into the field.
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void loadGlider(const int rows, const int cols, cell field[rows][cols]) {
- field[0][1].current = ALIVE;
- field[1][2].current = ALIVE;
- field[2][0].current = ALIVE;
- field[2][1].current = ALIVE;
- field[2][2].current = ALIVE;
- }
- /* Function: loadSemaphore
- * Description: Inserts a semaphore into the field.
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void loadSemaphore(const int rows, const int cols, cell field[rows][cols]) {
- field[8][1].current = ALIVE;
- field[8][2].current = ALIVE;
- field[8][3].current = ALIVE;
- }
- /* Function: loadRandom
- * Description: Inserts a random structure into the field.
- * Input: The field array and its size.
- * Output: The field array is updated. There is a 50 % chance that a cell
- * is alive.
- */
- void loadRandom(const int rows, const int cols, cell field[rows][cols]) {
- for(int r = 0; r < rows; r++){
- for(int c = 0; c < cols; c++){
- int randomNumber = rand() % 2;
- if(randomNumber == 1) {
- field[r][c].current = ALIVE;
- }
- else{
- field[r][c].current = DEAD;
- }
- }
- }
- }
- /* Function: loadCustom
- * Description: Lets the user specify a structure that then is inserted into
- * the field.
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void loadCustom(const int rows, const int cols, cell field[rows][cols]) {
- printf("Give custom format string: ");
- do {
- int r, c;
- scanf("%d,%d", &r, &c);
- field[r][c].current = ALIVE;
- } while (getchar() != '\n');
- }
- /* Function: printField
- * Description: Prints all the cells as a 20 x 20 field.
- *
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void printField(const int rows, const int cols, cell field[rows][cols]) {
- for(int r = 0; r < rows; r++){
- for(int c = 0; c < cols; c++){
- printf("%c ", field[r][c].current);
- }
- printf("\n");
- }
- }
- /* Function: optionSelect
- * Description: Lets user decide if the program will go to the next step or
- * exit.
- * Input: Variable for running the while-loop.
- * Output: Returns a new value for the run variable.
- */
- int optionSelect() {
- char ch;
- printf("Select one of the following options:\n");
- printf("\t(enter) Step\n");
- printf("\t(any) Exit\n");
- scanf("%c", &ch);
- if (ch == '\n') {
- return 1;
- }
- else{
- return 0;
- }
- }
- /* Function: updateField
- * Description: Updates the cells to their next values.
- *
- * Input: The field array and its size.
- * Output: The field array is updated.
- */
- void updateField(const int rows, const int cols, cell field[rows][cols]) {
- for(int r = 0; r < rows; r++) {
- for(int c = 0; c < cols; c++) {
- determineState(r, c, rows, cols, field);
- }
- }
- for(int r = 0; r < rows; r++) {
- for(int c = 0; c < cols; c++) {
- field[r][c].current = field[r][c].next;
- }
- }
- }
- /* Function: determineState
- * Description: Determines state(Alive or Dead) of the next generation of cells.
- *
- * Input: An element of the Field Array.
- * Output: Determines the next state of a cell.
- */
- void determineState(int r, int c, const int rows, const int cols, cell field[rows][cols]) {
- int neighbours;
- neighbours = checkNrOfNeighbours(r, c, rows, cols, field);
- if(field[r][c].current == ALIVE && (neighbours == 2 || neighbours == 3)) {
- field[r][c].next = ALIVE;
- }
- else if(field[r][c].current == DEAD && (neighbours == 3)) {
- field[r][c].next = ALIVE;
- }
- else{
- field[r][c].next = DEAD;
- }
- }
- /* Function: checkNrOfNeighbours
- * Description: Calculates the number of neighbours next to the cell.
- *
- * Input: An element of the Field Array.
- * Output: Returns the number of neighbours related to a certain element.
- */
- int checkNrOfNeighbours(int r, int c, const int rows, const int cols, cell field[rows][cols]) {
- int n = 0;
- for(int i = r - 1; i <= r + 1 ; i++) {
- for(int j = c - 1 ; j <= c + 1 ; j++){
- if(i >= 0 && i < 20 && j >= 0 && j < 20){
- if(field[i][j].current == ALIVE){
- n++;
- }
- }
- }
- }
- /* To prevent the cell to count itself as a neighbour*/
- if(field[r][c].current == ALIVE) {
- n--;
- }
- return n;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement