xref: /original-bsd/lib/libcurses/PSD.doc/life.c (revision 54e6d6c7)
1 /*
2  * Copyright (c) 1980 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)life.c	6.2 (Berkeley) 03/17/89";
26 #endif /* not lint */
27 
28 # include	<curses.h>
29 # include	<signal.h>
30 
31 /*
32  *	Run a life game.  This is a demonstration program for
33  * the Screen Updating section of the -lcurses cursor package.
34  */
35 
36 typedef struct lst_st {			/* linked list element */
37 	int		y, x;		/* (y, x) position of piece */
38 	struct lst_st	*next, *last;	/* doubly linked */
39 } LIST;
40 
41 LIST	*Head;			/* head of linked list */
42 
43 int	die();
44 
45 main(ac, av)
46 int	ac;
47 char	*av[];
48 {
49 	evalargs(ac, av);		/* evaluate arguments */
50 
51 	initscr();			/* initialize screen package */
52 	signal(SIGINT, die);		/* set to restore tty stats */
53 	cbreak();			/* set for char-by-char */
54 	noecho();			/*	input */
55 	nonl();				/* for optimization */
56 
57 	getstart();			/* get starting position */
58 	for (;;) {
59 		prboard();		/* print out current board */
60 		update();		/* update board position */
61 	}
62 }
63 
64 /*
65  * This is the routine which is called when rubout is hit.
66  * It resets the tty stats to their original values.  This
67  * is the normal way of leaving the program.
68  */
69 die()
70 {
71 	signal(SIGINT, SIG_IGN);		/* ignore rubouts */
72 	mvcur(0, COLS - 1, LINES - 1, 0);	/* go to bottom of screen */
73 	endwin();				/* set terminal to good state */
74 	exit(0);
75 }
76 
77 /*
78  * Get the starting position from the user.  They keys u, i, o, j, l,
79  * m, ,, and . are used for moving their relative directions from the
80  * k key.  Thus, u move diagonally up to the left, , moves directly down,
81  * etc.  x places a piece at the current position, " " takes it away.
82  * The input can also be from a file.  The list is built after the
83  * board setup is ready.
84  */
85 getstart()
86 {
87 	reg char	c;
88 	reg int		x, y;
89 	auto char	buf[100];
90 
91 	box(stdscr, '|', '_');		/* box in the screen */
92 	move(1, 1);			/* move to upper left corner */
93 
94 	for (;;) {
95 		refresh();		/* print current position */
96 		if ((c = getch()) == 'q')
97 			break;
98 		switch (c) {
99 		  case 'u':
100 		  case 'i':
101 		  case 'o':
102 		  case 'j':
103 		  case 'l':
104 		  case 'm':
105 		  case ',':
106 		  case '.':
107 			adjustyx(c);
108 			break;
109 		  case 'f':
110 			mvaddstr(0, 0, "File name: ");
111 			getstr(buf);
112 			readfile(buf);
113 			break;
114 		  case 'x':
115 			addch('X');
116 			break;
117 		  case ' ':
118 			addch(' ');
119 			break;
120 		}
121 	}
122 
123 	if (Head != NULL)			/* start new list */
124 		dellist(Head);
125 	Head = malloc(sizeof (LIST));
126 
127 	/*
128 	 * loop through the screen looking for 'x's, and add a list
129 	 * element for each one
130 	 */
131 	for (y = 1; y < LINES - 1; y++)
132 		for (x = 1; x < COLS - 1; x++) {
133 			move(y, x);
134 			if (inch() == 'x')
135 				addlist(y, x);
136 		}
137 }
138 
139 /*
140  * Print out the current board position from the linked list
141  */
142 prboard() {
143 
144 	reg LIST	*hp;
145 
146 	erase();			/* clear out last position */
147 	box(stdscr, '|', '_');		/* box in the screen */
148 
149 	/*
150 	 * go through the list adding each piece to the newly
151 	 * blank board
152 	 */
153 	for (hp = Head; hp; hp = hp->next)
154 		mvaddch(hp->y, hp->x, 'X');
155 
156 	refresh();
157 }
158