// display info overlay with CA number and start conditions?
// -overlay
// which ruleset number to use? Or random? Or random from small set of hand-selected interesting examples?
-// Options (with precedence): -rule N
-// -rule-curated
-// -rule-random
+// In order of precedence:
+// -random (select a random rule on each run)
+// -rule N (always simulate Rule N on each run)
+// (if neither of the above two are specified, then a random CURATED rule is selected on each run)
// which starting population to use? Or random? Or one bit in middle? Or one bit on edge? (For random: Can I allow specifying a density like 25%, 50%, 75%?)
// Options (with precedence): -population STRING (string is a comma separated list of cell IDs to populate, starting from 0)
// -population-curated
Bool display_info;
Bool * current_generation;
- uint8_t ruleset;
+
+ // TODO: Describe these.
+ uint8_t rule_number; // Note: This is not a CLI option. You're thinking of rule_requested.
+ uint8_t rule_requested; // Note: Repurposing Rule 0 as a null value.
+ Bool rule_random;
/* Misc Commandline Options */
int pixel_size; /* Size of CA cell in pixels (e.g. pixel_size=3 means 3x3 pixels per cell). */
size_t number_of_cells;
};
+// TODO: Check the full set of 256 CAs for visually interesting examples.
+static const uint8_t curated_rule_list[] = {
+ 22,
+ 30,
+ 45,
+ 57,
+ 73,
+ 86
+};
+
static void *
WolframAutomata_init(Display * dpy, Window win)
{
state->number_of_cells = state->xlim / state->pixel_size;
- /*
- * The minimum number of generations is 2 since we must allocate enough
- * space to hold the seed generation and at least one pass through
- * WolframAutomata_draw(), which is where we check whether or not we've
- * reached the end of the pixmap.
- */
+ /* The minimum number of generations is 2 since we must allocate enough */
+ /* space to hold the seed generation and at least one pass through */
+ /* WolframAutomata_draw(), which is where we check whether or not we've */
+ /* reached the end of the pixmap. */
state->num_generations = get_integer_resource(state->dpy, "num-generations", "Integer");
if (state->num_generations < 0) state->num_generations = 2;
+ /* Time to figure out which rule to use for this simulation. */
+ /* We ignore any weirdness resulting from the following cast since every */
+ /* bit pattern is also a valid rule; if the user provides weird input, */
+ /* then we'll return weird (but well-defined!) output. */
+ state->rule_requested = (uint8_t) get_integer_resource(state->dpy, "rule-requested", "Integer");
+ state->rule_random = get_boolean_resource(state->dpy, "rule-random", "Boolean");
+ /* Through the following set of branches, we enforce CLI flag precedence. */
+ if (state->rule_random) {
+ /* If this flag is set, the user wants truly random rules rather than */
+ /* random rules from a curated list. */
+ state->rule_number = (uint8_t) random();
+ } else if (state->rule_requested != 0) {
+ /* Rule 0 is terribly uninteresting, so we are reusing it as a 'null' */
+ /* value and hoping nobody notices. Finding a non-zero value means */
+ /* the user requested a specific rule. Use it. */
+ state->rule_number = state->rule_requested;
+ } else {
+ /* No command-line options were specified, so select rules randomly */
+ /* from a curated list. */
+ size_t number_of_array_elements = sizeof(curated_rule_list)/sizeof(curated_rule_list[0]);
+ state->rule_number = curated_rule_list[random() % number_of_array_elements];
+ }
+
// TODO: These should be command-line options, but I need to learn how the get_integer_resource() and similar functions work first.
state->display_info = True;
- state->ruleset = 30;
state->current_generation = calloc(1, (sizeof(*(state->current_generation))*state->number_of_cells)); // TODO: Check calloc() call TODO: Can't recall precedence; can I eliminate any parenthesis?
// TODO: Make the starting state a user-configurable option. At least give the user some options like 'random', 'one-middle', 'one edge', etc.
cell_pattern |= 1;
}
}
- if ((state->ruleset >> cell_pattern) & 1) {
+ if ((state->rule_number >> cell_pattern) & 1) {
return True;
} else {
return False;
static const char * WolframAutomata_defaults[] = {
".background: black",
".foreground: white",
- "*delay-usec: 2500",
+ "*delay-usec: 25000",
// TODO: Difference between dot and asterisk? Presumably the asterisk matches all resouces of attribute "pixelsize"? Apply answer to all new options.
"*pixel-size: 2",
"*num-generations: 5000",
+ "*rule-requested: 0",
+ "*rule-random: False",
0
};
{ "-delay-usec", ".delay-usec", XrmoptionSepArg, 0 },
{ "-pixel-size", ".pixel-size", XrmoptionSepArg, 0 },
{ "-num-generations", ".num-generations", XrmoptionSepArg, 0 },
+ { "-rule", ".rule-requested", XrmoptionSepArg, 0 },
+ { "-rule-random", ".rule-random", XrmoptionNoArg, "True" },
{ 0, 0, 0, 0 }
};