79 std::size_t max_value, std::size_t &
out)
81 if (text ==
nullptr or text[0] ==
'-')
83 std::cerr <<
"Invalid " << name <<
": '"
84 << (text ==
nullptr ?
"" : text)
85 <<
"' (expected a positive integer)\n";
90 const unsigned long long value = std::strtoull(text, &end, 10);
92 value > std::numeric_limits<std::size_t>::max()
or
95 std::cerr <<
"Invalid " << name <<
": '" << text
96 <<
"' (expected an integer in [1, "
100 out =
static_cast<std::size_t
>(
value);
110 const auto ca_max = std::numeric_limits<ca_size_t>::max();
111 const auto idx_max =
static_cast<std::size_t
>(
112 std::numeric_limits<ca_index_t>::max());
115 std::cerr <<
"Invalid " << name <<
": '" << text
116 <<
"' (value is too large)\n";
124 void render(
const Grid & g, std::size_t step, std::size_t alive)
129 std::cout <<
"\033[H";
130 std::cout <<
"Game of Life — step " << step
131 <<
" (" << alive <<
" alive)\n";
132 std::cout <<
'+' << std::string(
cols,
'-') <<
"+\n";
137 std::cout << (g.at({ i, j }) ?
'#' :
' ');
140 std::cout <<
'+' << std::string(
cols,
'-') <<
"+\n";
152 if (g.at({ i, j })) ++a;
160 const std::vector<std::pair<int, int>> & pattern)
166 for (
auto [
r, c] : pattern)
175 std::vector<std::pair<int, int>>
pattern_for(
const std::string & name)
178 return { {0,0}, {0,1}, {1,0}, {1,1} };
180 if (name ==
"blinker")
181 return { {0,-1}, {0,0}, {0,1} };
184 return { {0,1}, {0,2}, {0,3},
185 {1,0}, {1,1}, {1,2} };
187 if (name ==
"beacon")
188 return { {0,0}, {0,1}, {1,0}, {1,1},
189 {2,2}, {2,3}, {3,2}, {3,3} };
191 if (name ==
"r-pentomino")
192 return { {0,1}, {0,2}, {1,0}, {1,1}, {2,1} };
194 if (name ==
"gosper")
197 {4,0}, {4,1}, {5,0}, {5,1},
199 {2,12}, {2,13}, {3,11}, {3,15}, {4,10}, {4,16}, {5,10}, {5,14},
200 {5,16}, {5,17}, {6,10}, {6,16}, {7,11}, {7,15}, {8,12}, {8,13},
202 {0,24}, {1,22}, {1,24}, {2,20}, {2,21}, {3,20}, {3,21},
203 {4,20}, {4,21}, {5,22}, {5,24}, {6,24},
205 {2,34}, {2,35}, {3,34}, {3,35}
209 return { {0,1}, {1,2}, {2,0}, {2,1}, {2,2} };
215 std::string pattern = (
argc >= 2) ?
argv[1] :
"glider";
216 std::size_t
steps = 40;
229 if (pattern ==
"gosper")
231 if (width < 50) width = 50;
232 if (height < 20) height = 20;
235 Grid
grid({ height, width }, 0);
242 std::cout <<
"\033[2J";
243 for (std::size_t t = 0; t <=
steps; ++t)
245 const Grid & frame =
engine.frame();
247 if (t ==
steps)
break;
248 std::this_thread::sleep_for(std::chrono::milliseconds(80));
size_t size_t int32_t value
size_t size_t int32_t * out
Convenience builders for the Phase 3 synchronous engine.
Common typedefs and tag types for the Cellular Automata module.
Lattice that adds boundary-aware access on top of a storage.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Game_Of_Life_Engine make_gol_engine(ca_size_t rows, ca_size_t cols)
Build a Conway's Game of Life engine of the given shape.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
auto max_value(const Container &data) -> std::decay_t< decltype(*std::begin(data))>
Compute maximum value.
The lattice wraps around on every axis.
Cellular automata lattice with pluggable boundary policies.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).