Добрый день!
Очень странно себя ведет std::deque в котором хранятся указатели.
simpleOrganism.h
Кликните здесь для просмотра всего текста
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
| #ifndef SIMPLEORGANISM_H
#define SIMPLEORGANISM_H
#include <QObject>
#include <QList>
#include <QListIterator>
#include <QMutableListIterator>
#include <QDebug>
#include <QtMath>
#include <cmath>
#include <time.h>
#include "dna.h"
#include <vector>
#include <deque>
//#include <thread>
//#include <mutex>
struct statistic {
int mutations;
int alives;
int deads;
int creates;
int delete_objects;
int size_pull;
int del_test;
};
class SimpleOrganism : public QObject
{
//std::mutex g_mutex;
Q_OBJECT
public:
const double LIFE_INTERVAL = 0.1;
static int GLOBAL_ID_ORGANISM;
static int GLOBAL_CLASS_ORGANISM;;
static std::deque<SimpleOrganism *> pull_organism;
explicit SimpleOrganism(QObject *parent = 0);
explicit SimpleOrganism(SimpleOrganism *parent_organism, QObject *parent = 0);
~SimpleOrganism();
DNA * dna;
bool life;
int get_id();
int get_class();
bool lifecicle();
static bool global_life_cicle();
void clone();
void death();
bool get_life();
void show();
static void show_stat();
private:
int ID_Organism;
int Class_organism;
struct parametrs {
double outer_shell; //внешняя оболочка толщина [1]
double inner_shell; //внутреняя оболочка толщина [2]
double insides; //внутренности толщина [3]
double force; //массивность/сила/etc. [4]
double density; //плотность [5]
double life_cicle; //жизненный цыкл. [8]
} max_param, current_param;
static statistic stat;
struct movement {
double speed;
float direction; //направление 360градусов
float acceleration = 0; //разгон, макс 100% 1.0.
bool move;
double posX, posY;
} move;
double size; //общая толщина. (радиус)
double hungry; //голод
//bool life;
bool dna_calc();
bool param_calc();
bool push_pull();
signals:
public slots:
};
#endif // SIMPLEORGANISM_H |
|
SimpleOrganism.cpp
Кликните здесь для просмотра всего текста
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
| #include "simpleorganism.h"
int SimpleOrganism::GLOBAL_ID_ORGANISM = 0;
int SimpleOrganism::GLOBAL_CLASS_ORGANISM = 0;
statistic SimpleOrganism::stat;
std::deque<SimpleOrganism *> SimpleOrganism::pull_organism;
SimpleOrganism::SimpleOrganism(QObject *parent) : QObject(parent)
{
ID_Organism = GLOBAL_ID_ORGANISM;
GLOBAL_ID_ORGANISM++;
Class_organism = GLOBAL_CLASS_ORGANISM;
GLOBAL_CLASS_ORGANISM++;
dna = new DNA(this);
dna_calc();
}
SimpleOrganism::SimpleOrganism(SimpleOrganism *parent_organism, QObject *parent) : QObject(parent)
{
ID_Organism = GLOBAL_ID_ORGANISM;
GLOBAL_ID_ORGANISM++;
Class_organism = parent_organism->get_class();
dna = new DNA(parent_organism->dna, this);
dna_calc();
}
SimpleOrganism::~SimpleOrganism() {
stat.delete_objects++;
}
bool SimpleOrganism::dna_calc() {
stat.alives++;
stat.creates++;
max_param.insides = log(dna->get_dna_block(3)) / log(1.01); //внутренности от ДНК
max_param.outer_shell = max_param.insides / 20 + (log(dna->get_dna_block(1)) / log(1.1) / 2); //внешняя оболочка, зависит от размеров внутренностей и ДНК
max_param.inner_shell = max_param.insides / 20 + (log(dna->get_dna_block(2)) / log(1.1) / 2); //внутренняя оболочка, зависит от размера внутренностей и ДНК
max_param.force = log(dna->get_dna_block(4)) / log(1.01); //мощность.
max_param.density = log(dna->get_dna_block(5)) / log(1.1); // чем выше плотность - тем прочнее и медленнее создание.
max_param.life_cicle = log(dna->get_dna_block(8)) / log(1.1);
current_param.life_cicle = LIFE_INTERVAL;
life = true;
hungry = 1;
return true;
}
bool SimpleOrganism::param_calc() {
double procent_life = current_param.life_cicle / max_param.life_cicle;
current_param.insides = max_param.insides * procent_life;
current_param.outer_shell = max_param.outer_shell * procent_life;
current_param.inner_shell = max_param.inner_shell * procent_life;
current_param.force = max_param.force * procent_life;
current_param.density = max_param.density * procent_life;
size = current_param.insides + current_param.inner_shell + current_param.outer_shell;
double temp_speed = current_param.force - ((size * (current_param.density / 10)) / 20);
if (move.move) {
if (move.acceleration < 1)
move.acceleration += 0.1;
}
else {
if (move.acceleration > 0)
move.acceleration -= 0.1;
}
move.speed = temp_speed * move.acceleration;
return true;
}
bool SimpleOrganism::lifecicle() {
if (!life)
return false;
//смерть от голода.
if (hungry >= 100) {
death();
return false;
}
//Вероятность смерти от старости
if (current_param.life_cicle > max_param.life_cicle) {
if (rand() % 100+1 <= current_param.life_cicle / max_param.life_cicle * 100 - 100) {
death();
return false;
}
}
current_param.life_cicle += LIFE_INTERVAL;
//Голод
//if (hungry < 100)
// hungry++;
if (rand() % 1000 <= 1) {
dna->mutations();
stat.mutations++;
}
if (current_param.life_cicle / max_param.life_cicle * 100 + (rand() % 40) - hungry >= 100 ) {
clone();
return false;
}
param_calc();
return true;
}
bool SimpleOrganism::global_life_cicle() {
int z = pull_organism.size();
for (int i = 0; i < z; ++i) {
pull_organism[i]->lifecicle();
}
if (!pull_organism.back()->get_life()) {
stat.del_test++;
}
// pull_organism.back()->show();
if (stat.delete_objects > 100000) {
stat.delete_objects = 0;
pull_organism.shrink_to_fit();
}
return true;
}
void SimpleOrganism::death() {
life = false;
stat.deads++;
stat.alives--;
}
void SimpleOrganism::clone() {
//pull_organusm.push_back(new SimpleOrganism(this, 0));
//pull_organusm.push_back(new SimpleOrganism(this, 0));
pull_organism.push_front(new SimpleOrganism(this, 0));
pull_organism.push_front(new SimpleOrganism(this, 0));
death();
}
int SimpleOrganism::get_class() {
return Class_organism;
}
int SimpleOrganism::get_id() {
return ID_Organism;
}
bool SimpleOrganism::get_life() {
return life;
}
bool SimpleOrganism::push_pull() {
pull_organism.push_front(this);
return true;
}
void SimpleOrganism::show_stat() {
qDebug() << "\n####STATS:####"
<< "\n creates - " << stat.creates
<< "\n lifes - " << stat.alives
<< "\n deads - " << stat.deads
<< "\n mutations - " << stat.mutations
<< "\n delete obj - " << stat.delete_objects
<< "\n size_pull - " << stat.size_pull
<< "\n del test - " << stat.del_test
<< "\n#############\n";
}
void SimpleOrganism::show() {
qDebug() << "life " << life
<< "\n life cicle " << current_param.life_cicle;
} |
|
main.cpp
Кликните здесь для просмотра всего текста
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
| #include <QCoreApplication>
#include <QProcess>
#include "simpleorganism.h"
#include <iostream>
#include <time.h>
#include <QDebug>
int main(int argc, char *argv[])
{
clock_t t;
QCoreApplication a(argc, argv);
srand(time(NULL));
SimpleOrganism::pull_organism.clear();
for (int i = 0; i < 100; ++i)
SimpleOrganism::pull_organism.push_front(new SimpleOrganism());
for (int i = 0; i < 10000; ++i) {
t = clock();
SimpleOrganism::global_life_cicle();
SimpleOrganism::show_stat();
t = clock() - t;
qDebug() << "\ntime " << t;
}
return a.exec();
} |
|
Внимание на функцию bool SimpleOrganism::global_life_cicle();
В ней перебирается весь контейнер (пробовал по итератору, через функцию .at(index) и просто по индексу [index]. Тут все нормально вызывается, хотя Qtcreator не видит функции объектов, не подсвечивает у них синтаксис и прочее.
В функции clone обьект создает новые свои копии и помещает в
начало очереди.
Ниже идет условие:
C++ (Qt) |
1
2
3
| if (!pull_organism.back()->get_life()) {
stat.del_test++;
} |
|
get_life() возвращает переменную life, которая булево. Так вот по не ведомой мне причине, очередь всегда возвращает true. Даже когда life давно уже false.
Для теста я сделал так (вынес переменную life в public)
C++ (Qt) |
1
2
3
| if (!pull_organism.back()->life) {
stat.del_test++;
} |
|
И угадайте что? - правильно, оно опять возвращает true.
Меня это взбесило, я сделал так. Я создал функцию такого содержания.
C++ (Qt) |
1
2
3
4
5
6
7
| //костыль
void SimpleOrganism::delete_back() {
if (!life) {
pull_organism.pop_back();
stat.del_test++;
}
} |
|
а в global_life_cicle сделал просто функцию, которая впыолняет так: pull_organism.back()->delete_back();
и знаете что? опять оно возвращает мне вегда true!
И тут я сделал сдледующее.. В main я убрал цыкл, что бы создался ОДИН обьект.
C++ (Qt) |
1
2
| //for (int i = 0; i < 100; ++i) //Закоментил
SimpleOrganism::pull_organism.push_front(new SimpleOrganism()); |
|
и стало нормально все работать.
Что с очередью не так? Почему QtCreator не видит что внутри? Почему она себя так странно ведет?
п.с. за место stat.del_test должно быть delete this, это если кто-то решит что память течет.