phillips@cs.ubc.ca (George Phillips) (02/12/90)
Here is my wireworld simulator for the PC. I compiled it using Turbo-C 2.0, but any version of Turbo-C should do. It uses text characters for the display. WARNING: This program is almost everything a good program shouldn't be: inefficient, fragile and inflexible. It does, however, simulate wireworld. It is in the public domain and if you want to claim you wrote it, please do. -- George Phillips phillips@cs.ubc.ca {alberta,uw-beaver,uunet}!ubc-cs!phillips /* * wire -- simulate the wireworld as described in "Computer Recreations", * Scientific American, Jan. 1990, p. 146 * * A real dumb-o algorithm is used. * * use: wire wire-file * * A wire-file uses '=' for a wire cell, '.' or ' ' for a space cell, * '#' for an electron head and '-' for an electron tail. * * The program waits for a key after each generation and quits if it * gets a 'q' or ESC. */ #include <stdio.h> #include <conio.h> #define MX (80) #define MY (24) #define SPACE (0) #define WIRE (1) #define HEAD (2) #define TAIL (3) static char w1[MY][MX]; static char w2[MY][MX]; static char *pretty = " =#-"; static void print_world(void); static void next_gen(void); main(int argc, char* argv[]) { static char buf[256]; char* p; int x; int y; FILE* fp; int ch; if (argc != 2) { fprintf(stderr, "usage: wire file\n"); exit(1); } if ((fp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "wire: can't open %s\n", argv[1]); exit(1); } for (x = 0; x < MX; x++) for (y = 0; y < MY; y++) { w1[y][x] = SPACE; w2[y][x] = SPACE; } y = 1; while (fgets(buf, 256, fp) != NULL) { x = 1; for (p = buf; *p; p++, x++) { switch (*p) { case '.': case ' ': w2[y][x] = SPACE; break; case '=': w2[y][x] = WIRE; break; case '#': w2[y][x] = HEAD; break; case '-': w2[y][x] = TAIL; break; case '\n': break; default: fprintf(stderr, "bad character in input: %c\n", *p); exit(1); } } y++; } fclose(fp); clrscr(); for (;;) { print_world(); next_gen(); ch = getch(); if (ch == 'q' || ch == 'Q' || ch == 27) break; } exit(0); } static void print_world(void) { int x; int y; for (y = 0; y < MY; y++) for (x = 0; x < MX; x++) { if (w2[y][x] != w1[y][x]) { gotoxy(x + 1, y + 1); putch(pretty[w2[y][x]]); w1[y][x] = w2[y][x]; } } } static void next_gen(void) { int x; int y; int count; for (y = 1; y < MY - 1; y++) for (x = 1; x < MX - 1; x++) { switch (w1[y][x]) { case SPACE: w2[y][x] = SPACE; break; case TAIL: w2[y][x] = WIRE; break; case HEAD: w2[y][x] = TAIL; break; case WIRE: count = 0; if (w1[y - 1][x - 1] == HEAD) count++; if (w1[y ][x - 1] == HEAD) count++; if (w1[y + 1][x - 1] == HEAD) count++; if (w1[y - 1][x ] == HEAD) count++; if (w1[y + 1][x ] == HEAD) count++; if (w1[y - 1][x + 1] == HEAD) count++; if (w1[y ][x + 1] == HEAD) count++; if (w1[y + 1][x + 1] == HEAD) count++; if (count == 1 || count == 2) w2[y][x] = HEAD; else w2[y][x] = WIRE; break; default: fprintf(stderr, "uh-oh...\n"); exit(1); } } }