Непонятная ошибка в программе Game Of Life

У меня есть рабочий код Game of Life. Это сохраняет каждую популяцию как растровое изображение. Вот как выглядит результат (обрезается):

желаемый результат

При очистке кода я обнаружил, что если я закомментировал или иным образом удалил строку 60:

cout << "Survivor: " << x << ", " << y << "\n";

Это полностью портит программу, и вместо того, чтобы производить планер, как должно, он производит это:

неправильный вывод

Я искал вокруг, пытаясь выяснить, что может вызвать это, но я до сих пор безуспешно. Это мой текущий код:

//Bitmap Library from http://partow.net/programming/bitmap/
#include "bitmap_image.hpp"#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

using namespace std;

#define WIDTH 160
#define HEIGHT 128

bool population[WIDTH][HEIGHT];
bool survivors[WIDTH][HEIGHT];

int check_survivors();
int check_neighbors(int x, int y);
int write_population(char* file);

int main() {
int i, populations;

cout << "Enter number of populations: ";
cin >> populations;

//Glider
survivors[28][100] = true;
survivors[29][100] = true;
survivors[29][101] = true;
survivors[30][101] = true;
survivors[28][102] = true;

//Initial image generation
write_population("population0.bmp");

//populations
for (i = 0; i < populations; i++) {
char filename[17] = "population";
char ii[3];
sprintf(ii, "%d", i+1);

strcat(filename, ii);
strcat(filename, ".bmp");

check_survivors();
write_population(filename);
}

return 0;
}

int check_survivors() {
//set x and y variables
int x, y;

for (x = 0; x < WIDTH; x++) {
for (y = 0; y < HEIGHT; y++) {
if (check_neighbors(x, y)) {
survivors[x][y] = true;
cout << "Survivor: " << x << ", " << y << "\n";
} else {
survivors[x][y] = false;
}
}
}
return 0;
}

int check_neighbors(int x, int y) {
int neighbors = 0, survives;

//I really need to rewrite this mess

//Neighbors above
if (population[x-1][y-1] == true && x != 0 && y != 0) {
neighbors++;
}
if (population[x][y-1] == true && y != 0) {
neighbors++;
}
if (population[x+1][y-1] == true && x != WIDTH-1 && y != 0) {
neighbors++;
}

//Neighbors next to
if (population[x-1][y] == true && x != 0 ) {
neighbors++;
}
if (population[x+1][y] == true && x != WIDTH-1) {
neighbors++;
}

//Neighbors below
if (population[x-1][y+1] == true && x != 0  && y != HEIGHT-1) {
neighbors++;
}
if (population[x][y+1] == true && y != HEIGHT-1) {
neighbors++;
}
if (population[x+1][y+1] == true && x != WIDTH-1 && y != HEIGHT-1) {
neighbors++;
}

//Determining life or death
if (neighbors < 2 || neighbors > 3) {
//Neighbors less than 2 or more than 3 is dead cell
survives = 0;
} else if (neighbors == 3 && population[x][y] == false) {
//Exactly 3 neighbors re-animates a cell
survives = 1;
} else if (population[x][y] == true) {
//2 or 3 neighbors is survivor
survives = 1;
}

return survives;
}

int write_population(char* file) {
//Create Image
bitmap_image image(WIDTH, HEIGHT);

//Set background to white
image_drawer draw(image);
image.set_all_channels(255,255,255);

//set x and y variables
int x, y;

//For every array point, check to see if it survives,
//and transfer survivors to population
for (x = 0; x < WIDTH; x++) {
for (y = 0; y < HEIGHT; y++) {
if (survivors[x][y] == true) {
draw.pen_width(1);
draw.pen_color(0,0,0);
draw.plot_pixel(x, y);
}
population[x][y] = survivors[x][y];
}
}

//Save image
image.save_image(file);

//return
return 1;
}

8

Решение

Вещи как это:

if (population[x-1][y-1] == true && x != 0 && y != 0)

нужно переписать как:

if ( x > 0 && y > 0 && population[x-1][y-1] == true )

в противном случае вы окажетесь прямо на неопределенной территории поведения, когда либо x или же y являются 0 (как они будут несколько раз при звонке check_neighbors() от check_survivors()), и вы можете ожидать странные, необъяснимые ошибки, подобные этой. Вы должны проверить на недопустимые индексы массива до вы пытаетесь получить доступ к этим элементам.

Также здесь:

if (neighbors < 2 || neighbors > 3) {
//Neighbors less than 2 or more than 3 is dead cell
survives = 0;
} else if (neighbors == 3 && population[x][y] == false) {
//Exactly 3 neighbors re-animates a cell
survives = 1;
} else if (population[x][y] == true) {
//2 or 3 neighbors is survivor
survives = 1;
}

это выглядит, как если бы survives может быть оставлено неопределенное значение, если neighbors == 2 а также population[x][y] == false, что также приведет к неопределенному поведению, если вы получите доступ к этому значению. Из вашего кода не сразу понятно, может ли эта комбинация обстоятельств когда-либо быть верной, но если вы все еще находитесь на стадии отладки, то как минимум стоит добавить проверку условия, чтобы проверить, так ли это или нет.

Если ваша программа демонстрирует неопределенное поведение, как эта, то в значительной степени невозможно рассуждать об этом, пока эти проблемы не будут устранены.

6

Другие решения

Вы не всегда присваиваете значение переменной survives например если population[x][y] является false а также neighbors 2. Это оставляет survives со значением того, что находится в памяти в то время. Когда вы добавляете cout возможно, для вызова этого бита стековой памяти установлено значение 0, маскирующее ошибку вашей программы.

Добавьте начальное значение к survives когда ты это заявляешь.

3

По вопросам рекламы [email protected]