Игра грани массива Игра ведет себя странно

Я посмотрел «Игру жизни» Конвея и решил сделать свою собственную.
У меня есть массив bool для представления мира, но края (сверху и снизу) ведут себя странно, случайные ячейки становятся живыми.

В этом коде он не печатает дно и вершину мира, но это плохое решение.
Мир «оборачивается» справа и слева, вызывая еще больше проблем, но это в другой раз.

#include <iostream>

const int height = 20;
const int width  = 20;

bool now_world[height][width];
bool then_world[height][width];

void clear_world();
void place_random_live_cells();
void then_world_initialization();
void print_world();
void generation_pass();
void update_worlds();

int main(int argc, const char * argv[])
{
using namespace std;
srand((unsigned)time(NULL));
int timer = 0;
int generation = 0;
clear_world();
place_random_live_cells();
then_world_initialization();
bool running = true;
while (running) {
if (timer == 50000000) {
cout << "Generation #" << generation << endl;
print_world();
generation_pass();
update_worlds();
++generation;
timer = 0;
}
++timer;
}//While (running) ends here
return 0;
}

void place_random_live_cells()
{
int percent = 30;
int max_live_cells = ((height * width) / 100) * percent;
int current_live_cells = 0;
while (current_live_cells < max_live_cells) {
int ycoords = 0 + (rand() % (height + 1));
int xcoords = 0 + (rand() % (width  + 1));
if (now_world[ycoords][xcoords] == false) {
now_world[ycoords][xcoords] = true;
} else {
current_live_cells--;
}
++current_live_cells;
}
}

//A generation pass and cells die and some cells come to life
void generation_pass()
{
using namespace std;
int neighbours = 0;
for (int iii = 0; iii < height; iii++) {
for (int jjj = 0; jjj < width; jjj++) {
//Count neighbouring cells that are alive
if (now_world[iii+1][jjj+1] == true) {
++neighbours;
}
if (now_world[iii+1][jjj  ] == true) {
++neighbours;
}
if (now_world[iii+1][jjj-1] == true) {
++neighbours;
}
if (now_world[iii  ][jjj+1] == true) {
++neighbours;
}
if (now_world[iii  ][jjj-1] == true) {
++neighbours;
}
if (now_world[iii-1][jjj+1] == true) {
++neighbours;
}
if (now_world[iii-1][jjj  ] == true) {
++neighbours;
}
if (now_world[iii-1][jjj-1] == true) {
++neighbours;
}
//Apply rules to the cells
//Dead cells with three live neighbours becomes alive
if (then_world[iii][jjj] == false && neighbours == 3) {
then_world[iii][jjj] =  true;
}
//Alive with fewer than two, they die
if (then_world[iii][jjj] == true  && neighbours <  2) {
then_world[iii][jjj] =  false;
}
//Alive with 2 or three live neighbours live on unchanged
if (then_world[iii][jjj] == true  && neighbours == 2) {
then_world[iii][jjj] =  true;
}
if (then_world[iii][jjj] == true  && neighbours == 3) {
then_world[iii][jjj] =  true;
}
//Alive with more than three, they die
if (then_world[iii][jjj] == true  && neighbours >  3) {
then_world[iii][jjj] =  false;
}
//Dead cells without exactly three live neighbours remain dead
//Reset neighbour value to zero
neighbours = false;
}
}
}

//Make next generation identical to current
//This is only called once
void then_world_initialization()
{
for (int iii = 0; iii < height; iii++) {
for (int jjj = 0; jjj < width; jjj++) {
then_world[iii][jjj] = now_world[iii][jjj];
}
}
}

//Make the next generation be today
//This is called every generation
void update_worlds()
{
for (int iii = 0; iii < height; iii++) {
for (int jjj = 0; jjj < width; jjj++) {
now_world[iii][jjj] = then_world[iii][jjj];
}
}
}

//Set all cells to dead
void clear_world()
{
for (long iii = 0; iii < height; iii++) {
for (long jjj = 0; jjj < width; jjj++) {
now_world[iii][jjj]  = false;
then_world[iii][jjj] = false;
}
}
}

//Print world
void print_world()
{
using namespace std;
char live = 'X';
char dead = '.';
for (long iii = height; iii > 0; iii--) {
for (long jjj = width; jjj > 0; jjj--) {
if (iii != 0 && iii != height) {
if (now_world[iii][jjj]) {
cout << live;
} else {
cout << dead;
}
cout << " ";
}
}
cout << endl;
}
cout << endl;
}

0

Решение

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

Если вы посмотрите на операторы if в вашем вложенном цикле for, я думаю, вы найдете некоторые проблемы. Например, что в этом случае происходит, когда iii равно (height-1) или jjj равно (width-1)?

for (int iii = 0; iii < height; iii++) {
for (int jjj = 0; jjj < width; jjj++) {
//Count neighbouring cells that are alive
if (now_world[iii+1][jjj+1] == true) {
++neighbours;

Вы выходите за границы вашего массива, и поэтому ваши результаты будут неопределенными. Вы можете получить segfaults, но вы также можете получить ложные данные. C ++ не заставляет вас оставаться в пределах заданного вами массива.

Убедитесь, что вы также обрабатываете такие случаи:

if (now_world[iii-1][jjj+1] == true) {
++neighbours;
}

Что если iii равно нулю?

Надеюсь, это поможет.

3

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

Вы пытаетесь получить доступ к внешним индексам в вашем массиве.

Я не уверен, какое поведение вы ожидаете, но простой способ — не вычислять обновления для ячеек по краям.

Так в generation_pass петли должны идти от 1 до height-1,

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector