162779Sbostic .\" Copyright (c) 1980, 1993 262779Sbostic .\" The Regents of the University of California. All rights reserved. 348164Sbostic .\" 448164Sbostic .\" %sccs.include.redist.roff% 548164Sbostic .\" 6*62780Sbostic .\" @(#)life.c 8.1 (Berkeley) 06/08/93 748164Sbostic .\" 827331Smckusick # include <curses.h> 927331Smckusick # include <signal.h> 1027331Smckusick 1127331Smckusick /* 1227331Smckusick * Run a life game. This is a demonstration program for 1327331Smckusick * the Screen Updating section of the -lcurses cursor package. 1427331Smckusick */ 1527331Smckusick 1627333Smckusick typedef struct lst_st { /* linked list element */ 1727331Smckusick int y, x; /* (y, x) position of piece */ 1827331Smckusick struct lst_st *next, *last; /* doubly linked */ 1927333Smckusick } LIST; 2027331Smckusick 2127331Smckusick LIST *Head; /* head of linked list */ 2227331Smckusick 2327333Smckusick int die(); 2427333Smckusick 2527331Smckusick main(ac, av) 2627331Smckusick int ac; 2727333Smckusick char *av[]; 2827333Smckusick { 2927331Smckusick evalargs(ac, av); /* evaluate arguments */ 3027331Smckusick 3127331Smckusick initscr(); /* initialize screen package */ 3227331Smckusick signal(SIGINT, die); /* set to restore tty stats */ 3327333Smckusick cbreak(); /* set for char-by-char */ 3427331Smckusick noecho(); /* input */ 3527331Smckusick nonl(); /* for optimization */ 3627331Smckusick 3727331Smckusick getstart(); /* get starting position */ 3827331Smckusick for (;;) { 3927331Smckusick prboard(); /* print out current board */ 4027331Smckusick update(); /* update board position */ 4127331Smckusick } 4227331Smckusick } 4327331Smckusick 4427331Smckusick /* 4527331Smckusick * This is the routine which is called when rubout is hit. 4627331Smckusick * It resets the tty stats to their original values. This 4727331Smckusick * is the normal way of leaving the program. 4827331Smckusick */ 4927333Smckusick die() 5027333Smckusick { 5127333Smckusick signal(SIGINT, SIG_IGN); /* ignore rubouts */ 5227333Smckusick mvcur(0, COLS - 1, LINES - 1, 0); /* go to bottom of screen */ 5327333Smckusick endwin(); /* set terminal to good state */ 5427331Smckusick exit(0); 5527331Smckusick } 5627331Smckusick 5727331Smckusick /* 5827331Smckusick * Get the starting position from the user. They keys u, i, o, j, l, 5927331Smckusick * m, ,, and . are used for moving their relative directions from the 6027331Smckusick * k key. Thus, u move diagonally up to the left, , moves directly down, 6127331Smckusick * etc. x places a piece at the current position, " " takes it away. 6227331Smckusick * The input can also be from a file. The list is built after the 6327331Smckusick * board setup is ready. 6427331Smckusick */ 6527333Smckusick getstart() 6627333Smckusick { 6727331Smckusick reg char c; 6827331Smckusick reg int x, y; 6927333Smckusick auto char buf[100]; 7027331Smckusick 7127331Smckusick box(stdscr, '|', '_'); /* box in the screen */ 7227331Smckusick move(1, 1); /* move to upper left corner */ 7327331Smckusick 7427333Smckusick for (;;) { 7527331Smckusick refresh(); /* print current position */ 7627333Smckusick if ((c = getch()) == 'q') 7727331Smckusick break; 7827331Smckusick switch (c) { 7927331Smckusick case 'u': 8027331Smckusick case 'i': 8127331Smckusick case 'o': 8227331Smckusick case 'j': 8327331Smckusick case 'l': 8427331Smckusick case 'm': 8527331Smckusick case ',': 8627331Smckusick case '.': 8727331Smckusick adjustyx(c); 8827331Smckusick break; 8927331Smckusick case 'f': 9027331Smckusick mvaddstr(0, 0, "File name: "); 9127331Smckusick getstr(buf); 9227331Smckusick readfile(buf); 9327331Smckusick break; 9427331Smckusick case 'x': 9527331Smckusick addch('X'); 9627331Smckusick break; 9727331Smckusick case ' ': 9827331Smckusick addch(' '); 9927331Smckusick break; 10027331Smckusick } 10127331Smckusick } 10227331Smckusick 10327331Smckusick if (Head != NULL) /* start new list */ 10427331Smckusick dellist(Head); 10527331Smckusick Head = malloc(sizeof (LIST)); 10627331Smckusick 10727331Smckusick /* 10827331Smckusick * loop through the screen looking for 'x's, and add a list 10927331Smckusick * element for each one 11027331Smckusick */ 11127331Smckusick for (y = 1; y < LINES - 1; y++) 11227331Smckusick for (x = 1; x < COLS - 1; x++) { 11327331Smckusick move(y, x); 11427331Smckusick if (inch() == 'x') 11527331Smckusick addlist(y, x); 11627331Smckusick } 11727331Smckusick } 11827331Smckusick 11927331Smckusick /* 12027331Smckusick * Print out the current board position from the linked list 12127331Smckusick */ 12227331Smckusick prboard() { 12327331Smckusick 12427331Smckusick reg LIST *hp; 12527331Smckusick 12627331Smckusick erase(); /* clear out last position */ 12727331Smckusick box(stdscr, '|', '_'); /* box in the screen */ 12827331Smckusick 12927331Smckusick /* 13027331Smckusick * go through the list adding each piece to the newly 13127331Smckusick * blank board 13227331Smckusick */ 13327331Smckusick for (hp = Head; hp; hp = hp->next) 13427331Smckusick mvaddch(hp->y, hp->x, 'X'); 13527331Smckusick 13627331Smckusick refresh(); 13727331Smckusick } 138