Hey so my problem is that the when I go run this code and choose to "Zufallstand generieren" (Generate random state) and then type in the "Prozentualer Anteil lebender Zellen" (Percentage of living cells) and then "Schrittweise Animation" or "Fließende Animation" (Step-by-step animation/Flowing animation) the second generation is absolute trash it does not match the first generation in one thing.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#pragma warning (disable: 4996)
#define MAX_ROWS 30
#define MAX_COLS 20
typedef struct {
char data[MAX_ROWS][MAX_COLS];
int rows;
int cols;
} Matrix;
char neighbor_count(Matrix *m, int row, int col) {
int count = 0;
for (int i = row - 1; i <= row + 1; i++) {
if (i < 0 || i >= m->rows) {
continue;
}
for (int j = col - 1; j <= col + 1; j++) {
if (j < 0 || j >= m->cols) {
continue;
}
if (m->data[i][j] == '*' && (i != row || j != col)) {
count++;
}
}
}
return count;
}
void check_cell(Matrix *m, int row, int col) {
char neighbors_count = neighbor_count(m, row, col);
char current_cell = m->data[row][col];
if (neighbors_count < 2) { //Die Zelle stirbt an Vereinsamung
m->data[row][col] = ' ';
}
else if (neighbors_count > 3 && current_cell == '*') { //Die Zelle stirbt an Übervölkerung
m->data[row][col] = ' ';
}
else if (neighbors_count == 3 && current_cell == ' ') { //Aus der toten Zelle wird eine neue lebende Zelle
m->data[row][col] = '*';
}
else if (neighbors_count == 2 || neighbors_count == 3) { //Die Zelle lebt weiter
m->data[row][col] = '*';
}
}
void load_from_file(Matrix *m, const char *filename) {
FILE *f = fopen(filename, "r");
if (f == NULL) {
printf("File not found\n");
exit(-1);
}
int row_idx = 0;
char ch;
while ((ch = fgetc(f)) != EOF && row_idx < MAX_ROWS) {
if (ch == '\n') {
row_idx++;
continue;
}
#
m->data[row_idx][m->cols] = ch;
m->cols++;
}
m->rows = row_idx;
fclose(f);
}
void randomize(Matrix *m, int percent) {
memset(m->data, (int)' ', MAX_COLS * MAX_ROWS);
m->rows = MAX_ROWS;
m->cols = MAX_COLS;
int cells = (m->rows * m->cols) * (percent / 100.0f);
srand(time(NULL));
while (cells > 0) {
int row = rand() % m->rows;
int col = rand() % m->cols;
if (m->data[row][col] == ' ') {
m->data[row][col] = '*';
cells--;
}
}
}
void print_matrix(Matrix *m) {
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
printf("%c", m->data[i][j]);
}
printf("\n");
}
printf("\n");
}
void step(Matrix *m) {
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++) {
check_cell(&m_tmp, i, j);
}
}
*m = m_tmp;
}
int main() {
Matrix m;
// Menü zur Auswahl des Startzustands
printf("1. Aus Datei laden\n");
printf("2. Zufallszustand generieren\n");
int selection;
scanf("%d", &selection);
switch (selection) {
case 1: // Aus Datei laden
{
char filename[20];
printf("Bitte Dateinamen angeben: ");
scanf("%s", filename);
load_from_file(&m, filename);
break;
}
case 2: // Zufallszustand generieren
{
int percent;
printf("Prozentualer Anteil an lebenden Zellen: ");
scanf("%d%%", &percent);
randomize(&m, percent);
break;
}
default:
printf("Ungültige Eingabe\n");
return 0;
}
// Menü zur Auswahl der Animation
printf("1. Schrittweise Animation\n");
printf("2. Fließende Animation\n");
scanf("%d", &selection);
switch (selection) {
case 1: // Schrittweise Animation
while (1) {
print_matrix(&m);
step(&m);
getchar();
}
break;
case 2: // Fließende Animation6
while (1) {
print_matrix(&m);
step(&m);
Sleep(2000);
}
break;
default:
printf("Ungültige Eingabe\n");
break;
}
return 0;
}
I tried to change the how the matrix works but without any success.
As others have mentioned, you are modifying the current matrix. You need to have a copy.
Ironically, your step
function makes a copy. But, it still passes only one pointer to check_cell
.
check_cell
needs to have two matrix pointers. One for old/current state and another for new/future state.
Here are the changed functions:
void
check_cell(Matrix *mnew, Matrix *mold, int row, int col)
{
char neighbors_count = neighbor_count(mold, row, col);
char current_cell = mold->data[row][col];
do {
// Die Zelle stirbt an Vereinsamung
if (neighbors_count < 2) {
current_cell = ' ';
break;
}
// Die Zelle stirbt an Übervölkerung
if (neighbors_count > 3 && current_cell == '*') {
current_cell = ' ';
break;
}
// Aus der toten Zelle wird eine neue lebende Zelle
if (neighbors_count == 3 && current_cell == ' ') {
current_cell = '*';
break;
}
// Die Zelle lebt weiter
if (neighbors_count == 2 || neighbors_count == 3) {
current_cell = '*';
break;
}
} while (0);
mnew->data[row][col] = current_cell;
}
void
step(Matrix *m)
{
Matrix m_tmp = *m;
for (int i = 0; i < m->rows; i++) {
for (int j = 0; j < m->cols; j++)
check_cell(m, &m_tmp, i, j);
}
}