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

Как реализовать "Жизнь" по другому? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Вычисление суммы n членов ряда http://www.cyberforum.ru/cpp-beginners/thread1220181.html
Вычисление суммы n членов ряда \sin(x)+\frac{\cos(3x)}{9}+\frac{\cos(5x)}{25}+...
C++ В чем ошибка? Вызов функции Вот код: #include <iostream> #include <math.h> void filter(double x,double y,int N) { int i,j = 0; int M = 100; //длина фильтра int prop = 50; //частота пропускания int zat... http://www.cyberforum.ru/cpp-beginners/thread1220179.html
Перемещение содержимого одного контейнера в другой C++
Нужно переместить содержимое обьекта vector в обьект list. Подскажите пожалуйста!
Таймер C++
Привет, друзья, возникла проблема: ............................................. if(KEYDOWN(keyboard, DIK_SPACE)) { if (bulletVec.empty() || bulletVec.size() < 3 || bulletVec.back()-> сounter...
C++ Литература по ООП на С++ http://www.cyberforum.ru/cpp-beginners/thread1220130.html
Всем привет, на 1 курсе достаточно хорошо изучил СИ, на втором курсе будет ООП на СИ++, подскажите какую книжку лучше почитать летом чтоб быть более менее подготовленным
C++ Инжектор lua-скриптов Хочу написать написать свой инжектор луа-скриптов для одной программы. Как лучше осуществить? подробнее

Показать сообщение отдельно
Dimsssss
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 20

Как реализовать "Жизнь" по другому? - C++

30.06.2014, 20:34. Просмотров 422. Ответов 4
Метки (Все метки)

Значит есть игра такая - "жизнь" называется
C++ (Qt)
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#include <iostream>
#include <time.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
 
using namespace std;
 
class Cell { //класс клетки поля
public:
    virtual int who_are_you()=0;  //виртуальный метод, определяющий, чем именно является клетка
    virtual void print()=0; //виртуальный метод, ответственный за вывод клетки на экран
    virtual void extended_print()=0;  //см. выше + добавляется время жизни клетки
    virtual Cell* next(int rabbits_count, int wolfs_count, int grass_count) { //метод, который отвечает за время жизни самой клетки
        return 0;
    }
private:
    int x; //координаты
    int y;
    Cell* check(Cell *** field, int &size, int &x, int &y); //метод, который проверяет рядомстоящие клетки (их взаимодействие)
};
 
class Wolf : public Cell { //класс волка, наследуется от клетки
    int lifetime; //время жизни
public:
 
    Wolf() { //конструктор нового волка
        lifetime = 10;
    }
 
    Wolf(int lifetime) { //конструктор, которому передаем время жизни
        this->lifetime = lifetime; //переприсваиваем время жизни
    }
 
    void extended_print() { //функция расширенного вывода
        cout << "W(" << lifetime << ")";
    }
 
    void print() { //функция обычного вывода
        cout << "W";
    }
 
    int who_are_you() { //функция проверки, кем является клетка
        return 2; //так как 2 - то это волк
    }
    Cell* next(int rabbits_count, int wolfs_count, int grass_count);
};
 
class Rabbit : public Cell { /*класс кролика, наследуется от клетки.
    кроликам конструктор не нужен, так как время их жизни, по условию, бесконечно,
    и численность их популяции зависит от других факторов :) */
 
    void print() { //функция вывода
        cout << "R";
    }
 
    void extended_print() { //расширенного вывода
        cout << "R";
    }
 
    int who_are_you() { //функция проверки, кем является клетка
        return 3; //так как 3 - то это кролик
    }
    Cell* next(int rabbits_count, int wolfs_count, int grass_count);
};
 
class Grass : public Cell { //класс травы, наследуется от клетки
    int lifetime; //время жизни
public:
 
    Grass() { //конструктор новой травы
        lifetime = 5;
    }
 
    Grass(int lifetime) { //конструктор травы, которой передаем время жизни
        this -> lifetime = lifetime; //переприсваиваем время жизни
    }
 
    void print() { //функция вывода
        cout << "G";
    }
 
    void extended_print() { //функция расширенного вывода
        cout << "G(" << lifetime << ")";
    }
 
    int who_are_you() { //функция проверки, кем является клетка
        return 4; //так как 4 - то это трава
    }
    Cell* next(int rabbits_count, int wolfs_count, int grass_count);
};
 
class Empty_Cell : public Cell { //пустая клетка, которая наследуется от общей клетки
 
    void print() { //функция вывода
        cout << "_";
    }
 
    void extended_print() { //функция расширенного вывода
        cout << "_";
    }
 
    int who_are_you() { //функция проверки, кем является клетка
        return 1; //так как 1 - то это пустая клетка
    }
 
    Cell* next(int rabbits_count, int wolfs_count, int grass_count);
};
 
class LifeGame { //класс поля
    int size; //значение стороны
    Cell *** firstField; //поле - массив клеток
    Cell *** secondField; // и второе поле, как ни странно, тоже массив клеток
    int turns_count;
 
public:
    LifeGame(int size) { //конструктор поля, в который передается размер стороны
        this->size = size; //значению стороны этого поля присваиваем значение стороны
        firstField = createField();
        secondField = createField();
        turns_count = 0;
        fill(firstField);
    }
 
    ~LifeGame() { //деструктор поля
        deleteField(firstField);
        deleteField(secondField);
    }
 
    void print() const {
        if (turns_count % 2 == 0)
            printField(firstField);
        else printField(secondField);
    }
 
    void extended_print() { //расширенный вывод
        if (turns_count % 2 == 0)
            extendedFieldPrint(firstField);
        else extendedFieldPrint(secondField);
    }
 
    void turn() { //метод хода
        Cell *** oldField;
        Cell *** newField;
        if (turns_count % 2 == 0) {
            oldField = firstField;
            newField = secondField;
        }
        else {
            newField = firstField;
            oldField = secondField;
        }
 
        for (int y = 0; y < size; j++) {//Идём циклом по всему первоначальному полю
            for (int x = 0; x < size; i++)
                newField[x][y] = oldField[x][y]->check(oldField, size, x, y); //короче
        }
        ++turns_count;
    }
 
    int getterTurns (){
        return turns_count;
    }
 
private:
    Cell*** createField() const {
        //пока i меньше размера стороны поля
        //каждому field[i] присваиваем значение указателя на клетку,
        //field присваиваем значение двойного указателя на клетку, таким образом создаем динамический одномерный массив
        //таким образом создается двумерный динамический массив
        Cell*** newField = new Cell**[size];
        for (int x = 0; x < size; ++x)
            newField[x] = new Cell*[size];
        return newField;
    }
 
    void deleteField(Cell*** field) {
        for (int x = 0; x < size; ++x)
            delete [] field[x];
        delete [] field;
    }
 
    void printField(Cell *** field) const { //функция вывода
        for (int y = 0; y < size; y++) { //пока j меньше стороны
            for (int x = 0; x < size; x++) { //пока i меньше стороны
                field[x][y]->print(); //вызываем метод print для field [i][j], а соответственно - для каждой клетки поля
                cout << " ";
            }
            cout << endl;
        }
        cout << endl;
    }
 
    void extendedFieldPrint(Cell *** field) const {
        for (int y = 0; y < size; y++) {
            for (int x = 0; x < size; x++) {
                field[x][y]->extended_print(); //расширенный вывод для каждой клетки поля
                cout << "\t"; //через символ табуляции
            }
            cout << endl;
        }
        cout << endl;
    }
 
    void fill(Cell *** field) {
        //Заполнение поля игры рандомными фишками
        srand(time(NULL));
        for (int x = 0; x < size; x++) {
            for (int y = 0; y < size; y++) {
                int object_id = rand() % 4; //object_id присваиваем значение остатка от деления рандомного числа на 4
                if (object_id == 0) //если object_id равно 0
                    field[x][y] = new Wolf(); //создаем в клетка нового волка
                else if (object_id == 1) //если 1
                    field[x][y] = new Rabbit(); //нового кролика
                else if (object_id == 2) //если 2
                    field[x][y] = new Empty_Cell(); //пустую клетку
                else field[x][y] = new Grass(); //иначе траву
            }
        }
    }
};
 
int main() {
    cout << "Enter game field size: ";
    int size = _getch() - 48; //считываем значение размера поля с клавиатуры
    cout << size << endl;
    LifeGame * game = new LifeGame(size); //создаем поле под указателем field field->fill(); //вызываем метод заполнения рандомными фишками
    cout << "1 - make a turn" << endl << "2 - print" << endl
            << "3 - extended print" << endl << "4 - exit" << endl << endl;
    int q = 0;
    while (q != 4) {
        q = _getch() - 48;
        switch (q) {
        case 1:
                game->turn(); //вызываем метод хода
                cout << "Turn " << game->getterTurns() << endl;
                break;
 
            case 2:
                game->print(); //Выводим игровое поле на экран
                break;
 
            case 3: //Выводим игровое поле на экран показывая время жизни клеток
                game->extended_print(); //Выводим игровое поле на экран
                break;
            case 4: break;
            default: cout << "Wrong command! Try again." << endl;
        }
    }
    delete game; //удаляем field
    //delete secondfield;
}
 
Cell* Cell::check(Cell *** field, int &size, int &x, int &y) { //метод, который возвращает новое поле, которое является результатом хода на предыдущем
    int rabbits_count = 0;
    int wolfs_count = 0;
    int grass_count = 0;
    int empty_count = 0;
    //cout << "i = " << i << " j = " << j << endl;
    /*while (b < 4) {
        //cout << "x = " << x << " y = " << y;
        if (x >= 0 && y >= 0 && x < size && y < size) {
            //cout << "Kletka ok" << endl;
            if (field[x][y]->who_are_you() == 1)
                empty_count++;
            else if (field[x][y]->who_are_you() == 2)
                wolfs_count++;
            else if (field[x][y]->who_are_you() == 3)
                rabbits_count++;
            else if (field[x][y]->who_are_you() == 4)
                grass_count++;
        }
        //else cout << "Kletka ne ok" << endl;
        if (a < 2) { //этой операцией обходим вокруг клетки
            if (b == 0)
                x++;
            else if (b == 1)
                y++;
            else if (b == 2)
                x--;
            else y--;
            a++;
        }
        if (a == 2) {
            b++;
            a = 0;
        }
    }*/
    for (int j = (y - 1); j <= (y + 1); j++){
        for (int i = (x - 1); i <= (x + 1); i++){
            if ((x == i) && (y == j)){
                x++;
            }
            if (i >= 0 && j >= 0 && i < size && j < size) {
                //cout << "Kletka ok" << endl;
                if (field[i][j]->who_are_you() == 1)
                    empty_count++;
                else if (field[i][j]->who_are_you() == 2)
                    wolfs_count++;
                else if (field[i][j]->who_are_you() == 3)
                    rabbits_count++;
                else if (field[i][j]->who_are_you() == 4)
                    grass_count++;
            }
        }
    }
    Cell* result; //result - указатель на клетку
    //cout << "rabbits_count = " << rabbits_count << " wolfs_count = " << wolfs_count
    //  << "grass_count = " << grass_count << endl;
    return result = field[x][y]->next(rabbits_count, wolfs_count, grass_count);
}
//Почему голодные волки рожают сытых волков?
 
Cell* Empty_Cell::next(int rabbits_count, int wolfs_count, int grass_count) { //проверка для пустой клетки
    Cell* result;
    if (wolfs_count == 2) { //если 2 волка - результат - новый волк
        return result = new Wolf();
    }
    if (rabbits_count > 2) //если больше двух кроликов - результат - новый кроль
        return result = new Rabbit();
    if (grass_count > 1) //если больше одной травы - результат - новая трава
        return result = new Grass();
    return result = new Empty_Cell(); //иначе клетка "обновляется" на пустую
}
 
Cell* Rabbit::next(int rabbits_count, int wolfs_count, int grass_count) { //проверка для клетки кролика
    Cell* result;
    //if (wolfs_count > 1)
    //  return result = new Wolf();
    if ((rabbits_count < 2) || (rabbits_count > 3)) //если кроликов меньше 2
        return result = new Empty_Cell(); //клетка с кроликом меняется на пустую клетку
    return result = new Rabbit(); //иначе - новый кролик
}
 
Cell* Wolf::next(int rabbits_count, int wolfs_count, int grass_count) { //проверка для клетки волка
    Cell* result;
    if (lifetime == 1) //если волку осталось недолго жить
        return result = new Empty_Cell(); //то результат для следующего хода - пустая клетка
    if (rabbits_count > wolfs_count / 2) //если кроликов больше чем волков/2
        return result = new Wolf(); //результат - новый волк
    return result = new Wolf(lifetime - 1); //иначе волку остается жить меньше на 1 ход
}
 
Cell* Grass::next(int rabbits_count, int wolfs_count, int grass_count) { //проверка для клетки травы
    Cell* result;
    if (lifetime == 1 || rabbits_count > grass_count) //если время жизни на этом ходу равно 1 или кроликов больше чем травы
        return result = new Empty_Cell(); //в результате получим пустую клетку
    return result = new Grass(lifetime - 1); //иначе уменьшаем время жизни травы на 1
}
в общем, правила есть в конце кода в комментах. Подскажите плиз как реализовать игру так, чтобы мы обращались непосредственно к объектам Cell (клеток) по их координатам, а не создавать двумерный динамический массив с указателем на клетку?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru