Форум программистов, компьютерный форум CyberForum.ru

Игра "Жизнь" ( найти ошибку) - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Перемещение фигуры http://www.cyberforum.ru/cpp/thread1618220.html
Реализовать отображение на экране геометрической фигуры с возможностью перемещать ее с помощью клавиш(стрелки) и изменение цвета фигуры "+".
C++ Информация о железе Здравствуйте форумчане Очень нужно узнать информацию о: HDD(разделы, размер каждого раздела, сколько занято места) CPU(температура, загрузку каждого ядра) процессы(как в диспетчера задач) службы запущенные приложения заранее спасибо) http://www.cyberforum.ru/cpp/thread1618027.html
C++ Вычисление количества знаков после запятой
Написал функцию определяющую, что у числа менее 4 знаков после запятой. Помогите оптимизировать. bool rac(double a) { int c(0); a -= int(a); while (a - int(a) && c < 4) { a *= 10; a -= int(a);
Создать и подключить библиотеку в Dev-C++ C++
Помогите пожалуйста. Необходимо создать библиотеку и exe файл. При запуске exe файла ввести 2 значения (a=число1, b=число2). Эти числа должны передаться библиотеке (dll) там сложиться и вернуться обратно в виде суммы.
C++ Ошибка сегментирования при компиляции http://www.cyberforum.ru/cpp/thread1617311.html
Когда компилирую через g++ компилируется, при запуске выдает ошибку сегментирования, а при компиляции через NetBeans IDE выдает две ошибки, на скринах показал. Задача: Разработать две программы – сервер и клиент. Клиент отсылает серверу через датаграммный сокет два числа L и U, введенные пользователем, где L – это нижняя граница диапазона, U – верхняя граница диапазона. Сервер принимает...
C++ Как достать кириллические символы из char* Добрый день. Использую библиотеку, которая возвращает строку в char*. Если создавать std::wstring из этой строки, то кириллица отображается как знаки вопросов. Помогите достать из буфера char* русские символы. Заранее спасибо. подробнее

Показать сообщение отдельно
NikBond
2 / 2 / 2
Регистрация: 21.07.2015
Сообщений: 36

Игра "Жизнь" ( найти ошибку) - C++

20.12.2015, 17:08. Просмотров 396. Ответов 5
Метки (Все метки)

Писал клеточный автомат "Жизнь"(описание можно посмотреть на википедии, либо в комментариях к коду ниже).
Когда все вроде бы сделал, обнаружил, что алгоритм на самом деле работает не правильно.
Например, это видно, когда на вход идет такой файл("1.txt"):
Код
10 10
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 1 0 0
0 1 1 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 1 0 0 0 0 
0 0 0 1 1 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0
По логике игры, "квадратик" имеет стабильное положение и не должен меняться, "полоска" должна "вращаться", а фигура снизу представлять из себя глайдер. Но этого не происходит. Но этого не происходит.

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

Код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/** \file
  * \brief Клеточный автомат "Жизнь"
  *
  * Программа реализует клеточный автомат "Жизнь"("Life").
  * Дано поле, в котормо каждая клетка может быть либо "живой", либо "мертвой".
  * Пользователь задает начальные условия - первое поколение. Программа генерирует новое поколения (состояние поля) по таким правилам:
  * Если клетка имеет более 3 или менее 2 соседей, она становится/остается мертвой.
  * Если клетка имеет строго 3 соседя, она становится/остается живой.
  * Новые поколения генерируется до тех пор, пока все клетки клетки не умрут либо не образуют стабильное состояние (перестанут меняться).
*/
 
#include <iostream>
#include <fstream>
#include <iomanip>
#include <ctime>
#include <random>
#include <windows.h>
 
//#include <chrono>
//#include <thread>
 
using namespace std;
 
class Fields {
    /* Класс описывает состояние поля ("Поколения жизни"). */
    private:
        int n; // количество рядков поля
        int m; // количество столбцов поля
        bool **array; //игровое поле. Если клетка поля true - она жива, если false - мертва.
    public:
        Fields(int a, int b);
        Fields(const Fields& );
        Fields(ifstream &);
        Fields& operator= (Fields&r);
        void print();
        void run( Fields last);
};
 
int countOfChanges = 1; //счетчик изменений состояния игрового поля .
 
int main(){
    int countLife = 0; //счетчик состояний игрового поля("Поколений жизни")
    int n, m; //длинна и ширина поля
    cout << "Hello. This is game of life. " << endl
         << "1. Create the random generated field" << endl
         << "2. Create the field with file" << endl;
    int choice;
    cin >> choice;
 
    Fields current(0, 0); // текущее поколение
 
 
    switch(choice){
        case 1:{
            cout << "Enter the number of rows and columns of field" << endl;
            cout << setw(9) << "Rows: ";
            cin >> n;
            cout << setw(9) << "Columns: ";
            cin >> m;
            Fields randomField = Fields(n, m);
            current = randomField;
            break;
        }
        case 2:{
            ifstream fin("1.txt");
            Fields fileField = Fields(fin);
            current = fileField;
            break;
        }
    }
 
    Fields next(current); // следующее поколение
 
    cout << "Field: "<< endl;
    current.print();
 
    while (countOfChanges != 0){
        //system("cls");
        cout << ++countLife << "st generation: " << endl;
        countOfChanges = 0;
        next.run(current);
        current = next;
        current.print();
        Sleep(1000);
        //std::this_thread::sleep_for (std::chrono::seconds(1));
    }
 
    //system("cls");
 
    cout << endl << "This system has been alive for " << countLife - 1 << " steps." << endl;
 
    return 0;
}
 
void Fields:: run( Fields last ){
 
    /* Метод реализует логику игры. Проходит по всем клеткам поля last,
       считает количество соседей у каждой клетки и устанавливает новое состояние аналогичной клетки своего поля.
       Если изменения происходят, счетчик изменений увеличивается.
    */
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
 
            int neighbors = 0; //количество живых клеток-соседей
 
            if ( j - 1 > 0 ){   //тут и далее: проверка, не выходит ли "сосед" за пределы массива, чтобы можно было к нему обратиться
                if(last.array[i][j-1]){
                    neighbors++;
                }
            }
            if ( i + 1 < n && j - 1 > 0) {
                if(last.array[i+1][j-1]){
                    neighbors++;
                }
            }
            if ( i + 1 < n) {
                if(last.array[i+1][j] ){
                    neighbors++;
                }
            }
            if ( i + 1 < n && j - 1 > 0) {
                if(last.array[i+1][j-1]){
                    neighbors++;
                }
            }
            if ( j - 1  > 0) {
                if(last.array[i][j-1]){
                    neighbors++;
                }
            }
            if ( i - 1 > 0 && j + 1 < m ){
                if(last.array[i-1][j+1]){
                    neighbors++;
                }
            }
            if ( i - 1 > 0 ){
                if(last.array[i-1][j]){
                    neighbors++;
                }
            }
            if (  i -1 > 0 && j - 1 > 0){
                if(last.array[i-1][j-1]){
                    neighbors++;
                }
            }
 
 
            if (neighbors == 3 && last.array[i][j] == false){
                //если соседей строго 3, мертвая клетка оживает
                array[i][j] = true;
                ::countOfChanges++;
            }
 
            if ( (neighbors <= 2 || neighbors > 3 ) && last.array[i][j] == true) {
                //если соседей меньше или равно 2 или больше 3, живая клетка умирает
                array[i][j] = false;
                ::countOfChanges++;
            }
        }
    }
}
 
Fields:: Fields(int a, int b): n(a), m(b){
 
    array = new bool* [n];                         // объявление динамического двумерного массива
    for(int count = 0; count < n; count ++){        //
        array[count] = new bool [m];                //
    }                                               //
 
    mt19937 gen(time(0));                           // генератор псевдо-случайных чисел из с++11
    uniform_int_distribution <> dist(0, 1);         // распределение рандомайзера - целые числа 0 и 1
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            array[i][j] = dist(gen);                // рандомное заполнение двумерного массива 0 и 1
        }
    }
}
 
Fields:: Fields(const Fields& last){
    /* Конструктор копирования */
 
    n = last.n;
    m = last.m;
 
    array = new bool* [n];                         // объявление динамического двумерного массива
    for(int count = 0; count < n; count ++){        //
        array[count] = new bool [m];                //
    }
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            array[i][j] = last.array[i][j];
        }
    }
}
 
Fields:: Fields(ifstream & fin){
    /* Создание поля с файла*/
    fin >> n;
    fin >> m;
 
    array = new bool * [n];                         // объявление динамического двумерного массива
    for(int count = 0; count < n; count ++){        //
        array[count] = new bool [m];                //
    }
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            fin >> array[i][j];
        }
    }
}
 
Fields& Fields:: operator = (Fields &right){
    n = right.n;
    m = right.m;
 
 
    delete []array;
 
    array = new bool * [n];                         // объявление динамического двумерного массива
    for(int count = 0; count < n; count ++){        //
        array[count] = new bool [m];                //
    }
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            array[i][j] = right.array[i][j];
        }
    }
    return *this;
}
 
void Fields:: print(){
 
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(array[i][j]){
                cout << "*";
            }
            else{
                cout << " ";
            }
        }
        cout << endl;
    }
    cout << endl;
}
Помогите найти ошибку.
Вложения
Тип файла: txt 1.txt (221 байт, 2 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru