Невозможно определить «игру жизни» Конвея правильно (три основных правила для живых и мертвых)

#include <iostream>
using namespace std;

char **create_2darray(int rows, int cols){
char **a;
a = new char *[rows];
for(int i = 0;i<rows;i++){
a[i]=new char[cols];
}
return a;
}
char **set_2darry(int rows, int cols, char** array){
char ** a = array;
for(int i = 0; i < rows; i++){
for(int x = 0; x < cols; x++){
a[i][x]= ' ';
}
}
return a;
}

char **locate_array(char ** a, int rows, int cols){
a[rows][cols] = '*';
return a;
}
char **determine(char ** a, int rows, int cols){
int counter;
int n[1000];

for(int i = 0; i< rows;i++){
for(int x = 0; x< cols; x++){

if(i == 0 && x == 0){
if(a[i][x] == '*'){
if(a[i+1][x] == '*'){
n[counter]++;
}

if(a[i][x+1] == '*'){
n[counter]++;

}
if(a[i+1][x+1] == '*'){
n[counter]++;
}
}
}
else if(i == 0 && x == cols-1){
if(a[i][x] == '*'){
if(a[i][x-1] == '*'){
n[counter]++;
}
if(a[i+1][x-1] == '*'){
n[counter]++;
}

if(a[i+1][x] == '*'){
n[counter]++;
}
}

}
else if(i == rows-1 && x == 0){
if(a[i][x] == '*'){
if(a[i-1][x] == '*'){
n[counter]++;
}
if(a[i-1][x+1] == '*'){
n[counter]++;
}
if(a[i][x+1] == '*'){
n[counter]++;
}
}
}
else if(i == rows-1 && x == cols-1){
if(a[i][x] == '*'){
if(a[i-1][x-1] == '*'){
n[counter]++;
}
if(a[i][x-1] == '*'){
n[counter]++;
}

if(a[i-1][x] == '*'){
n[counter]++;
}
}
}
else if(i == rows-1){
if(a[i][x] == '*'){
if(a[i-1][x-1] == '*'){
n[counter]++;

}
if(a[i][x-1] == '*'){
n[counter]++;
}

if(a[i-1][x] == '*'){
n[counter]++;
}

if(a[i-1][x+1] == '*'){
n[counter]++;
}
if(a[i][x+1] == '*'){
n[counter]++;
}
}

}
else if(i == 0){
if(a[i][x] == '*'){
if(a[i][x-1] == '*'){
n[counter]++;
}
if(a[i+1][x-1] == '*'){
n[counter]++;
}
if(a[i+1][x] == '*'){
n[counter]++;
}

if(a[i][x+1] == '*'){
n[counter]++;
}
if(a[i+1][x+1] == '*'){
n[counter]++;
}
}
}
else if(x == 0){
if(a[i][x] == '*'){
if(a[i-1][x] == '*'){
n[counter]++;
}
if(a[i+1][x] == '*'){
n[counter]++;
}
if(a[i-1][x+1] == '*'){
n[counter]++;
}
if(a[i][x+1] == '*'){
n[counter]++;
}
if(a[i+1][x+1] == '*'){
n[counter]++;
}
}
}
else if(x == cols-1){
if(a[i][x] == '*'){
if(a[i-1][x-1] == '*'){
n[counter]++;
}
if(a[i][x-1] == '*'){
n[counter]++;
}
if(a[i+1][x-1] == '*'){
n[counter]++;
}
if(a[i-1][x] == '*'){
n[counter]++;
}
if(a[i+1][x] == '*'){
n[counter]++;
}
}
}
else {
if(a[i][x] == '*'){
if(a[i-1][x-1] == '*'){
n[counter]++;
}
if(a[i][x-1] == '*'){
n[counter]++;
}
if(a[i+1][x-1] == '*'){
n[counter]++;
}
if(a[i-1][x] == '*'){
n[counter]++;
}
if(a[i+1][x] == '*'){
n[counter]++;
}
if(a[i-1][x+1] == '*'){
n[counter]++;
}
if(a[i][x+1] == '*'){
n[counter]++;
}
if(a[i+1][x+1] == '*'){
n[counter]++;
}
}

}
counter++;
}
}
counter = 0;
for(int i = 0; i< rows;i++){
for(int x = 0; x< cols; x++){

if(n[counter] > 3){
a[i][x] = ' ';
}
else if(n[counter] == 0 || n[counter] == 1){
a[i][x] = ' ';
}
else if(n[counter] == 3){
a[i][x] = '*';
}
counter++;
}
}

return a;
}

struct GOL{
char** table;
int gen;
int rows;
int cols;
};

void print_2darray(char** a, int rows, int cols){
for(int i = 0; i < rows; i++){
for(int x = 0; x < cols; x++){
cout << a[i][x];
}
cout << endl;
}
}

Три главных правила в игре жизни Конвея:

  1. Если у занятой клетки ноль или один сосед, она умирает от одиночества.
  2. Если у занятой ячейки более трех соседей, она умирает от переполненности.
  3. Если пустая ячейка имеет ровно три занятые соседние ячейки, происходит рождение новой ячейки, чтобы заменить пустую ячейку.

Кстати, соседи — это ячейки, расположенные непосредственно над, под, справа, слева, по диагонали выше справа и слева и по диагонали ниже справа и слева.

Я не могу правильно напечатать «Игру жизни», и я знаю, что моя функция определения имеет некоторые проблемы; но я не знаю, где ошибка ..

-1

Решение

Во-первых, переменные count а также n должны быть инициализированы перед использованием:

int counter = 0;
int n[1000] = {0};

Во-вторых, вы проверяете только занятые ячейки (правила 1 и 2), но нет кода, который проверял бы пустые ячейки (правило 3).

Хотя можно вносить изменения в существующий код, я бы предложил написать новый код, чтобы он занимал совершенно другую логику. Вместо того, чтобы проверять влияние соседних ячеек на текущую ячейку, лучше рассчитать, какое влияние оказывает текущая ячейка на соседние ячейки. (увеличить на 1 все ячейки в массиве n рядом с живой клеткой). Код будет выглядеть проще.

Изменения в существующем коде довольно просты. Удалить все if(a[i][x] == '*'), так что подсчет соседних живых клеток делается как для живых, так и для мертвых токовых клеток.

0

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

Вы можете сделать свою жизнь проще, сделав игровое поле бесконечным — то есть, оно оборачивается.

#include <vector>
#include <iostream>

struct Grid
{
std::vector< std::vector<char> > m_grid;
size_t m_width, m_height;
size_t m_turns;

Grid(size_t width_, size_t height_)
: m_width(width_), m_height(height_)
, m_turns(0)
{
m_grid.resize(m_width);
for (size_t x = 0; x < m_width; ++x) {
m_grid[x].resize(m_height);
std::fill(m_grid[x].begin(), m_grid[x].end(), ' ');
}
}

char& at(int w_, int h_)
{
size_t x = static_cast<size_t>((w_ + m_width) % m_width);
size_t y = static_cast<size_t>((h_ + m_height) % m_height);
return m_grid[x][y];
}

int count(int w_, int h_)
{
return (at(w_, h_) == ' ') ? 0 : 1;
}

void turn()
{
std::vector< std::vector< char > > newGrid;
newGrid.resize(m_width);
for (size_t x = 0; x < m_width; ++x) {
newGrid[x].resize(m_height);
for (size_t y = 0; y < m_height; ++y) {
int counter = count(x - 1, y - 1) + count(x - 1, y) + count(x - 1, y + 1) +
count(x, y - 1) + count(x, y + 1) +
count(x + 1, y - 1) + count(x + 1, y) + count(x + 1, y + 1);
if (m_grid[x][y] == '*')
newGrid[x][y] = (counter >= 2 && counter <= 3) ? '*' : ' ';
else
newGrid[x][y] = (counter == 3) ? '*' : ' ';
}
}
m_grid = newGrid;

++m_turns;
}

void paint()
{
std::cout << "Turns: " << m_turns << "\n";
for (size_t x = 0; x < m_width; ++x) {
for (size_t y = 0; y < m_height; ++y) {
std::cout << at(x, y);
}
std::cout << "\n";
}
std::cout << "\n";
}
};

int main()
{
Grid g(8, 8);

g.at(3, 2) = '*';
g.at(3, 3) = '*';
g.at(3, 4) = '*';
g.at(2, 4) = '*';
g.at(1, 3) = '*';

for (size_t i = 0; i < 5; ++i) {
g.paint();
g.turn();
}
g.paint();
}

Несмотря на то, что этот код работает и создает работающую игру, я избегал многочисленных идиом и особенностей языка C ++, что делает код очень неэффективным. Если вы включите это как тестовый ответ, вы, вероятно, получите очень подозрительного лектора. Надеюсь, он предоставит вам материал, который позволит вам написать собственную реализацию.

Например: этот код копирует всю m_grid каждый раз, когда мы turn(), Это можно улучшить, используя два m_gridи переключаться между ними.

0

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