我有两个生命游戏实现,使用的结构差异很小:
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;
}
}
}
}