commit 54b8cd8fce22623c4063c3ac7df092825f99aa22
parent 7bcbc09e0f12589af69eafbdc39fa74bf9d0e1ac
Author: aabacchus <ben@bvnf.space>
Date: Tue, 28 Sep 2021 11:58:32 +0100
add some command line options
Diffstat:
M | Makefile | | | 2 | +- |
M | cgol.1 | | | 11 | ++++++++++- |
M | main.c | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
3 files changed, 71 insertions(+), 18 deletions(-)
diff --git a/Makefile b/Makefile
@@ -25,7 +25,7 @@ images:
mkdir -p images
out.webm: images
- ffmpeg -r 15 -i images/%04d.png $@
+ ffmpeg -r 15 -i images/%06d.png $@
clean:
rm -fr $(OBJS) cgol images/
diff --git a/cgol.1 b/cgol.1
@@ -6,6 +6,7 @@
.Nd generate images of the game of life
.Sh SYNOPSIS
.Nm
+.Op Ar width height Op Ar gens
.Sh DESCRIPTION
.Nm
generates frames of the progression of the game of life as images,
@@ -29,9 +30,17 @@ A
cell remains living only if it has 2 or 3 neighbours.
.It
All other cells remain or become dead.
-.Ed
+.El
According to these rules, the random initial state can give rise to
some interesting behaviours.
+.Pp
+Options:
+.Bl -tag -width Ds
+.It Ar width height
+the width and height of the images to be printed, in pixels.
+.It Ar gens
+the number of generations to evolve. Must be 0 < gens <= 999999.
+.El
.Ss Creating a video from the images
Using a tool such as
.Xr ffmpeg 1 ,
diff --git a/main.c b/main.c
@@ -2,6 +2,9 @@
* Copyright (c) 2021 Ben Fuller
*/
#include "cgol.h"
+#include <errno.h>
+#include <string.h>
+#include <limits.h>
#ifndef __TEST
#define NROWS 20
@@ -11,11 +14,52 @@
#define NCOLS 10
#endif
+/* check errno and the result of ato* for an error */
+void
+check(int res) {
+ if (res == 0 && errno != 0) {
+ fprintf(stderr, "bad argument\n");
+ fprintf(stderr, "usage: cgol [width height [gens]]\nthe defaults are \"800\" \"600\" \"200\"\n");
+ exit(1);
+ }
+ errno = 0;
+}
+
+
int
-main(void) {
- int n_gens = 200;
+main(int argc, char **argv) {
+ double width, height;
+ int gens;
+
+ if (argc > 1 && strncmp("-h", *(argv + 1), 2) == 0) {
+ fprintf(stderr, "usage: %s [width height [gens]]\nthe defaults are \"800\" \"600\" \"200\"\n", *argv);
+ return 1;
+ }
+ if (argc > 2) {
+ errno = 0;
+ width = atof(*++argv);
+ check(width);
+ height = atof(*++argv);
+ check(height);
+ if (argc > 3) {
+ gens = atoi(*++argv);
+ check(gens);
+ if (gens < 1 || gens > 999999) {
+ /* the upper limit is to ensure the gen number fits onto the
+ * image filenames */
+ fprintf(stderr, "bad gens arg\n");
+ return 1;
+ }
+ } else
+ gens = 200;
+ } else {
+ width = 800;
+ height = 600;
+ gens = 200;
+ }
+
struct imgdata img = {
- 400, 400,
+ width, height,
NROWS, NCOLS,
{ 1, 1, 1, },
{ 0.1, 0.1, 0.1 },
@@ -28,30 +72,27 @@ main(void) {
#else
short cells[NROWS][NCOLS] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 1, 0, 0, 1, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
-
- int x, y;
- x = 1;
- y = 2;
- printf("%d,%d = %hd and has %d neighbours\n", x, y, cells[y][x], neighbours(x, y, &cells[0][0], NCOLS, NROWS));
#endif
int gen, n_alive;
- char *fn = malloc(12 + 4);
- for (gen = 0; gen < n_gens; gen++) {
+ char *fn = malloc(12 + 6);
+ for (gen = 0; gen < gens; gen++) {
#ifdef __TEST
- printf("==> GEN %d <==\n", gen);
+ printf("==> GEN %d <==\r", gen);
#endif
- sprintf(fn, "images/%04d.png", gen);
+
+ /* %06d because gens <= 999999 */
+ sprintf(fn, "images/%06d.png", gen);
if (png(&img, &cells[0][0], fn) != 0) {
free(fn);
return 1;
@@ -62,6 +103,9 @@ main(void) {
#endif
}
free(fn);
+#ifdef __TEST
+ puts("");
+#endif
return 0;