几乎相同的实现与不同结果之间的差异

时间:2018-01-10 13:39:51

标签: c struct conways-game-of-life

我有两个生命游戏实现,使用的结构差异很小:

typedef struct{
  char state;
  int neighbours;
} cell;

typedef struct{
  char current;
  char next;
  int neighbours;
} cell;

更大的结构只需要很少的额外工作线:

 for (int r = 0; r < rows; r++) {
      for(int c = 0; c < cols; c++) {
          if (field[r][c].next == ALIVE) {
              field[r][c].current = ALIVE;
          }
          else {
              field[r][c].current = DEAD;
          }
      }
   }
}

然而,如果你跑的话,那是完全不同的结果。为什么呢?

有效的代码:

#include <stdio.h>
#include <stdlib.h>

#define ALIVE 'X'
#define DEAD '.'


typedef struct{
  char state;
  int neighbours;
} cell;


void initField(const int rows, const int cols, cell field[rows][cols]);
void printField(const int rows, const int cols, cell field[rows][cols]);
void getNeighbours(const int rows, const int cols, cell field[rows][cols]);
void updateField(const int rows, const int cols, cell field[rows][cols]);


int main(void) {

  //Keeps track for of user choice.
  char key;

  //World size.
  const int R = 20;
  const int C = 20;

  //Creates the RxC cell field.
  cell cells[R][C];

  initField(R, C, cells);

  do {
    printField(R, C, cells);
    scanf("%c", &key);
    updateField(R, C, cells);
  } while(key == '\n');

  return 0;
}


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].state = DEAD;
    }
  }
  field[0][1].state = ALIVE;
  field[1][2].state = ALIVE;
  field[2][0].state = ALIVE;
  field[2][1].state = ALIVE;
  field[2][2].state = ALIVE;
}

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].state);
    }
    printf("\n");
  }
}

void getNeighbours(const int rows, const int cols, cell field[rows][cols]) {

  for(int rowCell = 0; rowCell < rows; rowCell++){
    for(int colCell = 0; colCell < cols; colCell++) {
      //Resets the neighbour count for all cells.
      field[rowCell][colCell].neighbours = 0;
      //Checks for alove neighbours "around" cell".
      for(int rl = -1; rl <= 1; rl++){
        for(int cl = -1; cl <= 1; cl++) {
          if(field[rowCell - rl][colCell - cl].state == ALIVE) {
            //Ignore the center cell to count as its own neighbour and ignore
            //the memory cells beyond the given size of the world for right and left.
            if(!(rl == 0 && cl == 0) && (rowCell-rl < rows) && (colCell-cl < cols) && (colCell-cl >= 0) && (rowCell-rl >= 0)) {
              field[rowCell][colCell].neighbours += 1;
            }
          }
        }
      }
    }
  }
}


void updateField(const int rows, const int cols, cell field[rows][cols]) {

  getNeighbours(rows, cols, field);

  for (int r = 0; r < rows; r++) {
    for (int c = 0; c < cols; c++) {
      if(field[r][c].neighbours == 3) {
        field[r][c].state = ALIVE;
      }
      else if(field[r][c].neighbours <= 1) {
        field[r][c].state = DEAD;
      }
      else if(field[r][c].neighbours >= 4) {
        field[r][c].state = DEAD;
      }
    }
 }
}

没有的代码:

 #include <stdio.h>
 #include <stdlib.h>

/* Constants, representation of states */
#define ALIVE 'X'
#define DEAD '.'

/* Declaration of data structure */
typedef struct{
  char current;
  char next;
  int neighbours;
} cell;


/* Declaration of functions */
void initField(const int rows, const int cols, cell field[rows][cols]);
void printField(const int rows, const int cols, cell field[rows][cols]);
void getNeighbours(const int rows, const int cols, cell field[rows][cols]);
void updateField(const int rows, const int cols, cell field[rows][cols]);


int main(void) {

  char key;

  //Rows and colum sizes.
  const int R = 20;
  const int C = 20;

  //Create an array of size 20x20 containin cells.
  cell cells[R][C];

  //Initates the game.
  initField(R, C, cells);

  //Prints field, menu and updates the game while the user presses enter.
  do {
    printField(R, C, cells);
    scanf("%c", &key);
    if(key == '\n') {
      updateField(R, C, cells);
    }
  } while(key == '\n');

  return 0;
}


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;
    }
  }
  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;
}

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");
  }
}

void getNeighbours(const int rows, const int cols, cell field[rows][cols]) {

  for(int rowCell = 0; rowCell < rows; rowCell++){
    for(int colCell = 0; colCell < cols; colCell++) {
      //Resets the neighbour count for all cells.
      field[rowCell][colCell].neighbours = 0;
      //Checks for alove neighbours "around" cell".
      for(int rl = -1; rl <= 1; rl++){
        for(int cl = -1; cl <= 1; cl++) {
          if(field[rowCell - rl][colCell - cl].current == ALIVE) {
            //Ignore the center cell to count as its own neighbour and ignore
            //the data beyond the given size of the world for right and left.
            if(!(rl == 0 && cl == 0) && (rowCell-rl < rows) && (colCell-cl < cols) && (colCell-cl >= 0) && (rowCell-rl >= 0)) {
              field[rowCell][colCell].neighbours += 1;
            }
          }
        }
      }
    }
  }
}


void updateField(const int rows, const int cols, cell field[rows][cols]) {

  getNeighbours(rows, cols, field);
  for (int r = 0; r < rows; r++) {
    for (int c = 0; c < cols; c++) {
      if(field[r][c].neighbours == 3) {
        field[r][c].next = ALIVE;
      }
      else if(field[r][c].neighbours <= 1) {
        field[r][c].next = DEAD;
      }
      else if(field[r][c].neighbours >= 4) {
        field[r][c].next = DEAD;
      }
    }
  }

  for (int r = 0; r < rows; r++) {
      for(int c = 0; c < cols; c++) {
          if (field[r][c].next == ALIVE) {
              field[r][c].current = ALIVE;
          }
          else {
              field[r][c].current = DEAD;
          }
      }
  }
}

0 个答案:

没有答案