xref: /original-bsd/lib/libcurses/PSD.doc/life.c (revision ec35a16d)
1 .\" Copyright (c) 1980, 1993
2 .\"	 The Regents of the University of California.  All rights reserved.
3 .\"
4 .\" %sccs.include.redist.roff%
5 .\"
6 .\"	@(#)life.c	8.1 (Berkeley) 06/08/93
7 .\"
8 # include	<curses.h>
9 # include	<signal.h>
10 
11 /*
12  *	Run a life game.  This is a demonstration program for
13  * the Screen Updating section of the -lcurses cursor package.
14  */
15 
16 typedef struct lst_st {			/* linked list element */
17 	int		y, x;		/* (y, x) position of piece */
18 	struct lst_st	*next, *last;	/* doubly linked */
19 } LIST;
20 
21 LIST	*Head;			/* head of linked list */
22 
23 int	die();
24 
25 main(ac, av)
26 int	ac;
27 char	*av[];
28 {
29 	evalargs(ac, av);		/* evaluate arguments */
30 
31 	initscr();			/* initialize screen package */
32 	signal(SIGINT, die);		/* set to restore tty stats */
33 	cbreak();			/* set for char-by-char */
34 	noecho();			/*	input */
35 	nonl();				/* for optimization */
36 
37 	getstart();			/* get starting position */
38 	for (;;) {
39 		prboard();		/* print out current board */
40 		update();		/* update board position */
41 	}
42 }
43 
44 /*
45  * This is the routine which is called when rubout is hit.
46  * It resets the tty stats to their original values.  This
47  * is the normal way of leaving the program.
48  */
49 die()
50 {
51 	signal(SIGINT, SIG_IGN);		/* ignore rubouts */
52 	mvcur(0, COLS - 1, LINES - 1, 0);	/* go to bottom of screen */
53 	endwin();				/* set terminal to good state */
54 	exit(0);
55 }
56 
57 /*
58  * Get the starting position from the user.  They keys u, i, o, j, l,
59  * m, ,, and . are used for moving their relative directions from the
60  * k key.  Thus, u move diagonally up to the left, , moves directly down,
61  * etc.  x places a piece at the current position, " " takes it away.
62  * The input can also be from a file.  The list is built after the
63  * board setup is ready.
64  */
65 getstart()
66 {
67 	reg char	c;
68 	reg int		x, y;
69 	auto char	buf[100];
70 
71 	box(stdscr, '|', '_');		/* box in the screen */
72 	move(1, 1);			/* move to upper left corner */
73 
74 	for (;;) {
75 		refresh();		/* print current position */
76 		if ((c = getch()) == 'q')
77 			break;
78 		switch (c) {
79 		  case 'u':
80 		  case 'i':
81 		  case 'o':
82 		  case 'j':
83 		  case 'l':
84 		  case 'm':
85 		  case ',':
86 		  case '.':
87 			adjustyx(c);
88 			break;
89 		  case 'f':
90 			mvaddstr(0, 0, "File name: ");
91 			getstr(buf);
92 			readfile(buf);
93 			break;
94 		  case 'x':
95 			addch('X');
96 			break;
97 		  case ' ':
98 			addch(' ');
99 			break;
100 		}
101 	}
102 
103 	if (Head != NULL)			/* start new list */
104 		dellist(Head);
105 	Head = malloc(sizeof (LIST));
106 
107 	/*
108 	 * loop through the screen looking for 'x's, and add a list
109 	 * element for each one
110 	 */
111 	for (y = 1; y < LINES - 1; y++)
112 		for (x = 1; x < COLS - 1; x++) {
113 			move(y, x);
114 			if (inch() == 'x')
115 				addlist(y, x);
116 		}
117 }
118 
119 /*
120  * Print out the current board position from the linked list
121  */
122 prboard() {
123 
124 	reg LIST	*hp;
125 
126 	erase();			/* clear out last position */
127 	box(stdscr, '|', '_');		/* box in the screen */
128 
129 	/*
130 	 * go through the list adding each piece to the newly
131 	 * blank board
132 	 */
133 	for (hp = Head; hp; hp = hp->next)
134 		mvaddch(hp->y, hp->x, 'X');
135 
136 	refresh();
137 }
138