Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: crib.c
===================================================================
--- crib.c	(nonexistent)
+++ crib.c	(revision 5)
@@ -0,0 +1,658 @@
+/*	$NetBSD: crib.c,v 1.19 2004/01/27 20:30:29 jsm 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 <sys/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)crib.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: crib.c,v 1.19 2004/01/27 20:30:29 jsm Exp $");
+#endif
+#endif /* not lint */
+
+#include <curses.h>
+#include <err.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "deck.h"
+#include "cribbage.h"
+#include "cribcur.h"
+#include "pathnames.h"
+
+int	main(int, char *[]);
+
+int
+main(argc, argv)
+	int argc;
+	char *argv[];
+{
+	BOOLEAN playing;
+	FILE *f;
+	int ch;
+	int fd;
+	int flags;
+
+	f = fopen(_PATH_LOG, "a");
+	if (f == NULL)
+		warn("fopen %s", _PATH_LOG);
+	if (f != NULL && fileno(f) < 3)
+		exit(1);
+
+	/* Revoke setgid privileges */
+	setregid(getgid(), getgid());
+
+	/* Set close-on-exec flag on log file */
+	if (f != NULL) {
+		fd = fileno(f);
+		flags = fcntl(fd, F_GETFD);
+		if (flags < 0)
+			err(1, "fcntl F_GETFD");
+		flags |= FD_CLOEXEC;
+		if (fcntl(fd, F_SETFD, flags) == -1)
+			err(1, "fcntl F_SETFD");
+	}
+
+	while ((ch = getopt(argc, argv, "eqr")) != -1)
+		switch (ch) {
+		case 'e':
+			explain = TRUE;
+			break;
+		case 'q':
+			quiet = TRUE;
+			break;
+		case 'r':
+			rflag = TRUE;
+			break;
+		case '?':
+		default:
+			(void) fprintf(stderr, "usage: cribbage [-eqr]\n");
+			exit(1);
+		}
+
+	initscr();
+	(void)signal(SIGINT, receive_intr);
+	cbreak();
+	noecho();
+
+	Playwin = subwin(stdscr, PLAY_Y, PLAY_X, 0, 0);
+	Tablewin = subwin(stdscr, TABLE_Y, TABLE_X, 0, PLAY_X);
+	Compwin = subwin(stdscr, COMP_Y, COMP_X, 0, TABLE_X + PLAY_X);
+	Msgwin = subwin(stdscr, MSG_Y, MSG_X, Y_MSG_START, SCORE_X + 1);
+	leaveok(Playwin, TRUE);
+	leaveok(Tablewin, TRUE);
+	leaveok(Compwin, TRUE);
+	clearok(stdscr, FALSE);
+
+	if (!quiet) {
+		msg("Do you need instructions for cribbage? ");
+		if (getuchar() == 'Y') {
+			endwin();
+			clear();
+			mvcur(0, COLS - 1, LINES - 1, 0);
+			fflush(stdout);
+			instructions();
+			cbreak();
+			noecho();
+			clear();
+			refresh();
+			msg("For cribbage rules, use \"man cribbage\"");
+		}
+	}
+	playing = TRUE;
+	do {
+		wclrtobot(Msgwin);
+		msg(quiet ? "L or S? " : "Long (to 121) or Short (to 61)? ");
+		if (glimit == SGAME)
+			glimit = (getuchar() == 'L' ? LGAME : SGAME);
+		else
+			glimit = (getuchar() == 'S' ? SGAME : LGAME);
+		game();
+		msg("Another game? ");
+		playing = (getuchar() == 'Y');
+	} while (playing);
+
+	if (f != NULL) {
+		(void)fprintf(f, "%s: won %5.5d, lost %5.5d\n",
+		    getlogin(), cgames, pgames);
+		(void) fclose(f);
+	}
+	bye();
+	exit(0);
+}
+
+/*
+ * makeboard:
+ *	Print out the initial board on the screen
+ */
+void
+makeboard()
+{
+	mvaddstr(SCORE_Y + 0, SCORE_X,
+	    "+---------------------------------------+");
+	mvaddstr(SCORE_Y + 1, SCORE_X,
+	    "|  Score:   0     YOU                   |");
+	mvaddstr(SCORE_Y + 2, SCORE_X,
+	    "| *.....:.....:.....:.....:.....:.....  |");
+	mvaddstr(SCORE_Y + 3, SCORE_X,
+	    "| *.....:.....:.....:.....:.....:.....  |");
+	mvaddstr(SCORE_Y + 4, SCORE_X,
+	    "|                                       |");
+	mvaddstr(SCORE_Y + 5, SCORE_X,
+	    "| *.....:.....:.....:.....:.....:.....  |");
+	mvaddstr(SCORE_Y + 6, SCORE_X,
+	    "| *.....:.....:.....:.....:.....:.....  |");
+	mvaddstr(SCORE_Y + 7, SCORE_X,
+	    "|  Score:   0      ME                   |");
+	mvaddstr(SCORE_Y + 8, SCORE_X,
+	    "+---------------------------------------+");
+	gamescore();
+}
+
+/*
+ * gamescore:
+ *	Print out the current game score
+ */
+void
+gamescore()
+{
+	if (pgames || cgames) {
+		mvprintw(SCORE_Y + 1, SCORE_X + 28, "Games: %3d", pgames);
+		mvprintw(SCORE_Y + 7, SCORE_X + 28, "Games: %3d", cgames);
+	}
+	Lastscore[0] = -1;
+	Lastscore[1] = -1;
+}
+
+/*
+ * game:
+ *	Play one game up to glimit points.  Actually, we only ASK the
+ *	player what card to turn.  We do a random one, anyway.
+ */
+void
+game()
+{
+	int i, j;
+	BOOLEAN flag;
+	BOOLEAN compcrib;
+
+	compcrib = FALSE;
+	makedeck(deck);
+	shuffle(deck);
+	if (gamecount == 0) {
+		flag = TRUE;
+		do {
+			if (!rflag) {			/* player cuts deck */
+				msg(quiet ? "Cut for crib? " :
+			    "Cut to see whose crib it is -- low card wins? ");
+				cr_getline();
+			}
+			i = (rand() >> 4) % CARDS;	/* random cut */
+			do {	/* comp cuts deck */
+				j = (rand() >> 4) % CARDS;
+			} while (j == i);
+			addmsg(quiet ? "You cut " : "You cut the ");
+			msgcard(deck[i], FALSE);
+			endmsg();
+			addmsg(quiet ? "I cut " : "I cut the ");
+			msgcard(deck[j], FALSE);
+			endmsg();
+			flag = (deck[i].rank == deck[j].rank);
+			if (flag) {
+				msg(quiet ? "We tied..." :
+				    "We tied and have to try again...");
+				shuffle(deck);
+				continue;
+			} else
+				compcrib = (deck[i].rank > deck[j].rank);
+		} while (flag);
+		do_wait();
+		clear();
+		makeboard();
+		refresh();
+	} else {
+		makeboard();
+		refresh();
+		werase(Tablewin);
+		wrefresh(Tablewin);
+		werase(Compwin);
+		wrefresh(Compwin);
+		msg("Loser (%s) gets first crib", (iwon ? "you" : "me"));
+		compcrib = !iwon;
+	}
+
+	pscore = cscore = 0;
+	flag = TRUE;
+	do {
+		shuffle(deck);
+		flag = !playhand(compcrib);
+		compcrib = !compcrib;
+	} while (flag);
+	++gamecount;
+	if (cscore < pscore) {
+		if (glimit - cscore > 60) {
+			msg("YOU DOUBLE SKUNKED ME!");
+			pgames += 4;
+		} else
+			if (glimit - cscore > 30) {
+				msg("YOU SKUNKED ME!");
+				pgames += 2;
+			} else {
+				msg("YOU WON!");
+				++pgames;
+			}
+		iwon = FALSE;
+	} else {
+		if (glimit - pscore > 60) {
+			msg("I DOUBLE SKUNKED YOU!");
+			cgames += 4;
+		} else
+			if (glimit - pscore > 30) {
+				msg("I SKUNKED YOU!");
+				cgames += 2;
+			} else {
+				msg("I WON!");
+				++cgames;
+			}
+		iwon = TRUE;
+	}
+	gamescore();
+}
+
+/*
+ * playhand:
+ *	Do up one hand of the game
+ */
+int
+playhand(mycrib)
+	BOOLEAN mycrib;
+{
+	int deckpos;
+
+	werase(Compwin);
+	wrefresh(Compwin);
+	werase(Tablewin);
+	wrefresh(Tablewin);
+
+	knownum = 0;
+	deckpos = deal(mycrib);
+	sorthand(chand, FULLHAND);
+	sorthand(phand, FULLHAND);
+	makeknown(chand, FULLHAND);
+	prhand(phand, FULLHAND, Playwin, FALSE);
+	discard(mycrib);
+	if (cut(mycrib, deckpos))
+		return TRUE;
+	if (peg(mycrib))
+		return TRUE;
+	werase(Tablewin);
+	wrefresh(Tablewin);
+	if (score(mycrib))
+		return TRUE;
+	return FALSE;
+}
+
+/*
+ * deal cards to both players from deck
+ */
+int
+deal(mycrib)
+	BOOLEAN mycrib;
+{
+	int i, j;
+
+	for (i = j = 0; i < FULLHAND; i++) {
+		if (mycrib) {
+			phand[i] = deck[j++];
+			chand[i] = deck[j++];
+		} else {
+			chand[i] = deck[j++];
+			phand[i] = deck[j++];
+		}
+	}
+	return (j);
+}
+
+/*
+ * discard:
+ *	Handle players discarding into the crib...
+ * Note: we call cdiscard() after prining first message so player doesn't wait
+ */
+void
+discard(mycrib)
+	BOOLEAN mycrib;
+{
+	const char *prompt;
+	CARD crd;
+
+	prcrib(mycrib, TRUE);
+	prompt = (quiet ? "Discard --> " : "Discard a card --> ");
+	cdiscard(mycrib);	/* puts best discard at end */
+	crd = phand[infrom(phand, FULLHAND, prompt)];
+	cremove(crd, phand, FULLHAND);
+	prhand(phand, FULLHAND, Playwin, FALSE);
+	crib[0] = crd;
+
+	/* Next four lines same as last four except for cdiscard(). */
+	crd = phand[infrom(phand, FULLHAND - 1, prompt)];
+	cremove(crd, phand, FULLHAND - 1);
+	prhand(phand, FULLHAND, Playwin, FALSE);
+	crib[1] = crd;
+	crib[2] = chand[4];
+	crib[3] = chand[5];
+	chand[4].rank = chand[4].suit = chand[5].rank = chand[5].suit = EMPTY;
+}
+
+/*
+ * cut:
+ *	Cut the deck and set turnover.  Actually, we only ASK the
+ *	player what card to turn.  We do a random one, anyway.
+ */
+int
+cut(mycrib, pos)
+	BOOLEAN mycrib;
+	int  pos;
+{
+	int i;
+	BOOLEAN win;
+
+	win = FALSE;
+	if (mycrib) {
+		if (!rflag) {	/* random cut */
+			msg(quiet ? "Cut the deck? " :
+		    "How many cards down do you wish to cut the deck? ");
+			cr_getline();
+		}
+		i = (rand() >> 4) % (CARDS - pos);
+		turnover = deck[i + pos];
+		addmsg(quiet ? "You cut " : "You cut the ");
+		msgcard(turnover, FALSE);
+		endmsg();
+		if (turnover.rank == JACK) {
+			msg("I get two for his heels");
+			win = chkscr(&cscore, 2);
+		}
+	} else {
+		i = (rand() >> 4) % (CARDS - pos) + pos;
+		turnover = deck[i];
+		addmsg(quiet ? "I cut " : "I cut the ");
+		msgcard(turnover, FALSE);
+		endmsg();
+		if (turnover.rank == JACK) {
+			msg("You get two for his heels");
+			win = chkscr(&pscore, 2);
+		}
+	}
+	makeknown(&turnover, 1);
+	prcrib(mycrib, FALSE);
+	return (win);
+}
+
+/*
+ * prcrib:
+ *	Print out the turnover card with crib indicator
+ */
+void
+prcrib(mycrib, blank)
+	BOOLEAN mycrib, blank;
+{
+	int y, cardx;
+
+	if (mycrib)
+		cardx = CRIB_X;
+	else
+		cardx = 0;
+
+	mvaddstr(CRIB_Y, cardx + 1, "CRIB");
+	prcard(stdscr, CRIB_Y + 1, cardx, turnover, blank);
+
+	if (mycrib)
+		cardx = 0;
+	else
+		cardx = CRIB_X;
+
+	for (y = CRIB_Y; y <= CRIB_Y + 5; y++)
+		mvaddstr(y, cardx, "       ");
+	refresh();
+}
+
+/*
+ * peg:
+ *	Handle all the pegging...
+ */
+static CARD Table[14];
+static int Tcnt;
+
+int
+peg(mycrib)
+	BOOLEAN mycrib;
+{
+	static CARD ch[CINHAND], ph[CINHAND];
+	int i, j, k;
+	int l;
+	int cnum, pnum, sum;
+	BOOLEAN myturn, mego, ugo, last, played;
+	CARD crd;
+
+	played = FALSE;
+	cnum = pnum = CINHAND;
+	for (i = 0; i < CINHAND; i++) {	/* make copies of hands */
+		ch[i] = chand[i];
+		ph[i] = phand[i];
+	}
+	Tcnt = 0;		/* index to table of cards played */
+	sum = 0;		/* sum of cards played */
+	mego = ugo = FALSE;
+	myturn = !mycrib;
+	for (;;) {
+		last = TRUE;	/* enable last flag */
+		prhand(ph, pnum, Playwin, FALSE);
+		prhand(ch, cnum, Compwin, TRUE);
+		prtable(sum);
+		if (myturn) {	/* my tyrn to play */
+			if (!anymove(ch, cnum, sum)) {	/* if no card to play */
+				if (!mego && cnum) {	/* go for comp? */
+					msg("GO");
+					mego = TRUE;
+				}
+							/* can player move? */
+				if (anymove(ph, pnum, sum))
+					myturn = !myturn;
+				else {			/* give him his point */
+					msg(quiet ? "You get one" :
+					    "You get one point");
+					do_wait();
+					if (chkscr(&pscore, 1))
+						return TRUE;
+					sum = 0;
+					mego = ugo = FALSE;
+					Tcnt = 0;
+				}
+			} else {
+				played = TRUE;
+				j = -1;
+				k = 0;
+							/* maximize score */
+				for (i = 0; i < cnum; i++) {
+					l = pegscore(ch[i], Table, Tcnt, sum);
+					if (l > k) {
+						k = l;
+						j = i;
+					}
+				}
+				if (j < 0)		/* if nothing scores */
+					j = cchose(ch, cnum, sum);
+				crd = ch[j];
+				cremove(crd, ch, cnum--);
+				sum += VAL(crd.rank);
+				Table[Tcnt++] = crd;
+				if (k > 0) {
+					addmsg(quiet ? "I get %d playing " :
+					    "I get %d points playing ", k);
+					msgcard(crd, FALSE);
+					endmsg();
+					if (chkscr(&cscore, k))
+						return TRUE;
+				}
+				myturn = !myturn;
+			}
+		} else {
+			if (!anymove(ph, pnum, sum)) {	/* can player move? */
+				if (!ugo && pnum) {	/* go for player */
+					msg("You have a GO");
+					ugo = TRUE;
+				}
+							/* can computer play? */
+				if (anymove(ch, cnum, sum))
+					myturn = !myturn;
+				else {
+					msg(quiet ? "I get one" :
+					    "I get one point");
+					do_wait();
+					if (chkscr(&cscore, 1))
+						return TRUE;
+					sum = 0;
+					mego = ugo = FALSE;
+					Tcnt = 0;
+				}
+			} else {			/* player plays */
+				played = FALSE;
+				if (pnum == 1) {
+					crd = ph[0];
+					msg("You play your last card");
+				} else
+					for (;;) {
+						prhand(ph,
+						    pnum, Playwin, FALSE);
+						crd = ph[infrom(ph,
+						    pnum, "Your play: ")];
+						if (sum + VAL(crd.rank) <= 31)
+							break;
+						else
+					msg("Total > 31 -- try again");
+					}
+				makeknown(&crd, 1);
+				cremove(crd, ph, pnum--);
+				i = pegscore(crd, Table, Tcnt, sum);
+				sum += VAL(crd.rank);
+				Table[Tcnt++] = crd;
+				if (i > 0) {
+					msg(quiet ? "You got %d" :
+					    "You got %d points", i);
+					if (pnum == 0)
+						do_wait();
+					if (chkscr(&pscore, i))
+						return TRUE;
+				}
+				myturn = !myturn;
+			}
+		}
+		if (sum >= 31) {
+			if (!myturn)
+				do_wait();
+			sum = 0;
+			mego = ugo = FALSE;
+			Tcnt = 0;
+			last = FALSE;			/* disable last flag */
+		}
+		if (!pnum && !cnum)
+			break;				/* both done */
+	}
+	prhand(ph, pnum, Playwin, FALSE);
+	prhand(ch, cnum, Compwin, TRUE);
+	prtable(sum);
+	if (last) {
+		if (played) {
+			msg(quiet ? "I get one for last" :
+			    "I get one point for last");
+			do_wait();
+			if (chkscr(&cscore, 1))
+				return TRUE;
+		} else {
+			msg(quiet ? "You get one for last" :
+			    "You get one point for last");
+			do_wait();
+			if (chkscr(&pscore, 1))
+				return TRUE;
+		}
+	}
+	return (FALSE);
+}
+
+/*
+ * prtable:
+ *	Print out the table with the current score
+ */
+void
+prtable(score)
+	int score;
+{
+	prhand(Table, Tcnt, Tablewin, FALSE);
+	mvwprintw(Tablewin, (Tcnt + 2) * 2, Tcnt + 1, "%2d", score);
+	wrefresh(Tablewin);
+}
+
+/*
+ * score:
+ *	Handle the scoring of the hands
+ */
+int
+score(mycrib)
+	BOOLEAN mycrib;
+{
+	sorthand(crib, CINHAND);
+	if (mycrib) {
+		if (plyrhand(phand, "hand"))
+			return (TRUE);
+		if (comphand(chand, "hand"))
+			return (TRUE);
+		do_wait();
+		if (comphand(crib, "crib"))
+			return (TRUE);
+		do_wait();
+	} else {
+		if (comphand(chand, "hand"))
+			return (TRUE);
+		if (plyrhand(phand, "hand"))
+			return (TRUE);
+		if (plyrhand(crib, "crib"))
+			return (TRUE);
+	}
+	return (FALSE);
+}
Index: cribbage.h
===================================================================
--- cribbage.h	(nonexistent)
+++ cribbage.h	(revision 5)
@@ -0,0 +1,112 @@
+/*	$NetBSD: cribbage.h,v 1.12 2004/02/08 22:23:50 jsm 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.
+ *
+ *	@(#)cribbage.h	8.1 (Berkeley) 5/31/93
+ */
+
+extern  CARD		deck[ CARDS ];		/* a deck */
+extern  CARD		phand[ FULLHAND ];	/* player's hand */
+extern  CARD		chand[ FULLHAND ];	/* computer's hand */
+extern  CARD		crib[ CINHAND ];	/* the crib */
+extern  CARD		turnover;		/* the starter */
+
+extern  CARD		known[ CARDS ];		/* cards we have seen */
+extern  int		knownum;		/* # of cards we know */
+
+extern  int		pscore;			/* player's score */
+extern  int		cscore;			/* comp's score */
+extern  int		glimit;			/* points to win game */
+
+extern  int		pgames;			/* player's games won */
+extern  int		cgames;			/* comp's games won */
+extern  int		gamecount;		/* # games played */
+extern	int		Lastscore[2];		/* previous score for each */
+
+extern  BOOLEAN		iwon;			/* if comp won last */
+extern  BOOLEAN		explain;		/* player mistakes explained */
+extern  BOOLEAN		rflag;			/* if all cuts random */
+extern  BOOLEAN		quiet;			/* if suppress random mess */
+extern	BOOLEAN		playing;		/* currently playing game */
+
+extern  char		cr_explan[];		/* string for explanation */
+
+void	 addmsg(const char *, ...)
+    __attribute__((__format__(__printf__, 1, 2)));
+int	 adjust(const CARD [], CARD);
+int	 anymove(const CARD [], int, int);
+int	 anysumto(const CARD [], int, int, int);
+void	 bye(void);
+int	 cchose(const CARD [], int, int);
+void	 cdiscard(BOOLEAN);
+int	 chkscr(int *, int);
+int	 comphand(const CARD [], const char *);
+void	 cremove(CARD, CARD [], int);
+int	 cut(BOOLEAN, int);
+int	 deal(int);
+void	 discard(BOOLEAN);
+void	 do_wait(void);
+void	 endmsg(void);
+int	 eq(CARD, CARD);
+int	 fifteens(const CARD [], int);
+void	 game(void);
+void	 gamescore(void);
+char	*cr_getline(void);
+int	 getuchar(void);
+int	 incard(CARD *);
+int	 infrom(const CARD [], int, const char *);
+void	 instructions(void);
+int	 is_one(CARD, const CARD [], int);
+void	 makeboard(void);
+void	 makedeck(CARD []);
+void	 makeknown(const CARD [], int);
+void	 msg(const char *, ...)
+    __attribute__((__format__(__printf__, 1, 2)));
+int	 msgcard(CARD, BOOLEAN);
+int	 msgcrd(CARD, BOOLEAN, const char *, BOOLEAN);
+int	 number(int, int, const char *);
+int	 numofval(const CARD [], int, int);
+int	 pairuns(const CARD [], int);
+int	 peg(BOOLEAN);
+int	 pegscore(CARD, const CARD [], int, int);
+int	 playhand(BOOLEAN);
+int	 plyrhand(const CARD [], const char *);
+void	 prcard(WINDOW *, int, int, CARD, BOOLEAN);
+void	 prcrib(BOOLEAN, BOOLEAN);
+void	 prhand(const CARD [], int, WINDOW *, BOOLEAN);
+void	 printcard(WINDOW *, int, CARD, BOOLEAN);
+void	 prpeg(int, int, BOOLEAN);
+void	 prtable(int);
+int	 readchar(void);
+void	 receive_intr(int) __attribute__((__noreturn__));
+int	 score(BOOLEAN);
+int	 scorehand(const CARD [], CARD, int, BOOLEAN, BOOLEAN);
+void	 shuffle(CARD []);
+void	 sorthand(CARD [], int);
+void	 wait_for(int);
Index: extern.c
===================================================================
--- extern.c	(nonexistent)
+++ extern.c	(revision 5)
@@ -0,0 +1,71 @@
+/*	$NetBSD: extern.c,v 1.7 2003/08/07 09:37:10 agc 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 <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)extern.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: extern.c,v 1.7 2003/08/07 09:37:10 agc Exp $");
+#endif
+#endif /* not lint */
+
+#include <curses.h>
+
+#include "deck.h"
+#include "cribbage.h"
+
+BOOLEAN	explain		= FALSE;	/* player mistakes explained */
+BOOLEAN	iwon		= FALSE;	/* if comp won last game */
+BOOLEAN	quiet		= FALSE;	/* if suppress random mess */
+BOOLEAN	rflag		= FALSE;	/* if all cuts random */
+
+char	cr_explan[128];			/* explanation */
+
+int	cgames		= 0;		/* number games comp won */
+int	cscore		= 0;		/* comp score in this game */
+int	gamecount	= 0;		/* number games played */
+int	glimit		= LGAME;	/* game playe to glimit */
+int	knownum		= 0;		/* number of cards we know */
+int	pgames		= 0;		/* number games player won */
+int	pscore		= 0;		/* player score in this game */
+
+CARD	chand[FULLHAND];		/* computer's hand */
+CARD	crib[CINHAND];			/* the crib */
+CARD	deck[CARDS];			/* a deck */
+CARD	known[CARDS];			/* cards we have seen */
+CARD	phand[FULLHAND];		/* player's hand */
+CARD	turnover;			/* the starter */
+
+WINDOW	*Compwin;			/* computer's hand window */
+WINDOW	*Msgwin;			/* messages for the player */
+WINDOW	*Playwin;			/* player's hand window */
+WINDOW	*Tablewin;			/* table window */
Index: io.c
===================================================================
--- io.c	(nonexistent)
+++ io.c	(revision 5)
@@ -0,0 +1,604 @@
+/*	$NetBSD: io.c,v 1.18 2004/11/05 21:30:31 dsl 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 <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)io.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: io.c,v 1.18 2004/11/05 21:30:31 dsl Exp $");
+#endif
+#endif /* not lint */
+
+#include <ctype.h>
+#include <curses.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include "deck.h"
+#include "cribbage.h"
+#include "cribcur.h"
+
+#define	LINESIZE		128
+
+#ifdef CTRL
+#undef CTRL
+#endif
+#define	CTRL(X)			(X - 'A' + 1)
+
+char    linebuf[LINESIZE];
+
+const char   *const rankname[RANKS] = {
+	"ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN",
+	"EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING"
+};
+
+const char   *const rankchar[RANKS] = {
+	"A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K"
+};
+
+const char *const suitname[SUITS] = {"SPADES", "HEARTS", "DIAMONDS", "CLUBS"};
+
+const char   *const suitchar[SUITS] = {"S", "H", "D", "C"};
+
+/*
+ * msgcard:
+ *	Call msgcrd in one of two forms
+ */
+int
+msgcard(c, brief)
+	CARD c;
+	BOOLEAN brief;
+{
+	if (brief)
+		return (msgcrd(c, TRUE, NULL, TRUE));
+	else
+		return (msgcrd(c, FALSE, " of ", FALSE));
+}
+
+/*
+ * msgcrd:
+ *	Print the value of a card in ascii
+ */
+int
+msgcrd(c, brfrank, mid, brfsuit)
+	CARD c;
+	BOOLEAN brfrank, brfsuit;
+	const char *mid;
+{
+	if (c.rank == EMPTY || c.suit == EMPTY)
+		return (FALSE);
+	if (brfrank)
+		addmsg("%1.1s", rankchar[c.rank]);
+	else
+		addmsg(rankname[c.rank]);
+	if (mid != NULL)
+		addmsg(mid);
+	if (brfsuit)
+		addmsg("%1.1s", suitchar[c.suit]);
+	else
+		addmsg(suitname[c.suit]);
+	return (TRUE);
+}
+
+/*
+ * printcard:
+ *	Print out a card.
+ */
+void
+printcard(win, cardno, c, blank)
+	WINDOW *win;
+	int     cardno;
+	CARD    c;
+	BOOLEAN blank;
+{
+	prcard(win, cardno * 2, cardno, c, blank);
+}
+
+/*
+ * prcard:
+ *	Print out a card on the window at the specified location
+ */
+void
+prcard(win, y, x, c, blank)
+	WINDOW *win;
+	int y, x;
+	CARD c;
+	BOOLEAN blank;
+{
+	if (c.rank == EMPTY)
+		return;
+
+	mvwaddstr(win, y + 0, x, "+-----+");
+	mvwaddstr(win, y + 1, x, "|     |");
+	mvwaddstr(win, y + 2, x, "|     |");
+	mvwaddstr(win, y + 3, x, "|     |");
+	mvwaddstr(win, y + 4, x, "+-----+");
+	if (!blank) {
+		mvwaddch(win, y + 1, x + 1, rankchar[c.rank][0]);
+		waddch(win, suitchar[c.suit][0]);
+		mvwaddch(win, y + 3, x + 4, rankchar[c.rank][0]);
+		waddch(win, suitchar[c.suit][0]);
+	}
+}
+
+/*
+ * prhand:
+ *	Print a hand of n cards
+ */
+void
+prhand(h, n, win, blank)
+	const CARD h[];
+	int n;
+	WINDOW *win;
+	BOOLEAN blank;
+{
+	int i;
+
+	werase(win);
+	for (i = 0; i < n; i++)
+		printcard(win, i, *h++, blank);
+	wrefresh(win);
+}
+
+/*
+ * infrom:
+ *	reads a card, supposedly in hand, accepting unambigous brief
+ *	input, returns the index of the card found...
+ */
+int
+infrom(hand, n, prompt)
+	const CARD hand[];
+	int n;
+	const char *prompt;
+{
+	int i, j;
+	CARD crd;
+
+	if (n < 1) {
+		printf("\nINFROM: %d = n < 1!!\n", n);
+		exit(74);
+	}
+	for (;;) {
+		msg(prompt);
+		if (incard(&crd)) {	/* if card is full card */
+			if (!is_one(crd, hand, n))
+				msg("That's not in your hand");
+			else {
+				for (i = 0; i < n; i++)
+					if (hand[i].rank == crd.rank &&
+					    hand[i].suit == crd.suit)
+						break;
+				if (i >= n) {
+			printf("\nINFROM: is_one or something messed up\n");
+					exit(77);
+				}
+				return (i);
+			}
+		} else			/* if not full card... */
+			if (crd.rank != EMPTY) {
+				for (i = 0; i < n; i++)
+					if (hand[i].rank == crd.rank)
+						break;
+				if (i >= n)
+					msg("No such rank in your hand");
+				else {
+					for (j = i + 1; j < n; j++)
+						if (hand[j].rank == crd.rank)
+							break;
+					if (j < n)
+						msg("Ambiguous rank");
+					else
+						return (i);
+				}
+			} else
+				msg("Sorry, I missed that");
+	}
+	/* NOTREACHED */
+}
+
+/*
+ * incard:
+ *	Inputs a card in any format.  It reads a line ending with a CR
+ *	and then parses it.
+ */
+int
+incard(crd)
+	CARD *crd;
+{
+	int i;
+	int rnk, sut;
+	char *line, *p, *p1;
+	BOOLEAN retval;
+
+	retval = FALSE;
+	rnk = sut = EMPTY;
+	if (!(line = cr_getline()))
+		goto gotit;
+	p = p1 = line;
+	while (*p1 != ' ' && *p1 != '\0')
+		++p1;
+	*p1++ = '\0';
+	if (*p == '\0')
+		goto gotit;
+
+	/* IMPORTANT: no real card has 2 char first name */
+	if (strlen(p) == 2) {	/* check for short form */
+		rnk = EMPTY;
+		for (i = 0; i < RANKS; i++) {
+			if (*p == *rankchar[i]) {
+				rnk = i;
+				break;
+			}
+		}
+		if (rnk == EMPTY)
+			goto gotit;	/* it's nothing... */
+		++p;		/* advance to next char */
+		sut = EMPTY;
+		for (i = 0; i < SUITS; i++) {
+			if (*p == *suitchar[i]) {
+				sut = i;
+				break;
+			}
+		}
+		if (sut != EMPTY)
+			retval = TRUE;
+		goto gotit;
+	}
+	rnk = EMPTY;
+	for (i = 0; i < RANKS; i++) {
+		if (!strcmp(p, rankname[i]) || !strcmp(p, rankchar[i])) {
+			rnk = i;
+			break;
+		}
+	}
+	if (rnk == EMPTY)
+		goto gotit;
+	p = p1;
+	while (*p1 != ' ' && *p1 != '\0')
+		++p1;
+	*p1++ = '\0';
+	if (*p == '\0')
+		goto gotit;
+	if (!strcmp("OF", p)) {
+		p = p1;
+		while (*p1 != ' ' && *p1 != '\0')
+			++p1;
+		*p1++ = '\0';
+		if (*p == '\0')
+			goto gotit;
+	}
+	sut = EMPTY;
+	for (i = 0; i < SUITS; i++) {
+		if (!strcmp(p, suitname[i]) || !strcmp(p, suitchar[i])) {
+			sut = i;
+			break;
+		}
+	}
+	if (sut != EMPTY)
+		retval = TRUE;
+gotit:
+	(*crd).rank = rnk;
+	(*crd).suit = sut;
+	return (retval);
+}
+
+/*
+ * getuchar:
+ *	Reads and converts to upper case
+ */
+int
+getuchar()
+{
+	int c;
+
+	c = readchar();
+	if (islower(c))
+		c = toupper(c);
+	waddch(Msgwin, c);
+	return (c);
+}
+
+/*
+ * number:
+ *	Reads in a decimal number and makes sure it is between "lo" and
+ *	"hi" inclusive.
+ */
+int
+number(lo, hi, prompt)
+	int lo, hi;
+	const char *prompt;
+{
+	char *p;
+	int sum;
+
+	for (sum = 0;;) {
+		msg(prompt);
+		if (!(p = cr_getline()) || *p == '\0') {
+			msg(quiet ? "Not a number" :
+			    "That doesn't look like a number");
+			continue;
+		}
+		sum = 0;
+
+		if (!isdigit((unsigned char)*p))
+			sum = lo - 1;
+		else
+			while (isdigit((unsigned char)*p)) {
+				sum = 10 * sum + (*p - '0');
+				++p;
+			}
+
+		if (*p != ' ' && *p != '\t' && *p != '\0')
+			sum = lo - 1;
+		if (sum >= lo && sum <= hi)
+			break;
+		if (sum == lo - 1)
+			msg("that doesn't look like a number, try again --> ");
+		else
+		msg("%d is not between %d and %d inclusive, try again --> ",
+			    sum, lo, hi);
+	}
+	return (sum);
+}
+
+/*
+ * msg:
+ *	Display a message at the top of the screen.
+ */
+char    Msgbuf[BUFSIZ] = {'\0'};
+int     Mpos = 0;
+static int Newpos = 0;
+
+void
+msg(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	(void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+	Newpos = strlen(Msgbuf);
+	va_end(ap);
+	endmsg();
+}
+
+/*
+ * addmsg:
+ *	Add things to the current message
+ */
+void
+addmsg(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	(void)vsprintf(&Msgbuf[Newpos], fmt, ap);
+	Newpos = strlen(Msgbuf);
+	va_end(ap);
+}
+
+/*
+ * endmsg:
+ *	Display a new msg.
+ */
+int     Lineno = 0;
+
+void
+endmsg()
+{
+	static int lastline = 0;
+	int len;
+	char *mp, *omp;
+
+	/* All messages should start with uppercase */
+	mvaddch(lastline + Y_MSG_START, SCORE_X, ' ');
+	if (islower((unsigned char)Msgbuf[0]) && Msgbuf[1] != ')')
+		Msgbuf[0] = toupper((unsigned char)Msgbuf[0]);
+	mp = Msgbuf;
+	len = strlen(mp);
+	if (len / MSG_X + Lineno >= MSG_Y) {
+		while (Lineno < MSG_Y) {
+			wmove(Msgwin, Lineno++, 0);
+			wclrtoeol(Msgwin);
+		}
+		Lineno = 0;
+	}
+	mvaddch(Lineno + Y_MSG_START, SCORE_X, '*');
+	lastline = Lineno;
+	do {
+		mvwaddstr(Msgwin, Lineno, 0, mp);
+		if ((len = strlen(mp)) > MSG_X) {
+			omp = mp;
+			for (mp = &mp[MSG_X - 1]; *mp != ' '; mp--)
+				continue;
+			while (*mp == ' ')
+				mp--;
+			mp++;
+			wmove(Msgwin, Lineno, mp - omp);
+			wclrtoeol(Msgwin);
+		}
+		if (++Lineno >= MSG_Y)
+			Lineno = 0;
+	} while (len > MSG_X);
+	wclrtoeol(Msgwin);
+	Mpos = len;
+	Newpos = 0;
+	wrefresh(Msgwin);
+	refresh();
+	wrefresh(Msgwin);
+}
+
+/*
+ * do_wait:
+ *	Wait for the user to type ' ' before doing anything else
+ */
+void
+do_wait()
+{
+	static const char prompt[] = {'-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0'};
+
+	if ((int)(Mpos + sizeof prompt) < MSG_X)
+		wmove(Msgwin, Lineno > 0 ? Lineno - 1 : MSG_Y - 1, Mpos);
+	else {
+		mvwaddch(Msgwin, Lineno, 0, ' ');
+		wclrtoeol(Msgwin);
+		if (++Lineno >= MSG_Y)
+			Lineno = 0;
+	}
+	waddstr(Msgwin, prompt);
+	wrefresh(Msgwin);
+	wait_for(' ');
+}
+
+/*
+ * wait_for
+ *	Sit around until the guy types the right key
+ */
+void
+wait_for(ch)
+	int ch;
+{
+	char c;
+
+	if (ch == '\n')
+		while ((c = readchar()) != '\n')
+			continue;
+	else
+		while (readchar() != ch)
+			continue;
+}
+
+/*
+ * readchar:
+ *	Reads and returns a character, checking for gross input errors
+ */
+int
+readchar()
+{
+	int cnt;
+	char c;
+
+over:
+	cnt = 0;
+	while (read(STDIN_FILENO, &c, sizeof(char)) <= 0)
+		if (cnt++ > 100) {	/* if we are getting infinite EOFs */
+			bye();		/* quit the game */
+			exit(1);
+		}
+	if (c == CTRL('L')) {
+		wrefresh(curscr);
+		goto over;
+	}
+	if (c == '\r')
+		return ('\n');
+	else
+		return (c);
+}
+
+/*
+ * getline:
+ *      Reads the next line up to '\n' or EOF.  Multiple spaces are
+ *	compressed to one space; a space is inserted before a ','
+ */
+char *
+cr_getline()
+{
+	char *sp;
+	int c, oy, ox;
+	WINDOW *oscr;
+
+	oscr = stdscr;
+	stdscr = Msgwin;
+	getyx(stdscr, oy, ox);
+	refresh();
+	/* loop reading in the string, and put it in a temporary buffer */
+	for (sp = linebuf; (c = readchar()) != '\n'; clrtoeol(), refresh()) {
+		if (c == -1)
+			continue;
+		else
+			if (c == erasechar()) {	/* process erase character */
+				if (sp > linebuf) {
+					int i;
+
+					sp--;
+					for (i = strlen(unctrl(*sp)); i; i--)
+						addch('\b');
+				}
+				continue;
+			} else
+				if (c == killchar()) {	/* process kill
+							 * character */
+					sp = linebuf;
+					move(oy, ox);
+					continue;
+				} else
+					if (sp == linebuf && c == ' ')
+						continue;
+		if (sp >= &linebuf[LINESIZE - 1] || !(isprint(c) || c == ' '))
+			putchar(CTRL('G'));
+		else {
+			if (islower(c))
+				c = toupper(c);
+			*sp++ = c;
+			addstr(unctrl(c));
+			Mpos++;
+		}
+	}
+	*sp = '\0';
+	stdscr = oscr;
+	return (linebuf);
+}
+
+void
+receive_intr(signo)
+	int signo __attribute__((__unused__));
+{
+	bye();
+	exit(1);
+}
+
+/*
+ * bye:
+ *	Leave the program, cleaning things up as we go.
+ */
+void
+bye()
+{
+	signal(SIGINT, SIG_IGN);
+	mvcur(0, COLS - 1, LINES - 1, 0);
+	fflush(stdout);
+	endwin();
+	putchar('\n');
+}
Index: score.c
===================================================================
--- score.c	(nonexistent)
+++ score.c	(revision 5)
@@ -0,0 +1,374 @@
+/*	$NetBSD: score.c,v 1.10 2003/08/07 09:37:10 agc 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 <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)score.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: score.c,v 1.10 2003/08/07 09:37:10 agc Exp $");
+#endif
+#endif /* not lint */
+
+#include <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "deck.h"
+#include "cribbage.h"
+
+/*
+ * the following arrays give the sum of the scores of the (50 2)*48 = 58800
+ * hands obtainable for the crib given the two cards whose ranks index the
+ * array.  the two arrays are for the case where the suits are equal and
+ * not equal respectively
+ */
+const long crbescr[169] = {
+    -10000, 271827, 278883, 332319, 347769, 261129, 250653, 253203, 248259,
+    243435, 256275, 237435, 231051, -10000, -10000, 412815, 295707, 349497,
+    267519, 262521, 259695, 254019, 250047, 262887, 244047, 237663, -10000,
+    -10000, -10000, 333987, 388629, 262017, 266787, 262971, 252729, 254475,
+    267315, 248475, 242091, -10000, -10000, -10000, -10000, 422097, 302787,
+    256437, 263751, 257883, 254271, 267111, 248271, 241887, -10000, -10000,
+    -10000, -10000, -10000, 427677, 387837, 349173, 347985, 423861, 436701,
+    417861, 411477, -10000, -10000, -10000, -10000, -10000, -10000, 336387,
+    298851, 338667, 236487, 249327, 230487, 224103, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, 408483, 266691, 229803, 246195, 227355,
+    220971, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+    300675, 263787, 241695, 226407, 220023, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, -10000, 295635, 273543, 219771, 216939,
+    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+    -10000, 306519, 252747, 211431, -10000, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, -10000, -10000, 304287, 262971, -10000,
+    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+    -10000, -10000, 244131, -10000, -10000, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, -10000, -10000, -10000
+};
+
+const long crbnescr[169] = {
+    325272, 260772, 267828, 321264, 336714, 250074, 239598, 242148, 237204,
+    232380, 246348, 226380, 219996, -10000, 342528, 401760, 284652, 338442,
+    256464, 251466, 248640, 242964, 238992, 252960, 232992, 226608, -10000,
+    -10000, 362280, 322932, 377574, 250962, 255732, 251916, 241674, 243420,
+    257388, 237420, 231036, -10000, -10000, -10000, 360768, 411042, 291732,
+    245382, 252696, 246828, 243216, 257184, 237216, 230832, -10000, -10000,
+    -10000, -10000, 528768, 416622, 376782, 338118, 336930, 412806, 426774,
+    406806, 400422, -10000, -10000, -10000, -10000, -10000, 369864, 325332,
+    287796, 327612, 225432, 239400, 219432, 213048, -10000, -10000, -10000,
+    -10000, -10000, -10000, 359160, 397428, 255636, 218748, 236268, 216300,
+    209916, -10000, -10000, -10000, -10000, -10000, -10000, -10000, 331320,
+    289620, 252732, 231768, 215352, 208968, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, 325152, 284580, 263616, 208716, 205884,
+    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+    321240, 296592, 241692, 200376, -10000, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, -10000, 348600, 294360, 253044, -10000,
+    -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000, -10000,
+    -10000, 308664, 233076, -10000, -10000, -10000, -10000, -10000, -10000,
+    -10000, -10000, -10000, -10000, -10000, -10000, 295896
+};
+
+static const int ichoose2[5] = { 0, 0, 2, 6, 12 };
+static int pairpoints, runpoints;		/* Globals from pairuns. */
+
+/*
+ * scorehand:
+ *	Score the given hand of n cards and the starter card.
+ *	n must be <= 4
+ */
+int
+scorehand(hand, starter, n, crb, do_explain)
+	const CARD hand[];
+	CARD starter;
+	int n;
+	BOOLEAN crb;		/* true if scoring crib */
+	BOOLEAN do_explain;	/* true if must explain this hand */
+{
+	int i, k;
+	int score;
+	BOOLEAN flag;
+	CARD h[(CINHAND + 1)];
+	char buf[32];
+
+	cr_explan[0] = '\0';	/* initialize explanation */
+	score = 0;
+	flag = TRUE;
+	k = hand[0].suit;
+	for (i = 0; i < n; i++) {	/* check for flush */
+		flag = (flag && (hand[i].suit == k));
+		if (hand[i].rank == JACK)	/* check for his nibs */
+			if (hand[i].suit == starter.suit) {
+				score++;
+				if (do_explain)
+					strcat(cr_explan, "His Nobs");
+			}
+		h[i] = hand[i];
+	}
+
+	if (flag && n >= CINHAND) {
+		if (do_explain && cr_explan[0] != '\0')
+			strcat(cr_explan, ", ");
+		if (starter.suit == k) {
+			score += 5;
+			if (do_explain)
+				strcat(cr_explan, "Five-flush");
+		} else
+			if (!crb) {
+				score += 4;
+				if (do_explain && cr_explan[0] != '\0')
+					strcat(cr_explan, ", Four-flush");
+				else
+					strcpy(cr_explan, "Four-flush");
+			}
+	}
+	if (do_explain && cr_explan[0] != '\0')
+		strcat(cr_explan, ", ");
+	h[n] = starter;
+	sorthand(h, n + 1);	/* sort by rank */
+	i = 2 * fifteens(h, n + 1);
+	score += i;
+	if (do_explain) {
+		if (i > 0) {
+			(void) sprintf(buf, "%d points in fifteens", i);
+			strcat(cr_explan, buf);
+		} else
+			strcat(cr_explan, "No fifteens");
+	}
+	i = pairuns(h, n + 1);
+	score += i;
+	if (do_explain) {
+		if (i > 0) {
+			(void) sprintf(buf, ", %d points in pairs, %d in runs",
+			    pairpoints, runpoints);
+			strcat(cr_explan, buf);
+		} else
+			strcat(cr_explan, ", No pairs/runs");
+	}
+	return (score);
+}
+
+/*
+ * fifteens:
+ *	Return number of fifteens in hand of n cards
+ */
+int
+fifteens(hand, n)
+	const CARD hand[];
+	int n;
+{
+	int *sp, *np;
+	int i;
+	const CARD *endp;
+	static int sums[15], nsums[15];
+
+	np = nsums;
+	sp = sums;
+	i = 16;
+	while (--i) {
+		*np++ = 0;
+		*sp++ = 0;
+	}
+	for (endp = &hand[n]; hand < endp; hand++) {
+		i = hand->rank + 1;
+		if (i > 10)
+			i = 10;
+		np = &nsums[i];
+		np[-1]++;	/* one way to make this */
+		sp = sums;
+		while (i < 15) {
+			*np++ += *sp++;
+			i++;
+		}
+		sp = sums;
+		np = nsums;
+		i = 16;
+		while (--i)
+			*sp++ = *np++;
+	}
+	return sums[14];
+}
+
+/*
+ * pairuns returns the number of points in the n card sorted hand
+ * due to pairs and runs
+ * this routine only works if n is strictly less than 6
+ * sets the globals pairpoints and runpoints appropriately
+ */
+int
+pairuns(h, n)
+	const CARD h[];
+	int n;
+{
+	int i;
+	int runlength, runmult, lastmult, curmult;
+	int mult1, mult2, pair1, pair2;
+	BOOLEAN run;
+
+	run = TRUE;
+	runlength = 1;
+	mult1 = 1;
+	pair1 = -1;
+	mult2 = 1;
+	pair2 = -1;
+	curmult = runmult = 1;
+	for (i = 1; i < n; i++) {
+		lastmult = curmult;
+		if (h[i].rank == h[i - 1].rank) {
+			if (pair1 < 0) {
+				pair1 = h[i].rank;
+				mult1 = curmult = 2;
+			} else {
+				if (h[i].rank == pair1) {
+					curmult = ++mult1;
+				} else {
+					if (pair2 < 0) {
+						pair2 = h[i].rank;
+						mult2 = curmult = 2;
+					} else {
+						curmult = ++mult2;
+					}
+				}
+			}
+			if (i == (n - 1) && run) {
+				runmult *= curmult;
+			}
+		} else {
+			curmult = 1;
+			if (h[i].rank == h[i - 1].rank + 1) {
+				if (run) {
+					++runlength;
+				} else {
+							/* only if old short */
+					if (runlength < 3) {
+						run = TRUE;
+						runlength = 2;
+						runmult = 1;
+					}
+				}
+				runmult *= lastmult;
+			} else {
+							/* if just ended */
+				if (run)
+					runmult *= lastmult;
+				run = FALSE;
+			}
+		}
+	}
+	pairpoints = ichoose2[mult1] + ichoose2[mult2];
+	runpoints = (runlength >= 3 ? runlength * runmult : 0);
+	return (pairpoints + runpoints);
+}
+
+/*
+ * pegscore tells how many points crd would get if played after
+ * the n cards in tbl during pegging
+ */
+int
+pegscore(crd, tbl, n, sum)
+	CARD crd;
+	const CARD tbl[];
+	int n, sum;
+{
+	BOOLEAN got[RANKS];
+	int i, j, scr;
+	int k, lo, hi;
+
+	sum += VAL(crd.rank);
+	if (sum > 31)
+		return (-1);
+	if (sum == 31 || sum == 15)
+		scr = 2;
+	else
+		scr = 0;
+	if (!n)
+		return (scr);
+	j = 1;
+	while ((crd.rank == tbl[n - j].rank) && (n - j >= 0))
+		++j;
+	if (j > 1)
+		return (scr + ichoose2[j]);
+	if (n < 2)
+		return (scr);
+	lo = hi = crd.rank;
+	for (i = 0; i < RANKS; i++)
+		got[i] = FALSE;
+	got[crd.rank] = TRUE;
+	k = -1;
+	for (i = n - 1; i >= 0; --i) {
+		if (got[tbl[i].rank])
+			break;
+		got[tbl[i].rank] = TRUE;
+		if (tbl[i].rank < lo)
+			lo = tbl[i].rank;
+		if (tbl[i].rank > hi)
+			hi = tbl[i].rank;
+		for (j = lo; j <= hi; j++)
+			if (!got[j])
+				break;
+		if (j > hi)
+			k = hi - lo + 1;
+	}
+	if (k >= 3)
+		return (scr + k);
+	else
+		return (scr);
+}
+
+/*
+ * adjust takes a two card hand that will be put in the crib
+ * and returns an adjusted normalized score for the number of
+ * points such a crib will get.
+ */
+int
+adjust(cb, tnv)
+	const CARD cb[];
+	CARD tnv __attribute__((__unused__));
+{
+	long scr;
+	int i, c0, c1;
+
+	c0 = cb[0].rank;
+	c1 = cb[1].rank;
+	if (c0 > c1) {
+		i = c0;
+		c0 = c1;
+		c1 = i;
+	}
+	if (cb[0].suit != cb[1].suit)
+		scr = crbnescr[RANKS * c0 + c1];
+	else
+		scr = crbescr[RANKS * c0 + c1];
+	if (scr <= 0) {
+		printf("\nADJUST: internal error %d %d\n", c0, c1);
+		exit(93);
+	}
+	return ((scr + 29400) / 58800);
+}
Index: support.c
===================================================================
--- support.c	(nonexistent)
+++ support.c	(revision 5)
@@ -0,0 +1,361 @@
+/*	$NetBSD: support.c,v 1.7 2003/08/07 09:37:11 agc 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 <sys/cdefs.h>
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)support.c	8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: support.c,v 1.7 2003/08/07 09:37:11 agc Exp $");
+#endif
+#endif /* not lint */
+
+#include <curses.h>
+#include <string.h>
+
+#include "deck.h"
+#include "cribbage.h"
+#include "cribcur.h"
+
+#define	NTV	10		/* number scores to test */
+
+/* score to test reachability of, and order to test them in */
+const int tv[NTV] = {8, 7, 9, 6, 11, 12, 13, 14, 10, 5};
+
+/*
+ * computer chooses what to play in pegging...
+ * only called if no playable card will score points
+ */
+int
+cchose(h, n, s)
+	const CARD h[];
+	int n, s;
+{
+	int i, j, l;
+
+	if (n <= 1)
+		return (0);
+	if (s < 4) {		/* try for good value */
+		if ((j = anysumto(h, n, s, 4)) >= 0)
+			return (j);
+		if ((j = anysumto(h, n, s, 3)) >= 0 && s == 0)
+			return (j);
+	}
+	if (s > 0 && s < 20) {
+				/* try for retaliation to 31 */
+		for (i = 1; i <= 10; i++) {
+			if ((j = anysumto(h, n, s, 21 - i)) >= 0) {
+				if ((l = numofval(h, n, i)) > 0) {
+					if (l > 1 || VAL(h[j].rank) != i)
+						return (j);
+				}
+			}
+		}
+	}
+	if (s < 15) {
+				/* for retaliation after 15 */
+		for (i = 0; i < NTV; i++) {
+			if ((j = anysumto(h, n, s, tv[i])) >= 0) {
+				if ((l = numofval(h, n, 15 - tv[i])) > 0) {
+					if (l > 1 ||
+					    VAL(h[j].rank) != 15 - tv[i])
+						return (j);
+				}
+			}
+		}
+	}
+	j = -1;
+				/* remember: h is sorted */
+	for (i = n - 1; i >= 0; --i) {
+		l = s + VAL(h[i].rank);
+		if (l > 31)
+			continue;
+		if (l != 5 && l != 10 && l != 21) {
+			j = i;
+			break;
+		}
+	}
+	if (j >= 0)
+		return (j);
+	for (i = n - 1; i >= 0; --i) {
+		l = s + VAL(h[i].rank);
+		if (l > 31)
+			continue;
+		if (j < 0)
+			j = i;
+		if (l != 5 && l != 21) {
+			j = i;
+			break;
+		}
+	}
+	return (j);
+}
+
+/*
+ * plyrhand:
+ *	Evaluate and score a player hand or crib
+ */
+int
+plyrhand(hand, s)
+	const CARD    hand[];
+	const char   *s;
+{
+	static char prompt[BUFSIZ];
+	int i, j;
+	BOOLEAN win;
+
+	prhand(hand, CINHAND, Playwin, FALSE);
+	(void) sprintf(prompt, "Your %s scores ", s);
+	i = scorehand(hand, turnover, CINHAND, strcmp(s, "crib") == 0, explain);
+	if ((j = number(0, 29, prompt)) == 19)
+		j = 0;
+	if (i != j) {
+		if (i < j) {
+			win = chkscr(&pscore, i);
+			msg("It's really only %d points; I get %d", i, 2);
+			if (!win)
+				win = chkscr(&cscore, 2);
+		} else {
+			win = chkscr(&pscore, j);
+			msg("You should have taken %d, not %d!", i, j);
+		}
+		if (explain)
+			msg("Explanation: %s", cr_explan);
+		do_wait();
+	} else
+		win = chkscr(&pscore, i);
+	return (win);
+}
+
+/*
+ * comphand:
+ *	Handle scoring and displaying the computers hand
+ */
+int
+comphand(h, s)
+	const CARD h[];
+	const char *s;
+{
+	int j;
+
+	j = scorehand(h, turnover, CINHAND, strcmp(s, "crib") == 0, FALSE);
+	prhand(h, CINHAND, Compwin, FALSE);
+	msg("My %s scores %d", s, (j == 0 ? 19 : j));
+	return (chkscr(&cscore, j));
+}
+
+/*
+ * chkscr:
+ *	Add inc to scr and test for > glimit, printing on the scoring
+ *	board while we're at it.
+ */
+int Lastscore[2] = {-1, -1};
+
+int
+chkscr(scr, inc)
+	int    *scr, inc;
+{
+	BOOLEAN myturn;
+
+	myturn = (scr == &cscore);
+	if (inc != 0) {
+		prpeg(Lastscore[(int)myturn], '.', myturn);
+		Lastscore[(int)myturn] = *scr;
+		*scr += inc;
+		prpeg(*scr, PEG, myturn);
+		refresh();
+	}
+	return (*scr >= glimit);
+}
+
+/*
+ * prpeg:
+ *	Put out the peg character on the score board and put the
+ *	score up on the board.
+ */
+void
+prpeg(score, peg, myturn)
+	int score;
+	int peg;
+	BOOLEAN myturn;
+{
+	int y, x;
+
+	if (!myturn)
+		y = SCORE_Y + 2;
+	else
+		y = SCORE_Y + 5;
+
+	if (score <= 0 || score >= glimit) {
+		if (peg == '.')
+			peg = ' ';
+		if (score == 0)
+			x = SCORE_X + 2;
+		else {
+			x = SCORE_X + 2;
+			y++;
+		}
+	} else {
+		x = (score - 1) % 30;
+		if (score > 90 || (score > 30 && score <= 60)) {
+			y++;
+			x = 29 - x;
+		}
+		x += x / 5;
+		x += SCORE_X + 3;
+	}
+	mvaddch(y, x, peg);
+	mvprintw(SCORE_Y + (myturn ? 7 : 1), SCORE_X + 10, "%3d", score);
+}
+
+/*
+ * cdiscard -- the computer figures out what is the best discard for
+ * the crib and puts the best two cards at the end
+ */
+void
+cdiscard(mycrib)
+	BOOLEAN mycrib;
+{
+	CARD    d[CARDS], h[FULLHAND], cb[2];
+	int i, j, k;
+	int     nc, ns;
+	long    sums[15];
+	static int undo1[15] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4};
+	static int undo2[15] = {1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5};
+
+	makedeck(d);
+	nc = CARDS;
+	for (i = 0; i < knownum; i++) {	/* get all other cards */
+		cremove(known[i], d, nc--);
+	}
+	for (i = 0; i < 15; i++)
+		sums[i] = 0L;
+	ns = 0;
+	for (i = 0; i < (FULLHAND - 1); i++) {
+		cb[0] = chand[i];
+		for (j = i + 1; j < FULLHAND; j++) {
+			cb[1] = chand[j];
+			for (k = 0; k < FULLHAND; k++)
+				h[k] = chand[k];
+			cremove(chand[i], h, FULLHAND);
+			cremove(chand[j], h, FULLHAND - 1);
+			for (k = 0; k < nc; k++) {
+				sums[ns] +=
+				    scorehand(h, d[k], CINHAND, TRUE, FALSE);
+				if (mycrib)
+					sums[ns] += adjust(cb, d[k]);
+				else
+					sums[ns] -= adjust(cb, d[k]);
+			}
+			++ns;
+		}
+	}
+	j = 0;
+	for (i = 1; i < 15; i++)
+		if (sums[i] > sums[j])
+			j = i;
+	for (k = 0; k < FULLHAND; k++)
+		h[k] = chand[k];
+	cremove(h[undo1[j]], chand, FULLHAND);
+	cremove(h[undo2[j]], chand, FULLHAND - 1);
+	chand[4] = h[undo1[j]];
+	chand[5] = h[undo2[j]];
+}
+
+/*
+ * returns true if some card in hand can be played without exceeding 31
+ */
+int
+anymove(hand, n, sum)
+	const CARD hand[];
+	int n, sum;
+{
+	int i, j;
+
+	if (n < 1)
+		return (FALSE);
+	j = hand[0].rank;
+	for (i = 1; i < n; i++) {
+		if (hand[i].rank < j)
+			j = hand[i].rank;
+	}
+	return (sum + VAL(j) <= 31);
+}
+
+/*
+ * anysumto returns the index (0 <= i < n) of the card in hand that brings
+ * the s up to t, or -1 if there is none
+ */
+int
+anysumto(hand, n, s, t)
+	const CARD hand[];
+	int n, s, t;
+{
+	int i;
+
+	for (i = 0; i < n; i++) {
+		if (s + VAL(hand[i].rank) == t)
+			return (i);
+	}
+	return (-1);
+}
+
+/*
+ * return the number of cards in h having the given rank value
+ */
+int
+numofval(h, n, v)
+	const CARD h[];
+	int n, v;
+{
+	int i, j;
+
+	j = 0;
+	for (i = 0; i < n; i++) {
+		if (VAL(h[i].rank) == v)
+			++j;
+	}
+	return (j);
+}
+
+/*
+ * makeknown remembers all n cards in h for future recall
+ */
+void
+makeknown(h, n)
+	const CARD h[];
+	int n;
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		known[knownum++] = h[i];
+}
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~