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