Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca_gallery_gen.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 https://github.com/lrleon/Aleph-w
6
7 This file is part of Aleph-w library
8
9 Copyright (c) 2002-2026 Leandro Rabindranath Leon
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28*/
29
53#include <cstdint>
54#include <filesystem>
55#include <fstream>
56#include <iostream>
57#include <random>
58#include <string>
59
60#include <ca-io.H>
61#include <ca-png.H>
62#include <ca-engine-utils.H>
63#include <tpl_ca_engine.H>
64#include <tpl_ca_lattice.H>
65#include <tpl_ca_neighborhood.H>
66#include <tpl_ca_rule.H>
67#include <tpl_ca_storage.H>
68
69using namespace Aleph;
70using namespace Aleph::CA;
71
72namespace fs = std::filesystem;
73
74namespace
75{
76
78
79// Write `frame` (rank-2) to `path` as PNG using `mapper`.
80template <typename Lattice, typename Mapper>
81void write_png_file(const fs::path &path, const Lattice &frame, Mapper mapper)
82{
83 std::ofstream out(path, std::ios::binary);
84 write_png(out, frame, mapper);
85 if (not out)
86 std::cerr << "warning: failed writing " << path << '\n';
87}
88
89// Deterministic Bernoulli soup keyed by the rule name so each panel is
90// stable but visually distinct.
91Grid2D soup(ca_size_t side, double density, const std::string &key)
92{
93 std::mt19937 rng(0xA1E90000u ^ static_cast<std::uint32_t>(
94 std::hash<std::string>{}(key)));
95 std::uniform_real_distribution<double> u(0.0, 1.0);
96 Grid2D g({side, side}, 0);
97 for (ca_size_t i = 0; i < side; ++i)
98 for (ca_size_t j = 0; j < side; ++j)
99 g.set({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)},
100 u(rng) < density ? 1 : 0);
101 return g;
102}
103
104// Render a Life-like outer-totalistic rule `F(state, alive_count) -> state`.
105template <typename F>
106void render_life_like(const fs::path &dir, const std::string &name, F func,
107 ca_size_t side, std::size_t steps, double density,
108 RGB8 on)
109{
110 using Rule = Outer_Totalistic_Rule<F>;
112 soup(side, density, name), Rule(func), Moore<2, 1>{});
113 eng.run(steps);
114 const RGB8 off{18, 18, 24};
115 write_png_file(dir / (name + ".png"), eng.frame(),
116 [on, off](int v) { return v != 0 ? on : off; });
117 std::cout << " " << name << ".png (" << side << "x" << side << ", "
118 << steps << " steps)\n";
119}
120
121// Render an elementary Wolfram rule as a space-time diagram.
122void render_wolfram(const fs::path &dir, int rule_no, ca_size_t width,
123 ca_size_t steps, RGB8 on)
124{
126 row.set({static_cast<ca_index_t>(width / 2)}, 1);
127 auto eng = make_wolfram_engine(static_cast<std::uint8_t>(rule_no),
128 std::move(row));
129
130 Grid2D img({steps, width}, 0);
131 for (ca_size_t t = 0; t < steps; ++t)
132 {
133 for (ca_size_t x = 0; x < width; ++x)
134 img.set({static_cast<ca_index_t>(t), static_cast<ca_index_t>(x)},
135 eng.frame().at({static_cast<ca_index_t>(x)}));
136 eng.step();
137 }
138
139 const RGB8 off{248, 248, 252};
140 const std::string name = "wolfram_" + std::to_string(rule_no);
141 write_png_file(dir / (name + ".png"), img,
142 [on, off](int v) { return v != 0 ? on : off; });
143 std::cout << " " << name << ".png (" << width << "x" << steps
144 << " space-time)\n";
145}
146
147} // namespace
148
149int main(int argc, char *argv[])
150{
151 const fs::path out_dir = argc >= 2 ? fs::path(argv[1]) : fs::path("docs/gallery");
152 fs::create_directories(out_dir);
153
154 std::cout << "Rendering gallery into " << out_dir << "\n";
155
156 // --- Life-like outer-totalistic rules (Moore-8 neighbour count) ---------
157 std::cout << "Life-like rules:\n";
158 // Conway B3/S23.
159 render_life_like(out_dir, "conway_b3s23",
160 [](int s, std::size_t n) { return (n == 3 or (s != 0 and n == 2)) ? 1 : 0; },
161 96, 80, 0.30, RGB8{120, 220, 140});
162 // HighLife B36/S23 (replicator-bearing).
163 render_life_like(out_dir, "highlife_b36s23",
164 [](int s, std::size_t n)
165 { return ((n == 3 or n == 6) or (s != 0 and n == 2) or (s != 0 and n == 3)) ? 1 : 0; },
166 96, 80, 0.30, RGB8{240, 180, 90});
167 // Day & Night B3678/S34678 (symmetric).
168 render_life_like(out_dir, "day_and_night_b3678s34678",
169 [](int s, std::size_t n)
170 {
171 const bool birth = (n == 3 or n == 6 or n == 7 or n == 8);
172 const bool survive = (n == 3 or n == 4 or n == 6 or n == 7 or n == 8);
173 return ((s == 0 and birth) or (s != 0 and survive)) ? 1 : 0;
174 },
175 96, 64, 0.45, RGB8{150, 180, 250});
176 // Seeds B2/S (everything dies, explosive growth).
177 render_life_like(out_dir, "seeds_b2s",
178 [](int s, std::size_t n) { return (s == 0 and n == 2) ? 1 : 0; },
179 96, 24, 0.06, RGB8{250, 120, 120});
180 // Maze B3/S12345.
181 render_life_like(out_dir, "maze_b3s12345",
182 [](int s, std::size_t n)
183 {
184 const bool survive = (n >= 1 and n <= 5);
185 return ((s == 0 and n == 3) or (s != 0 and survive)) ? 1 : 0;
186 },
187 96, 90, 0.18, RGB8{200, 160, 250});
188 // 2x2 B36/S125.
189 render_life_like(out_dir, "two_by_two_b36s125",
190 [](int s, std::size_t n)
191 {
192 const bool birth = (n == 3 or n == 6);
193 const bool survive = (n == 1 or n == 2 or n == 5);
194 return ((s == 0 and birth) or (s != 0 and survive)) ? 1 : 0;
195 },
196 96, 80, 0.30, RGB8{120, 210, 230});
197 // Replicator B1357/S1357.
198 render_life_like(out_dir, "replicator_b1357s1357",
199 [](int, std::size_t n) { return (n % 2 == 1) ? 1 : 0; },
200 96, 40, 0.004, RGB8{240, 210, 120});
201 // Life without Death B3/S012345678.
202 render_life_like(out_dir, "life_without_death_b3s8",
203 [](int s, std::size_t n) { return ((s == 0 and n == 3) or s != 0) ? 1 : 0; },
204 96, 50, 0.06, RGB8{170, 230, 160});
205
206 // --- Elementary Wolfram rules (space-time diagrams) ---------------------
207 std::cout << "Wolfram elementary rules:\n";
208 const RGB8 ink{30, 30, 40};
209 render_wolfram(out_dir, 30, 201, 100, ink);
210 render_wolfram(out_dir, 54, 201, 100, ink);
211 render_wolfram(out_dir, 60, 201, 100, ink);
212 render_wolfram(out_dir, 90, 201, 100, ink);
213 render_wolfram(out_dir, 110, 201, 100, ink);
214 render_wolfram(out_dir, 150, 201, 100, ink);
215 render_wolfram(out_dir, 184, 201, 100, ink);
216 render_wolfram(out_dir, 250, 201, 100, ink);
217
218 std::cout << "Done.\n";
219 return 0;
220}
int main()
size_t steps
Definition ca-c-api.h:126
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t row
Definition ca-c-api.h:115
Convenience builders for the Phase 3 synchronous engine.
File-format readers and writers for cellular-automata frames.
Dependency-free PNG frame sink for cellular automata.
Lattice that adds boundary-aware access on top of a storage.
Moore (Chebyshev) neighborhood of radius R in N dimensions.
Rule whose next state depends on (current, alive_count).
Definition tpl_ca_rule.H:99
Synchronous double-buffered engine.
void run(const std::size_t steps)
Run several synchronous steps.
static mt19937 rng
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Wolfram_1D_Engine make_wolfram_engine(std::uint8_t rule_no, ca_size_t width)
Build a 1D elementary Wolfram engine of the given width.
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
double density(const Lattice &lat, const typename Lattice::state_type &s)
Definition ca-metrics.H:212
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
void write_png(std::ostream &out, const Lattice &frame, Mapper &&mapper)
Write a rank-2 frame as an 8-bit RGB PNG image.
Definition ca-png.H:171
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
Out-of-range neighbours behave as if the lattice ended.
Definition ca-traits.H:119
RGB byte triplet used by PPM exporters.
Definition ca-io.H:85
The lattice wraps around on every axis.
Definition ca-traits.H:124
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Rule mechanisms for Aleph::CA.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).