home *** CD-ROM | disk | FTP | other *** search
- From: jek5036@ultb.isc.rit.edu (J.E. King)
- Newsgroups: comp.sources.misc
- Subject: v17i061: clife - Curses based Life simulator, Part01/01
- Message-ID: <1991Mar21.210335.11867@sparky.IMD.Sterling.COM>
- Date: 21 Mar 91 21:03:35 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 33523710 56f0f4dc 69397a9c d9920629
-
- Submitted-by: J.E. King <jek5036@ultb.isc.rit.edu>
- Posting-number: Volume 17, Issue 61
- Archive-name: clife/part01
-
- This is called clife, or a curses implementation life simulator. It
- simulates the life 'function' which is described in the manual page.
- Basically it could be thought of as a game, but it isn't. That's
- why the manual page is under clife.6.
-
- Jim King, (jek5036@ultb.isc.rit.edu)
-
- -- cut here -- cut here -- cut here -- cut here -- cut here -- cut here --
- #!/bin/sh
- # to extract, remove the header and type "sh filename"
- if `test ! -s ./Makefile`
- then
- echo "writing ./Makefile"
- cat > ./Makefile << '\End\Of\Shar\'
- CFLAGS = -O
- DEST = .
- MANDEST = /usr/man/man6
- EXTHDRS = /usr/include/curses.h \
- /usr/include/sgtty.h \
- /usr/include/signal.h \
- /usr/include/stdio.h \
- /usr/include/sys/ioctl.h \
- /usr/include/sys/ttychars.h \
- /usr/include/sys/ttydev.h \
- /usr/include/sys/ttyio.h \
- /usr/include/time.h
- HDRS =
- LDFLAGS = -O
- LIBS = -lcurses -ltermlib
- LINKER = cc
- MAKEFILE = Makefile
- OBJS = clife.o
- PRINT = lpr
- PROGRAM = clife
- SRCS = clife.c
-
- all: $(PROGRAM)
-
- $(PROGRAM): $(OBJS)
- @echo -n "Loading $(PROGRAM) ... "
- @$(LINKER) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
- @echo "done"
-
- clean:; @rm -f $(OBJS)
-
- depend:; @mkmf -f $(MAKEFILE) PROGRAM=$(PROGRAM) DEST=$(DEST)
-
- index:; @ctags -wx $(HDRS) $(SRCS)
-
- install: $(PROGRAM)
- @echo Installing $(PROGRAM) in $(DEST)
- @install -s $(PROGRAM) $(DEST)
- @echo Copying manual pages...
- @cp clife.6 $(MANDEST)
- @chmod 644 $(MANDEST)/clife.6
-
- print:; @$(PRINT) $(HDRS) $(SRCS)
-
- program: $(PROGRAM)
-
- tags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS)
-
- update: $(DEST)/$(PROGRAM)
-
- $(DEST)/$(PROGRAM): $(SRCS) $(LIBS) $(HDRS) $(EXTHDRS)
- @make -f $(MAKEFILE) DEST=$(DEST)
- ###
- clife.o: /usr/include/signal.h /usr/include/time.h /usr/include/stdio.h \
- /usr/include/curses.h /usr/include/sgtty.h /usr/include/sys/ioctl.h \
- /usr/sys/h/ttychars.h /usr/sys/h/ttydev.h /usr/sys/h/ttyio.h \
- /usr/sys/h/sgtty.h /usr/include/sys/ttychars.h \
- /usr/include/sys/ttydev.h /usr/include/sys/ttyio.h
- \End\Of\Shar\
- else
- echo "will not over write ./Makefile"
- fi
- if `test ! -s ./clife.6`
- then
- echo "writing ./clife.6"
- cat > ./clife.6 << '\End\Of\Shar\'
- .TH clife 6
- .SH Name
- clife \- Life simulation using curses
- .SH Syntax
- .B clife
- \fI[-d] [-p]\fR
- .SH Description
- The
- .PN clife
- program is a simulator which has been around for quite some time.
- The screen is set up, with random 'people' on the screen. Each
- person is represented by a '*'. The rules are simple: If there are
- three people around any given square, a person is born there. If
- there are only two people around any given square, then it does not
- change. Any other number around a square kills the person there.
- .PP
- The clife (which stands for curses life) simulator will produce certain
- distinguishable patterns attributable to the life equation.
- .SH Options
- The
- .PN \-d
- option allows you to draw your own pattern on the screen
- and run it through the simulator. This is done by moving around the
- screen with the arrow keys and using space to put a person in the
- square you are currently over, or if there is a person there already,
- kill it.
-
- The
- .PN \-p
- option will print out information about the life cycles on the bottom
- of the screen.
- .SH Author
- Jim King, (jek5036@ritvax.isc.rit.edu)
- \End\Of\Shar\
- else
- echo "will not over write ./clife.6"
- fi
- if `test ! -s ./clife.c`
- then
- echo "writing ./clife.c"
- cat > ./clife.c << '\End\Of\Shar\'
- /*
- * clife.c - curses life simulator. Translated from Pascal to C implementing
- * curses Oct 1988 by pulsar@lsrhs, not jek5036@ritvax.isc.rit.edu
- *
- * V2 - Draw your own pattern then 'life' it.
- */
-
- #include <signal.h>
- #include <time.h>
- #include <stdio.h>
- #include <curses.h>
-
- /* a value of -1 will make it go forever */
- /* a value of 0 will make it exit immed. */
- #define REPSTOP -1 /* number of repetitions before stop */
-
- int present[23][80], /* screen 1 cycle ago */
- past[23][80], /* screen this cycle */
- total, /* total # of changes */
- icnt, /* counter to check for repetition */
- maxrow = 22, /* some defines to represent the screen */
- maxcol = 79,
- minrow = 0,
- mincol = 0,
- pri = 0, /* flag for printing stats on bottom line */
- draw = 0, /* flag for drawing your own screen */
- i, j, k, /* loop counters */
- cycle, /* current cycle # */
- changes, /* # of changes this cycle (live + die) */
- die, /* number of deaths this cycle */
- live; /* number of births this cycle */
-
- WINDOW *mns, /* Main Screen */
- *info; /* Bottom line */
-
- /*
- * cleanup - cleanup then exit
- */
-
- cleanup()
- {
- move(23, 0); /* go to bottom of screen */
- refresh(); /* update cursor */
- exit(1); /* exit */
- }
-
- /*
- * initialize - init windows, variables, and signals
- */
-
- initialize()
- {
- srandom(getpid()); /* init random seed */
- initscr(); /* init curses */
- signal(SIGINT, cleanup); /* catch ^C */
- mns = newwin(maxrow, maxcol, 0, 0); /* new window */
- scrollok(mns, FALSE);
- info = newwin(1, 80, 23, 0);
- scrollok(info, FALSE);
- wclear(mns);
- wclear(info);
- wmove(info, 0, 0);
- wprintw(info, "Life V2 by Jim King (pulsar@lsrhs)");
- wrefresh(info);
- sleep(3);
- if (!draw) { /* if no draw, make random pattern */
- for (j = 0; j < maxrow; j++) {
- for (k = 0; k < maxcol; k++) {
- present[j][k] = random()%2;
- if (present[j][k] == 1) changes++, live++;
- }
- }
- }
- }
-
- /*
- * makscr - make your own screen using arrow keys and space bar
- */
-
- makscr()
- {
- int curx, cury; /* current point on screen */
- char c; /* input char */
-
- wclear(info);
- wmove(info, 0, 0);
- wprintw(info, "Use arrow keys to move, space to place / erase, ^D to start");
- wrefresh(info);
- curx = cury = 1;
- wmove(mns, cury-1, curx-1); wrefresh(mns);
- noecho(); crmode();
- for (;;) {
- c = wgetch(mns);
- if (c == '\004')
- break;
- else if (c == ' ') {
- if (present[cury][curx]) {
- --present[cury][curx];
- changes++;
- die++;
- mvwaddch(mns, cury, curx, ' ');
- } else {
- ++present[cury][curx];
- changes++;
- live++;
- mvwaddch(mns, cury, curx, '*');
- }
- } else if (c == '\033') {
- wgetch(mns);
- switch(wgetch(mns)) {
- case 'A':
- --cury; break;
- case 'B':
- ++cury; break;
- case 'C':
- ++curx; break;
- case 'D':
- --curx; break;
- default:
- break;
- }
- }
- if (cury > maxrow) cury = minrow;
- if (cury < minrow) cury = maxrow;
- if (curx > maxcol) curx = mincol;
- if (curx < mincol) curx = maxcol;
- wmove(mns, cury, curx);
- wrefresh(mns);
- }
- wclear(info);
- }
-
- /* Update rules: 2 or 3 adjacent alive --- stay alive
- * 3 adjacent alive -- dead to live
- * all else die or stay dead
- */
-
- update() /* Does all mathmatical calculations */
- {
- int howmany, w, x, y, z;
- changes = die = live = 0;
- for (j = 0; j < maxrow; j++) {
- for (k = 0; k < maxcol; k++) {
- w = j-1; x = j+1;
- y = k-1; z = k+1;
-
- howmany = (past[w][y] + past[w][k] + past[w][z] +
- past[j][y] + past[j][z] + past[x][y] +
- past[x][k] + past[x][z]);
-
- switch(howmany) {
- case 0:
- case 1:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- present[j][k] = 0;
- if (past[j][k]) changes++, die++;
- break;
- case 3:
- present[j][k] = 1;
- if (!past[j][k]) changes++, live++;
- break;
- default:
- break;
- }
- }
- }
- if (live == die)
- ++icnt;
- else
- icnt = 0;
-
- if (icnt == REPSTOP)
- cleanup();
- }
-
- /*
- * print - updates the screen according to changes from past to present
- */
-
- print() /* Updates the screen, greatly improved using curses */
- {
- if (pri) {
- wmove(info, 0, 0);
- total += changes;
- wprintw(info, "Cycle %d | %d changes: %d died and %d born & %d total changes", ++cycle, changes, die, live, total);
- wclrtoeol(info);
- }
- for (j = 1; j < maxrow; j++) {
- for (k = 1; k < maxcol; k++) {
- if (present[j][k] != past[j][k] && present[j][k] == 1) {
- wmove(mns, j, k);
- wprintw(mns, "*");
- } else if (present[j][k] != past[j][k] && present[j][k] == 0) {
- wmove(mns, j, k);
- wprintw(mns, " ");
- }
- }
- }
- if (pri) wrefresh(info);
- wrefresh(mns);
- }
-
- /*
- * main - main procedure
- */
-
- main(ac, av)
- int ac;
- char *av[];
- {
- if (ac > 1) {
- for (j = 1; j < ac; j++) {
- switch(av[j][1]) {
- case 'd':
- ++draw;
- break;
- case 'p':
- ++pri;
- break;
- default:
- fprintf(stderr, "%s: usage: %s [-d] [-p]\n", av[0]);
- exit(1);
- }
- }
- }
-
- if (draw)
- printf("User-built screen\n");
- if (pri)
- printf("Print statistics\n");
-
- sleep(2);
-
- initialize();
- if (draw)
- makscr();
-
- for (;;) {
- print();
- for (j = 0; j < maxrow; j++) {
- for (k = 0; k < maxcol; k++)
- past[j][k] = present[j][k];
- }
- update();
- }
- }
- \End\Of\Shar\
- else
- echo "will not over write ./clife.c"
- fi
- echo "Finished archive 1 of 1"
- exit
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-