From 081c95a7f45981fada4c659de8c28d399efda43b Mon Sep 17 00:00:00 2001 From: Christopher Simons Date: Tue, 23 Oct 2018 23:03:25 -0400 Subject: [PATCH] import games/worm from NetBSD closes #262 Change-Id: I63674a1e5457bbb3d30708e12f25c30487d70324 --- distrib/sets/lists/minix-games/mi | 1 + distrib/sets/lists/minix-man/mi | 1 + games/Makefile | 2 +- games/worm/Makefile | 10 + games/worm/worm.6 | 62 +++++ games/worm/worm.c | 369 ++++++++++++++++++++++++++++++ 6 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 games/worm/Makefile create mode 100644 games/worm/worm.6 create mode 100644 games/worm/worm.c diff --git a/distrib/sets/lists/minix-games/mi b/distrib/sets/lists/minix-games/mi index cbcdec315..93564c206 100644 --- a/distrib/sets/lists/minix-games/mi +++ b/distrib/sets/lists/minix-games/mi @@ -37,6 +37,7 @@ ./usr/games/tetris minix-games ./usr/games/unstr minix-games ./usr/games/wargames minix-games +./usr/games/worm minix-games ./usr/games/worms minix-games ./usr/games/wtf minix-games ./usr/share minix-games diff --git a/distrib/sets/lists/minix-man/mi b/distrib/sets/lists/minix-man/mi index 0edc1fd32..58ac5bd6e 100644 --- a/distrib/sets/lists/minix-man/mi +++ b/distrib/sets/lists/minix-man/mi @@ -3430,6 +3430,7 @@ ./usr/man/man6/snake.6 minix-man ./usr/man/man6/tetris.6 minix-man ./usr/man/man6/wargames.6 minix-man +./usr/man/man6/worm.6 minix-man ./usr/man/man6/worms.6 minix-man ./usr/man/man6/wtf.6 minix-man ./usr/man/man7 minix-man diff --git a/games/Makefile b/games/Makefile index 8cf0d06a5..64d8422dc 100644 --- a/games/Makefile +++ b/games/Makefile @@ -15,7 +15,7 @@ SUBDIR= adventure arithmetic \ monop morse number \ pig ppt primes \ rain random rogue snake tetris \ - wargames worms wtf + wargames worm worms wtf .if !defined(__MINIX) .if ${MKCXX} != "no" diff --git a/games/worm/Makefile b/games/worm/Makefile new file mode 100644 index 000000000..36112e690 --- /dev/null +++ b/games/worm/Makefile @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.9 2010/02/06 23:45:26 he Exp $ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= worm +MAN= worm.6 +DPADD= ${LIBCURSES} ${LIBTERMINFO} +LDADD= -lcurses -lterminfo +HIDEGAME=hidegame + +.include diff --git a/games/worm/worm.6 b/games/worm/worm.6 new file mode 100644 index 000000000..5bd501c92 --- /dev/null +++ b/games/worm/worm.6 @@ -0,0 +1,62 @@ +.\" $NetBSD: worm.6,v 1.11 2004/01/01 16:06:57 jsm Exp $ +.\" +.\" Copyright (c) 1989, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)worm.6 8.1 (Berkeley) 5/31/93 +.\" +.Dd May 31, 1993 +.Dt WORM 6 +.Os +.Sh NAME +.Nm worm +.Nd Play the growing worm game +.Sh SYNOPSIS +.Nm +.Op Ar size +.Sh DESCRIPTION +In +.Nm , +you are a little worm, your body is the "o"'s on the screen +and your head is the "@". +You move with the hjkl keys and the arrow keys (as in the game snake). +If you don't press any keys, you continue in the direction you last moved. +The upper case HJKL keys move you as if you had pressed +several (9 for HL and 5 for JK) of the corresponding lower case key +(unless you run into a digit, then it stops). +.Pp +On the screen you will see a digit, if your worm eats the digit is will +grow longer, the actual amount longer depends on which digit it was +that you ate. +The object of the game is to see how long you can make the worm grow. +.Pp +The game ends when the worm runs into either the sides of the screen, +or itself. +The current score (how much the worm has grown) is kept in +the upper right corner of the screen. +.Pp +The optional argument, if present, is the initial length of the worm. diff --git a/games/worm/worm.c b/games/worm/worm.c new file mode 100644 index 000000000..225ed0a1f --- /dev/null +++ b/games/worm/worm.c @@ -0,0 +1,369 @@ +/* $NetBSD: worm.c,v 1.31 2015/08/17 17:17:01 dholland Exp $ */ + +/* + * Copyright (c) 1980, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#ifndef lint +__COPYRIGHT("@(#) Copyright (c) 1980, 1993\ + The Regents of the University of California. All rights reserved."); +#endif /* not lint */ + +#ifndef lint +#if 0 +static char sccsid[] = "@(#)worm.c 8.1 (Berkeley) 5/31/93"; +#else +__RCSID("$NetBSD: worm.c,v 1.31 2015/08/17 17:17:01 dholland Exp $"); +#endif +#endif /* not lint */ + +/* + * Worm. Written by Michael Toy + * UCSC + */ + +#include +#include +#include +#include +#include +#include +#include + +#define HEAD '@' +#define BODY 'o' +#define LENGTH 7 +#define RUNLEN 8 +#define CNTRL(p) (p-'A'+1) + +struct body { + int x; + int y; + struct body *prev; + struct body *next; +}; + +static WINDOW *tv; +static WINDOW *stw; +static struct body *head, *tail, goody; +static int growing = 0; +static int running = 0; +static int slow = 0; +static int score = 0; +static int start_len = LENGTH; +static int visible_len; +static int lastch; +static char outbuf[BUFSIZ]; + +int main(int, char **); +static void crash(void) __dead; +static void display(const struct body *, char); +static void leave(int) __dead; +static void life(void); +static void newpos(struct body *); +static void process(int); +static void prize(void); +static int rnd(int); +static void setup(void); +static void wake(int); + +static struct body * +newlink(void) +{ + struct body *b; + + b = malloc(sizeof(*b)); + if (b == NULL) { + err(EXIT_FAILURE, NULL); + } + return b; +} + +int +main(int argc, char **argv) +{ + + /* Revoke setgid privileges */ + setgid(getgid()); + + setbuf(stdout, outbuf); + srand(getpid()); + signal(SIGALRM, wake); + signal(SIGINT, leave); + signal(SIGQUIT, leave); + if (!initscr()) + errx(0, "couldn't initialize screen"); + cbreak(); + noecho(); +#ifdef KEY_LEFT + keypad(stdscr, TRUE); +#endif + slow = (baudrate() <= 1200); + clear(); + if (COLS < 18 || LINES < 5) { + /* + * Insufficient room for the line with " Worm" and the + * score if fewer than 18 columns; insufficient room for + * anything much if fewer than 5 lines. + */ + endwin(); + errx(1, "screen too small"); + } + if (argc == 2) + start_len = atoi(argv[1]); + if ((start_len <= 0) || (start_len > ((LINES-3) * (COLS-2)) / 3)) + start_len = LENGTH; + stw = newwin(1, COLS-1, 0, 0); + tv = newwin(LINES-1, COLS-1, 1, 0); + box(tv, '*', '*'); + scrollok(tv, FALSE); + scrollok(stw, FALSE); + wmove(stw, 0, 0); + wprintw(stw, " Worm"); + refresh(); + wrefresh(stw); + wrefresh(tv); + life(); /* Create the worm */ + prize(); /* Put up a goal */ + while(1) + { + if (running) + { + running--; + process(lastch); + } + else + { + fflush(stdout); + process(getch()); + } + } +} + +static void +life(void) +{ + struct body *bp, *np; + int i, j = 1; + + np = NULL; + head = newlink(); + head->x = start_len % (COLS-5) + 2; + head->y = LINES / 2; + head->next = NULL; + display(head, HEAD); + for (i = 0, bp = head; i < start_len; i++, bp = np) { + np = newlink(); + np->next = bp; + bp->prev = np; + if (((bp->x <= 2) && (j == 1)) || ((bp->x >= COLS-4) && (j == -1))) { + j *= -1; + np->x = bp->x; + np->y = bp->y + 1; + } else { + np->x = bp->x - j; + np->y = bp->y; + } + display(np, BODY); + } + tail = np; + tail->prev = NULL; + visible_len = start_len + 1; +} + +static void +display(const struct body *pos, char chr) +{ + wmove(tv, pos->y, pos->x); + waddch(tv, chr); +} + +static void +leave(int dummy) +{ + endwin(); + + if (dummy == 0){ /* called via crash() */ + printf("\nWell, you ran into something and the game is over.\n"); + printf("Your final score was %d\n\n", score); + } + exit(0); +} + +static void +wake(int dummy) +{ + signal(SIGALRM, wake); + fflush(stdout); + process(lastch); +} + +static int +rnd(int range) +{ + return abs((rand()>>5)+(rand()>>5)) % range; +} + +static void +newpos(struct body *bp) +{ + if (visible_len == (LINES-3) * (COLS-3) - 1) { + endwin(); + + printf("\nYou won!\n"); + printf("Your final score was %d\n\n", score); + exit(0); + } + do { + bp->y = rnd(LINES-3)+ 1; + bp->x = rnd(COLS-3) + 1; + wmove(tv, bp->y, bp->x); + } while(winch(tv) != ' '); +} + +static void +prize(void) +{ + int value; + + value = rnd(9) + 1; + newpos(&goody); + waddch(tv, value+'0'); + wrefresh(tv); +} + +static void +process(int ch) +{ + int x,y; + struct body *nh; + + alarm(0); + x = head->x; + y = head->y; + switch(ch) + { +#ifdef KEY_LEFT + case KEY_LEFT: +#endif + case 'h': + x--; break; + +#ifdef KEY_DOWN + case KEY_DOWN: +#endif + case 'j': + y++; break; + +#ifdef KEY_UP + case KEY_UP: +#endif + case 'k': + y--; break; + +#ifdef KEY_RIGHT + case KEY_RIGHT: +#endif + case 'l': + x++; break; + + case 'H': x--; running = RUNLEN; ch = tolower(ch); break; + case 'J': y++; running = RUNLEN/2; ch = tolower(ch); break; + case 'K': y--; running = RUNLEN/2; ch = tolower(ch); break; + case 'L': x++; running = RUNLEN; ch = tolower(ch); break; + case '\f': setup(); return; + + case ERR: + case CNTRL('C'): + case CNTRL('D'): + crash(); + return; + + default: if (! running) alarm(1); + return; + } + lastch = ch; + if (growing == 0) + { + display(tail, ' '); + tail->next->prev = NULL; + nh = tail->next; + free(tail); + tail = nh; + visible_len--; + } + else growing--; + display(head, BODY); + wmove(tv, y, x); + if (isdigit(ch = winch(tv))) + { + growing += ch-'0'; + prize(); + score += growing; + running = 0; + wmove(stw, 0, COLS - 12); + wprintw(stw, "Score: %3d", score); + wrefresh(stw); + } + else if(ch != ' ') crash(); + nh = newlink(); + nh->next = NULL; + nh->prev = head; + head->next = nh; + nh->y = y; + nh->x = x; + display(nh, HEAD); + head = nh; + visible_len++; + if (!(slow && running)) + { + wmove(tv, head->y, head->x); + wrefresh(tv); + } + if (!running) + alarm(1); +} + +static void +crash(void) +{ + leave(0); +} + +static void +setup(void) +{ + clear(); + refresh(); + touchwin(stw); + wrefresh(stw); + touchwin(tv); + wrefresh(tv); + alarm(1); +} -- 2.44.0