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);
}
}
}