Commit 871f9f07 authored by Adam P. Goucher's avatar Adam P. Goucher

Save multistate macrocell files

parent 14cd355d
Pipeline #44006547 passed with stages
in 7 minutes and 30 seconds
......@@ -258,6 +258,80 @@ namespace apg {
}
}
uint64_t write_macrocell_recurse(std::ostream &outstream, hypernode<I> hnode,
std::map<std::string, uint64_t> *subleaf2int,
std::map<std::pair<I, uint32_t>, uint64_t> *hnode2int,
uint64_t &linenum) {
/*
* Writes a multistate macrocell file.
*/
auto it = hnode2int->find(std::make_pair(hnode.index, hnode.depth));
if (hnode.index == 0) {
return 0;
} else if (it != hnode2int->end()) {
return it->second;
} else if (hnode.depth == 0) {
kiventry<nicearray<uint64_t, 4*N>, I, J >* pptr = ind2ptr_leaf(hnode.index);
uint64_t jays[4] = {0ull};
for (int j = 0; j < 4; j++) {
uint64_t colours[64] = {0ull};
for (unsigned int i = 0; i < N; i++) {
uint64_t rel = pptr->key.x[4*i + j];
for (int k = 0; k < 64; k++) { colours[k] |= (((rel >> k) & 1) << i); }
}
// TODO compact this
for (int i = 1; i <= 3; i++) {
for (int y = 0; y < (8 >> i); y++) {
for (int x = 0; x < (8 >> i); x++) {
uint64_t a = colours[16*y + 2*x];
uint64_t b = colours[16*y + 2*x + 1];
uint64_t c = colours[16*y + 2*x + 8];
uint64_t d = colours[16*y + 2*x + 9];
uint64_t nc = 0;
if (a | b | c | d) {
std::ostringstream ss;
ss << i << " " << a << " " << b << " " << c << " " << d;
std::string ssstr = ss.str();
auto it = subleaf2int->find(ssstr);
if (it != subleaf2int->end()) {
nc = it->second;
} else {
outstream << ssstr << std::endl;
subleaf2int->emplace(ssstr, (++linenum));
nc = linenum;
}
}
colours[8*y + x] = nc;
}
}
}
jays[j] = colours[0];
}
outstream << "4 " << jays[0] << " " << jays[1] << " " << jays[2] << " " << jays[3] << std::endl;
hnode2int->emplace(std::make_pair(hnode.index, hnode.depth), (++linenum));
return linenum;
} else {
uint64_t a = write_macrocell_recurse(outstream, getchild(hnode, 0), subleaf2int, hnode2int, linenum);
uint64_t b = write_macrocell_recurse(outstream, getchild(hnode, 1), subleaf2int, hnode2int, linenum);
uint64_t c = write_macrocell_recurse(outstream, getchild(hnode, 2), subleaf2int, hnode2int, linenum);
uint64_t d = write_macrocell_recurse(outstream, getchild(hnode, 3), subleaf2int, hnode2int, linenum);
outstream << (hnode.depth + 4) << " " << a << " " << b << " " << c << " " << d << std::endl;
hnode2int->emplace(std::make_pair(hnode.index, hnode.depth), (++linenum));
return linenum;
}
}
uint64_t write_macrocell_recurse(std::ostream &outstream, hypernode<I> hnode,
std::map<uint64_t, uint64_t> *subleaf2int,
std::map<std::pair<I, uint32_t>, uint64_t> *hnode2int,
......@@ -297,17 +371,32 @@ namespace apg {
outstream << "[M2] (lifelib " << LIFELIB_VERSION << ")" << std::endl;
}
void write_macrocell_headerless(std::ostream &outstream, hypernode<I> hnode, std::string rule) {
void write_macrocell_headerless(std::ostream &outstream, hypernode<I> hnode, std::string rule, int multistate) {
if (rule != "") { outstream << "#R " << gollyrule(rule) << std::endl; }
std::map<uint64_t, uint64_t> subleaf2int;
std::map<std::pair<I, uint32_t>, uint64_t> hnode2int;
uint64_t linenum = 0;
write_macrocell_recurse(outstream, breach(hnode), &subleaf2int, &hnode2int, linenum);
bool write_multistate;
switch (multistate) {
case 0 : write_multistate = false; break; // 0 : 2-state
case 1 : write_multistate = true; break; // 1 : multistate
case 2 : write_multistate = (N > 1); break; // 2 : infer
}
if (write_multistate) {
outstream << "#CLL state-numbering lifelib" << std::endl;
std::map<std::string, uint64_t> subleaf2int;
write_macrocell_recurse(outstream, breach(hnode), &subleaf2int, &hnode2int, linenum);
} else {
std::map<uint64_t, uint64_t> subleaf2int;
write_macrocell_recurse(outstream, breach(hnode), &subleaf2int, &hnode2int, linenum);
}
}
void write_macrocell(std::ostream &outstream, hypernode<I> hnode, std::string rule) {
void write_macrocell(std::ostream &outstream, hypernode<I> hnode, std::string rule, int multistate) {
write_macrocell_header(outstream);
write_macrocell_headerless(outstream, hnode, rule);
write_macrocell_headerless(outstream, hnode, rule, multistate);
}
hypernode<I> read_macrocell(std::istream &instream, std::string &rule) {
......
......@@ -69,14 +69,22 @@ namespace apg {
virtual void force_gc() = 0;
virtual bool threshold_gc(uint64_t threshold) = 0;
virtual uint64_t getcell_recurse(hypernode<I> hnode, uint64_t x, uint64_t y) = 0;
virtual void write_macrocell(std::ostream &outstream, hypernode<I> hnode, std::string rule) = 0;
virtual void write_macrocell(std::ostream &outstream, hypernode<I> hnode, std::string rule, int multistate) = 0;
virtual void write_macrocell_header(std::ostream &outstream) = 0;
virtual void write_macrocell_headerless(std::ostream &outstream, hypernode<I> hnode, std::string rule) = 0;
virtual void write_macrocell_headerless(std::ostream &outstream, hypernode<I> hnode, std::string rule, int multistate) = 0;
virtual void getcells_recurse(hypernode<I> hnode, uint64_t x, uint64_t y, std::map<std::pair<uint64_t, uint64_t>, uint64_t> &cells) = 0;
virtual void write_rle(std::ostream &outstream, hypernode<I> hnode, std::string rule) = 0;
virtual hypernode<I> _string32(std::string s) = 0;
virtual std::string _string32(hypernode<I> hnode) = 0;
void write_macrocell(std::ostream &outstream, hypernode<I> hnode, std::string rule) {
write_macrocell(outstream, hnode, rule, 2);
}
void write_macrocell_headerless(std::ostream &outstream, hypernode<I> hnode, std::string rule) {
write_macrocell_headerless(outstream, hnode, rule, 2);
}
bool threshold_gc() {
return threshold_gc(gc_threshold);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment