home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource5
/
301_01
/
lif.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-30
|
17KB
|
1,061 lines
/*
HEADER: CUG301;
TITLE: Conway's game of life;
DATE: 09/30/89;
DESCRIPTION: "This program is an example of the usage of the pull-down
graphics menu system (menu.c/menu.h) on the same disk.";
KEYWORDS: mathematical games, finite automata;
FILENAME: LIF.C;
WARNINGS: "The author claims copyrights and authorizes
non-commercial use only.";
AUTHORS: John Muczynski;
COMPILERS: Turbo C version 2.0;
*/
/*
lif.c
Conway's game of life.
(uses menu)
(c) Copyright 1989 by John Muczynski. All Rights Reserved.
*/
/* BULLETINS
jsm 09/04/89 known problems:
1. the box is not being turned off properly.
2. add a menu so that 1. is a feature after the bug is fixed.
3. make global commands work inside of box (run/seed/...)
4. the main computation loop can be made to run faster by using
a state table.
5. if you stamp when no file is active, then it blows up.
6. if you stamp when part of the box isn't on the plane, then
it blows up. (should wrap-around)
FUTURE EXPANSION:
jsm 09/29/89 -Need to check details before executing each function
from the user's keys. For example, the [?][b][r] function
will run into never-never land if you execute it before
specifing a block.
-Need to assign default hot-keys.
-Need functions to mirror image the box over either the
x or the y axis. A second cursor (and box) would also
be useful.
-Need to take the input for the file name from the MENU
buffer so that macros can name files to be loaded and
saved.
-Need to optimize the run-time loop with a state machine
so that it runs faster.
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <bios.h>
#include <graphics.h>
#include "menu.h"
#define SIZE 5
#define COLS 17 /* MAX OF 17 MIN OF ??1?? */
#define ROWS 60 /* MAX OF 60 MIN OF */
/* HOW MUCH SPACE TO LEAVE AT LEFT OF SCREEN */
#define COLOFF 11
/* HOW MUCH SPACE TO LEAVE AT TOP OF SCREEN (FOR MENUS) */
#define ROWOFF 30 /* MIN OF 30 OR SO */
void initgr();
void onblk();
typedef int plane[COLS][ROWS];
plane data1 = {0};
plane data2 = {0};
plane *old_ptr = &data1;
plane *new_ptr = &data2;
plane *temp_ptr = 0;
#define OLD_DATA (*old_ptr)
#define NEW_DATA (*new_ptr)
void cleardat();
static int oldX=0, oldY=0;
static int curX=0, curY=0;
static int blockX=0, blockY=0, blockon=0;
FILE *infil;
FILE *outfil;
int writeit(int val)
{
fprintf(outfil,"%c",val*( '*' - '.' ) +'.');
return(val);
};
void writelf()
{
fprintf(outfil,"\n");
};
static failflag=0;
/* doesn't use param that is passed */
int readit()
{
unsigned char ch;
int val;
fscanf(infil,"%c",&ch);
val = (ch!='.'); /* IF ERROR, THEN MAKE IT 'ON' */
return(val||failflag);
};
void readlf()
{
char ch;
fscanf(infil,"%c",&ch);
if (ch!='\n') failflag=1;
};
static int temp;
#define swapint(a,b) {temp=a; a=b; b=temp;}
/* do something to the marked block */
void eachblk(funct,functlf)
int funct(int val);
void functlf();
{
int x,y;
int ex, ey;
int i,j, mask, oldval,newval;
int fx,fy;
int bX,bY;
failflag=0;
if (blockon==1) {
bX=blockX;
bY=blockY;
};
if (blockon==2) {
bX=oldX-blockX;
bY=oldY-blockY;
};
fx=bX;
fy=bY;
ex=oldX;
ey=oldY;
if (ex<fx) swapint(ex,fx);
if (ey<fy) swapint(ey,fy);
for(j=fy;j<=ey;j++){
for(i=fx;i<=ex;i++){
x=i/8;
mask = (1 << (i%8));
y=j;
oldval = ( (NEW_DATA[x][y] & mask) != 0);
newval = (funct(oldval) != 0);
if (newval!=oldval) {
NEW_DATA[x][y] = NEW_DATA[x][y] ^ mask;
if( (OLD_DATA[x][y] & mask) == (NEW_DATA[x][y] & mask) ) {
OLD_DATA[x][y] = OLD_DATA[x][y] ^ mask;
};
};
}; /* end for i */
functlf();
}; /* end for j */
};
static char filnam[80];
static char *root = ""; /* WAS "IMAGES\\" */
/* turn off graphics and get a file name */
void getname(char *filnam)
{
int len;
char base[40];
savescr();
system("dir /w images");
printf("\n\n\nEnter the base file name: ");
fgets(base,40,stdin);
len = strlen(base);
if (isspace(base[len-1]) ) len--;
base[len]='\0';
strcpy(filnam,root);
strcat(filnam,base);
printf("\n using '%s'\n\n",filnam);
};
void readblk()
{
int i,j;
char ch;
getname(filnam);
infil = fopen(filnam,"r");
fscanf(infil,"%d %d%c",&i,&j,&ch);
fclose(infil);
restorescr();
blockon=2;
blockX=1-i;
blockY=1-j;
onblk();
};
/* doesn't use param that is passed */
int fillit()
{
return(1);
};
void filllf()
{
};
void fillblk()
{
eachblk(fillit,filllf);
};
/* doesn't use param that is passed */
int emptyit()
{
return(0);
};
void emptylf()
{
};
void emptyblk()
{
eachblk(emptyit,emptylf);
};
int revit(int it)
{
return(!it);
};
void revlf()
{
};
void reverseblk()
{
eachblk(revit,revlf);
};
void enterblk()
{
int i,j;
char ch;
infil = fopen(filnam,"r");
fscanf(infil,"%d %d%c",&i,&j,&ch);
blockon=2;
blockX=1-i;
blockY=1-j;
eachblk(readit,readlf);
fclose(infil);
};
void writeblk()
{
char filnam[80];
int x,y;
int ex, ey;
int i,j;
int bX,bY;
if (blockon==1) {
bX=blockX;
bY=blockY;
};
if (blockon==2) {
bX=oldX-blockX;
bY=oldY-blockY;
};
x=bX;
y=bY;
ex=oldX;
ey=oldY;
if (ex<x) swapint(ex,x);
if (ey<y) swapint(ey,y);
i=ex-x+1;
j=ey-y+1;
getname(filnam);
outfil = fopen(filnam,"w");
fprintf(outfil,"%d %d\n",i,j);
eachblk(writeit,writelf);
fclose(outfil);
restorescr();
};
/* turn the block on or off */
void putblk(col)
int col;
{
int x,y;
int ex, ey;
int bX,bY;
if (blockon==1) {
bX=blockX;
bY=blockY;
};
if (blockon==2) {
bX=oldX-blockX;
bY=oldY-blockY;
};
if (blockon) {
x=bX*SIZE+SIZE+1+COLOFF-2;
y=bY*SIZE+SIZE+1+ROWOFF -2;
ex=oldX*SIZE+SIZE+1+COLOFF -2;
ey=oldY*SIZE+SIZE+1+ROWOFF -2;
if (ex<x) swapint(ex,x);
if (ey<y) swapint(ey,y);
setcolor(col);
rectangle(x,y,ex+SIZE,ey+SIZE);
};
};
void onblk()
{
putblk(15);
};
void offblk()
{
putblk(00);
};
void rim()
{
int x1,y1;
int x2,y2;
x1=8*COLS *SIZE+SIZE+1+COLOFF-2;
y1=ROWS *SIZE+SIZE+1+ROWOFF -2;
x2= SIZE+1+COLOFF-2;
y2= SIZE+1+ROWOFF -2;
setcolor(15);
rectangle(x1+1,y1+1,x2-1,y2-1);
};
void cleardat()
{
int i,j;
offblk();
blockon=0;
clearviewport();
rim();
for(i=0;i<COLS;i=i+2){
for(j=0;j<ROWS;j=j+3){
OLD_DATA[i][j] = 0;
NEW_DATA[i][j] = 0;
};
};
};
void randdata()
{
int i,j;
for(i=0;i<COLS;i=i+1){
for(j=0;j<ROWS;j=j+1){
OLD_DATA[i][j] = (rand() % 256)& 0xFF;
NEW_DATA[i][j] = OLD_DATA[i][j] ^ 0xFF;
};
};
};
void neighbor(funct)
int funct(int);
{
int row_before, row_here, row_after;
int col_here, shiftsize;
int bits_before, bits_here, bits_after;
int col_mod, bitpos;
int mask;
int newmod; /* value of current row,col */
row_before = ROWS-1;
row_here = 0;
row_after = 1;
nextrow:
/* load up first 9 bits to be the last 1 and the leftmost 8 */
bits_before = ( (OLD_DATA[0][row_before]) <<1) | ( 1&( (OLD_DATA[COLS-1][row_before])>>7 ) );
bits_here = ( (OLD_DATA[0][row_here]) <<1) | ( 1&( (OLD_DATA[COLS-1][row_here])>>7 ) );
bits_after = ( (OLD_DATA[0][row_after]) <<1) | ( 1&( (OLD_DATA[C