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