-
Notifications
You must be signed in to change notification settings - Fork 1
/
hashlifemacrocell.cpp
120 lines (105 loc) · 3.3 KB
/
hashlifemacrocell.cpp
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
// © Copyright (c) 2018 SqYtCO
#include "hashlifemacrocell.h"
#include "hashlifetable.h"
// definition of static members
HashLife_Table Macrocell::hash_table;
Macrocell* Macrocell::new_macrocell(Macrocell* nw, Macrocell* ne, Macrocell* se, Macrocell* sw)
{
Macrocell* temp = Macrocell::hash_table.get(nw, ne, se, sw);
// if cell was found in hash_table, return it; otherwise insert a new macrocell and return it
if(temp)
return temp;
else
{
temp = new Macrocell(nw, ne, se, sw);
Macrocell::hash_table.insert(temp, temp);
return temp;
}
}
Macrocell::Macrocell(Macrocell* nw, Macrocell* ne, Macrocell* se, Macrocell* sw)
: nw(nw), ne(ne), se(se), sw(sw), result(nullptr)
{
// check if cell is a zero level cell and set population
if(ne == nullptr)
this->population = (nw != nullptr);
else
this->population = nw->population + ne->population + se->population + sw->population;
}
std::size_t Macrocell::hash() const
{
return HashLife_Table::hash(nw, ne, se, sw);
}
Macrocell* Macrocell::set_state(std::size_t x, std::size_t y, std::size_t level, Cell_State state)
{
if(ne == nullptr)
return (state) ? hash_table.get_alive() : hash_table.get_dead();
if(!state && population == 0)
return this;
Macrocell* cell = new Macrocell(nw, ne, se, sw);
std::size_t size = 0x01ull << (--level);
if(x < size)
{
if(y < size)
cell->nw = nw->set_state(x, y, level, state);
else
cell->sw = sw->set_state(x, y - size, level, state);
}
else
{
if(y < size)
cell->ne = ne->set_state(x - size, y, level, state);
else
cell->se = se->set_state(x - size, y - size, level, state);
}
Macrocell* temp = hash_table[cell];
if(temp)
{
delete cell;
return temp;
}
else
{
if(state)
cell->population = population + 1;
else
cell->population = population - 1;
hash_table.insert(cell, cell);
}
return cell;
}
Macrocell* Macrocell::calculate(std::size_t level, std::size_t generations)
{
if(result)
return result;
if(population == 0)
{
result = Macrocell::hash_table.get_empty(level - 1);
return result;
}
std::size_t half = level - 3;
Macrocell* nw_ = nw->calculate(level - 1, generations);
Macrocell* nn_ = nn()->calculate(level - 1, generations);
Macrocell* ne_ = ne->calculate(level - 1, generations);
Macrocell* ww_ = ww()->calculate(level - 1, generations);
Macrocell* cc_ = center()->calculate(level - 1, generations);
Macrocell* ee_ = ee()->calculate(level - 1, generations);
Macrocell* sw_ = sw->calculate(level - 1, generations);
Macrocell* ss_ = ss()->calculate(level - 1, generations);
Macrocell* se_ = se->calculate(level - 1, generations);
if(generations > half)
{
nw_ = Macrocell::new_macrocell(nw_, nn_, cc_, ww_)->calculate(level - 1, generations);
ne_ = Macrocell::new_macrocell(nn_, ne_, ee_, cc_)->calculate(level - 1, generations);
se_ = Macrocell::new_macrocell(cc_, ee_, se_, ss_)->calculate(level - 1, generations);
sw_ = Macrocell::new_macrocell(ww_, cc_, ss_, sw_)->calculate(level - 1, generations);
}
else
{
nw_ = Macrocell::new_macrocell(nw_->se, nn_->sw, cc_->nw, ww_->ne);
ne_ = Macrocell::new_macrocell(nn_->se, ne_->sw, ee_->nw, cc_->ne);
se_ = Macrocell::new_macrocell(cc_->se, ee_->sw, se_->nw, ss_->ne);
sw_ = Macrocell::new_macrocell(ww_->se, cc_->sw, ss_->nw, sw_->ne);
}
result = Macrocell::new_macrocell(nw_, ne_, se_, sw_);
return result;
}