xref: /minix3/lib/libcurses/PSD.doc/life.c (revision 51ffecc181005cb45a40108612ee28d1daaeeb86)
1*51ffecc1SBen Gras .\"	$NetBSD: life.c,v 1.6 2003/08/07 16:44:28 agc Exp $
2*51ffecc1SBen Gras .\"
3*51ffecc1SBen Gras .\" Copyright (c) 1980, 1993
4*51ffecc1SBen Gras .\"	 The Regents of the University of California.  All rights reserved.
5*51ffecc1SBen Gras .\"
6*51ffecc1SBen Gras .\" Redistribution and use in source and binary forms, with or without
7*51ffecc1SBen Gras .\" modification, are permitted provided that the following conditions
8*51ffecc1SBen Gras .\" are met:
9*51ffecc1SBen Gras .\" 1. Redistributions of source code must retain the above copyright
10*51ffecc1SBen Gras .\"    notice, this list of conditions and the following disclaimer.
11*51ffecc1SBen Gras .\" 2. Redistributions in binary form must reproduce the above copyright
12*51ffecc1SBen Gras .\"    notice, this list of conditions and the following disclaimer in the
13*51ffecc1SBen Gras .\"    documentation and/or other materials provided with the distribution.
14*51ffecc1SBen Gras .\" 3. Neither the name of the University nor the names of its contributors
15*51ffecc1SBen Gras .\"    may be used to endorse or promote products derived from this software
16*51ffecc1SBen Gras .\"    without specific prior written permission.
17*51ffecc1SBen Gras .\"
18*51ffecc1SBen Gras .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19*51ffecc1SBen Gras .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*51ffecc1SBen Gras .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*51ffecc1SBen Gras .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22*51ffecc1SBen Gras .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*51ffecc1SBen Gras .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*51ffecc1SBen Gras .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*51ffecc1SBen Gras .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*51ffecc1SBen Gras .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*51ffecc1SBen Gras .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*51ffecc1SBen Gras .\" SUCH DAMAGE.
29*51ffecc1SBen Gras .\"
30*51ffecc1SBen Gras .\"	@(#)life.c	8.1 (Berkeley) 6/8/93
31*51ffecc1SBen Gras .\"
32*51ffecc1SBen Gras # include	<curses.h>
33*51ffecc1SBen Gras # include	<signal.h>
34*51ffecc1SBen Gras 
35*51ffecc1SBen Gras /*
36*51ffecc1SBen Gras  *	Run a life game.  This is a demonstration program for
37*51ffecc1SBen Gras  * the Screen Updating section of the -lcurses cursor package.
38*51ffecc1SBen Gras  */
39*51ffecc1SBen Gras 
40*51ffecc1SBen Gras typedef struct lst_st {			/* linked list element */
41*51ffecc1SBen Gras 	int		y, x;		/* (y, x) position of piece */
42*51ffecc1SBen Gras 	struct lst_st	*next, *last;	/* doubly linked */
43*51ffecc1SBen Gras } LIST;
44*51ffecc1SBen Gras 
45*51ffecc1SBen Gras LIST	*Head;			/* head of linked list */
46*51ffecc1SBen Gras 
47*51ffecc1SBen Gras int	die();
48*51ffecc1SBen Gras 
49*51ffecc1SBen Gras main(ac, av)
50*51ffecc1SBen Gras int	ac;
51*51ffecc1SBen Gras char	*av[];
52*51ffecc1SBen Gras {
53*51ffecc1SBen Gras 	evalargs(ac, av);		/* evaluate arguments */
54*51ffecc1SBen Gras 
55*51ffecc1SBen Gras 	initscr();			/* initialize screen package */
56*51ffecc1SBen Gras 	signal(SIGINT, die);		/* set to restore tty stats */
57*51ffecc1SBen Gras 	cbreak();			/* set for char-by-char */
58*51ffecc1SBen Gras 	noecho();			/*	input */
59*51ffecc1SBen Gras 	nonl();				/* for optimization */
60*51ffecc1SBen Gras 
61*51ffecc1SBen Gras 	getstart();			/* get starting position */
62*51ffecc1SBen Gras 	for (;;) {
63*51ffecc1SBen Gras 		prboard();		/* print out current board */
64*51ffecc1SBen Gras 		update();		/* update board position */
65*51ffecc1SBen Gras 	}
66*51ffecc1SBen Gras }
67*51ffecc1SBen Gras 
68*51ffecc1SBen Gras /*
69*51ffecc1SBen Gras  * This is the routine which is called when rubout is hit.
70*51ffecc1SBen Gras  * It resets the tty stats to their original values.  This
71*51ffecc1SBen Gras  * is the normal way of leaving the program.
72*51ffecc1SBen Gras  */
73*51ffecc1SBen Gras die()
74*51ffecc1SBen Gras {
75*51ffecc1SBen Gras 	signal(SIGINT, SIG_IGN);		/* ignore rubouts */
76*51ffecc1SBen Gras 	mvcur(0, COLS - 1, LINES - 1, 0);	/* go to bottom of screen */
77*51ffecc1SBen Gras 	endwin();				/* set terminal to good state */
78*51ffecc1SBen Gras 	exit(0);
79*51ffecc1SBen Gras }
80*51ffecc1SBen Gras 
81*51ffecc1SBen Gras /*
82*51ffecc1SBen Gras  * Get the starting position from the user.  They keys u, i, o, j, l,
83*51ffecc1SBen Gras  * m, ,, and . are used for moving their relative directions from the
84*51ffecc1SBen Gras  * k key.  Thus, u move diagonally up to the left, , moves directly down,
85*51ffecc1SBen Gras  * etc.  x places a piece at the current position, " " takes it away.
86*51ffecc1SBen Gras  * The input can also be from a file.  The list is built after the
87*51ffecc1SBen Gras  * board setup is ready.
88*51ffecc1SBen Gras  */
89*51ffecc1SBen Gras getstart()
90*51ffecc1SBen Gras {
91*51ffecc1SBen Gras 	reg char	c;
92*51ffecc1SBen Gras 	reg int		x, y;
93*51ffecc1SBen Gras 	auto char	buf[100];
94*51ffecc1SBen Gras 
95*51ffecc1SBen Gras 	box(stdscr, '|', '_');		/* box in the screen */
96*51ffecc1SBen Gras 	move(1, 1);			/* move to upper left corner */
97*51ffecc1SBen Gras 
98*51ffecc1SBen Gras 	for (;;) {
99*51ffecc1SBen Gras 		refresh();		/* print current position */
100*51ffecc1SBen Gras 		if ((c = getch()) == 'q')
101*51ffecc1SBen Gras 			break;
102*51ffecc1SBen Gras 		switch (c) {
103*51ffecc1SBen Gras 		  case 'u':
104*51ffecc1SBen Gras 		  case 'i':
105*51ffecc1SBen Gras 		  case 'o':
106*51ffecc1SBen Gras 		  case 'j':
107*51ffecc1SBen Gras 		  case 'l':
108*51ffecc1SBen Gras 		  case 'm':
109*51ffecc1SBen Gras 		  case ',':
110*51ffecc1SBen Gras 		  case '.':
111*51ffecc1SBen Gras 			adjustyx(c);
112*51ffecc1SBen Gras 			break;
113*51ffecc1SBen Gras 		  case 'f':
114*51ffecc1SBen Gras 			mvaddstr(0, 0, "File name: ");
115*51ffecc1SBen Gras 			getstr(buf);
116*51ffecc1SBen Gras 			readfile(buf);
117*51ffecc1SBen Gras 			break;
118*51ffecc1SBen Gras 		  case 'x':
119*51ffecc1SBen Gras 			addch('X');
120*51ffecc1SBen Gras 			break;
121*51ffecc1SBen Gras 		  case ' ':
122*51ffecc1SBen Gras 			addch(' ');
123*51ffecc1SBen Gras 			break;
124*51ffecc1SBen Gras 		}
125*51ffecc1SBen Gras 	}
126*51ffecc1SBen Gras 
127*51ffecc1SBen Gras 	if (Head != NULL)			/* start new list */
128*51ffecc1SBen Gras 		dellist(Head);
129*51ffecc1SBen Gras 	Head = malloc(sizeof (LIST));
130*51ffecc1SBen Gras 
131*51ffecc1SBen Gras 	/*
132*51ffecc1SBen Gras 	 * loop through the screen looking for 'x's, and add a list
133*51ffecc1SBen Gras 	 * element for each one
134*51ffecc1SBen Gras 	 */
135*51ffecc1SBen Gras 	for (y = 1; y < LINES - 1; y++)
136*51ffecc1SBen Gras 		for (x = 1; x < COLS - 1; x++) {
137*51ffecc1SBen Gras 			move(y, x);
138*51ffecc1SBen Gras 			if (inch() == 'x')
139*51ffecc1SBen Gras 				addlist(y, x);
140*51ffecc1SBen Gras 		}
141*51ffecc1SBen Gras }
142*51ffecc1SBen Gras 
143*51ffecc1SBen Gras /*
144*51ffecc1SBen Gras  * Print out the current board position from the linked list
145*51ffecc1SBen Gras  */
146*51ffecc1SBen Gras prboard() {
147*51ffecc1SBen Gras 
148*51ffecc1SBen Gras 	reg LIST	*hp;
149*51ffecc1SBen Gras 
150*51ffecc1SBen Gras 	erase();			/* clear out last position */
151*51ffecc1SBen Gras 	box(stdscr, '|', '_');		/* box in the screen */
152*51ffecc1SBen Gras 
153*51ffecc1SBen Gras 	/*
154*51ffecc1SBen Gras 	 * go through the list adding each piece to the newly
155*51ffecc1SBen Gras 	 * blank board
156*51ffecc1SBen Gras 	 */
157*51ffecc1SBen Gras 	for (hp = Head; hp; hp = hp->next)
158*51ffecc1SBen Gras 		mvaddch(hp->y, hp->x, 'X');
159*51ffecc1SBen Gras 
160*51ffecc1SBen Gras 	refresh();
161*51ffecc1SBen Gras }
162