-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhashlifemacrocell.h
106 lines (90 loc) · 2.75 KB
/
hashlifemacrocell.h
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
// © Copyright (c) 2018 SqYtCO
#ifndef HASHLIFEMACROCELL_H
#define HASHLIFEMACROCELL_H
#include "basesystem.h"
class HashLife_Table;
// class for recursive hashlife algorithm
struct Macrocell
{
static HashLife_Table hash_table;
// num of living zero level cells in macrocell
std::size_t population;
// smaller daughter cells with level n-1
Macrocell* nw;
Macrocell* ne;
Macrocell* se;
Macrocell* sw;
// next state of macrocell
Macrocell* result;
// return macrocell with given daughter cells; if cell does not exist in hash_table, a new cell is created and inserted into the hash_table
static Macrocell* new_macrocell(Macrocell* nw, Macrocell* ne, Macrocell* se, Macrocell* sw);
// init instance; if ne == nullptr, the cell will be a zero level cell; nw != nullptr sets the population of a zero level cell to 1, otherwise it is 0
Macrocell(Macrocell* nw, Macrocell* ne, Macrocell* se, Macrocell* sw);
// return the hashed value of the daughter cells
inline std::size_t hash() const;
// calculate level of cell
std::size_t level() const
{
const Macrocell* temp = this;
std::size_t level = 0;
while(temp)
{
++level;
temp = temp->ne;
}
return level;
}
// set zero level cell at x,y to given state; upper left corner is 0,0
Macrocell* set_state(std::size_t x, std::size_t y, std::size_t level, Cell_State state);
// get zero level cell state at x,y; upper left corner is 0,0
inline bool get_state(std::size_t x, std::size_t y, std::size_t level) const
{
if(population == 0)
return false;
if(level == 0)
return population;
std::size_t half = 0x01ull << (--level);
if(x < half)
{
if(y < half)
return nw->get_state(x, y, level);
else
return sw->get_state(x, y - half, level);
}
else
{
if(y < half)
return ne->get_state(x - half, y, level);
else
return se->get_state(x - half, y - half, level);
}
}
// generations has to be a power of two
Macrocell* calculate(std::size_t level, std::size_t generations = 1);
// get macrocell of level n-1 which is located in the center
inline Macrocell* center() const
{
return new_macrocell(nw->se, ne->sw, se->nw, sw->ne);
}
// get macrocell of level n-1 which is located in the north
inline Macrocell* nn() const
{
return new_macrocell(nw->ne, ne->nw, ne->sw, nw->se);
}
// get macrocell of level n-1 which is located in the east
inline Macrocell* ee() const
{
return new_macrocell(ne->sw, ne->se, se->ne, se->nw);
}
// get macrocell of level n-1 which is located in the south
inline Macrocell* ss() const
{
return new_macrocell(sw->ne, se->nw, se->sw, sw->se);
}
// get macrocell of level n-1 which is located in the west
inline Macrocell* ww() const
{
return new_macrocell(nw->sw, nw->se, sw->ne, sw->nw);
}
};
#endif // HASHLIFEMACROCELL_H