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