diff options
author | jkh <jkh@FreeBSD.org> | 1994-09-04 04:03:31 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1994-09-04 04:03:31 +0000 |
commit | 057afceb86e030ad65b0130436860d9a18066186 (patch) | |
tree | a0ced9c9b9278eb776d89cd2565c27ddcf020b51 /games/cribbage | |
parent | eedec95276cdb8aef98e92c5371000f10b8d6ba7 (diff) | |
download | FreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.zip FreeBSD-src-057afceb86e030ad65b0130436860d9a18066186.tar.gz |
Bring in the 4.4 Lite games directory, modulo man page changes and segregation
of the x11 based games. I'm not going to tag the originals with bsd_44_lite
and do this in two stages since it's just not worth it for this collection,
and I've got directory renames to deal with that way. Bleah.
Submitted by: jkh
Diffstat (limited to 'games/cribbage')
-rw-r--r-- | games/cribbage/Makefile | 14 | ||||
-rw-r--r-- | games/cribbage/cards.c | 149 | ||||
-rw-r--r-- | games/cribbage/crib.c | 622 | ||||
-rw-r--r-- | games/cribbage/cribbage.6 | 129 | ||||
-rw-r--r-- | games/cribbage/cribbage.h | 112 | ||||
-rw-r--r-- | games/cribbage/cribbage.n | 226 | ||||
-rw-r--r-- | games/cribbage/cribcur.h | 57 | ||||
-rw-r--r-- | games/cribbage/deck.h | 85 | ||||
-rw-r--r-- | games/cribbage/extern.c | 68 | ||||
-rw-r--r-- | games/cribbage/instr.c | 87 | ||||
-rw-r--r-- | games/cribbage/io.c | 624 | ||||
-rw-r--r-- | games/cribbage/pathnames.h | 38 | ||||
-rw-r--r-- | games/cribbage/score.c | 367 | ||||
-rw-r--r-- | games/cribbage/support.c | 358 |
14 files changed, 2936 insertions, 0 deletions
diff --git a/games/cribbage/Makefile b/games/cribbage/Makefile new file mode 100644 index 0000000..83c97d2 --- /dev/null +++ b/games/cribbage/Makefile @@ -0,0 +1,14 @@ +# @(#)Makefile 8.1 (Berkeley) 5/31/93 + +PROG= cribbage +DPADD= ${LIBCURSES} ${LIBTERM} ${LIBCOMPAT} +LDADD= -lcurses -ltermlib -lcompat +SRCS= extern.c crib.c cards.c instr.c io.c score.c support.c +MAN6= cribbage.6 +HIDEGAME=hidegame + +beforeinstall: + install -c -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/cribbage.n \ + ${DESTDIR}/usr/share/games/cribbage.instr + +.include <bsd.prog.mk> diff --git a/games/cribbage/cards.c b/games/cribbage/cards.c new file mode 100644 index 0000000..742370a --- /dev/null +++ b/games/cribbage/cards.c @@ -0,0 +1,149 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)cards.c 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include <curses.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +#include "deck.h" +#include "cribbage.h" + + +/* + * Initialize a deck of cards to contain one of each type. + */ +void +makedeck(d) + CARD d[]; +{ + register int i, j, k; + + i = time(NULL); + i = ((i & 0xff) << 8) | ((i >> 8) & 0xff) | 1; + srand(i); + k = 0; + for (i = 0; i < RANKS; i++) + for (j = 0; j < SUITS; j++) { + d[k].suit = j; + d[k++].rank = i; + } +} + +/* + * Given a deck of cards, shuffle it -- i.e. randomize it + * see Knuth, vol. 2, page 125. + */ +void +shuffle(d) + CARD d[]; +{ + register int j, k; + CARD c; + + for (j = CARDS; j > 0; --j) { + k = (rand() >> 4) % j; /* random 0 <= k < j */ + c = d[j - 1]; /* exchange (j - 1) and k */ + d[j - 1] = d[k]; + d[k] = c; + } +} + +/* + * return true if the two cards are equal... + */ +int +eq(a, b) + CARD a, b; +{ + return ((a.rank == b.rank) && (a.suit == b.suit)); +} + +/* + * isone returns TRUE if a is in the set of cards b + */ +int +isone(a, b, n) + CARD a, b[]; + int n; +{ + register int i; + + for (i = 0; i < n; i++) + if (eq(a, b[i])) + return (TRUE); + return (FALSE); +} + +/* + * remove the card a from the deck d of n cards + */ +void +cremove(a, d, n) + CARD a, d[]; + int n; +{ + register int i, j; + + for (i = j = 0; i < n; i++) + if (!eq(a, d[i])) + d[j++] = d[i]; + if (j < n) + d[j].suit = d[j].rank = EMPTY; +} + +/* + * sorthand: + * Sort a hand of n cards + */ +void +sorthand(h, n) + register CARD h[]; + int n; +{ + register CARD *cp, *endp; + CARD c; + + for (endp = &h[n]; h < endp - 1; h++) + for (cp = h + 1; cp < endp; cp++) + if ((cp->rank < h->rank) || + (cp->rank == h->rank && cp->suit < h->suit)) { + c = *h; + *h = *cp; + *cp = c; + } +} diff --git a/games/cribbage/crib.c b/games/cribbage/crib.c new file mode 100644 index 0000000..16233ae --- /dev/null +++ b/games/cribbage/crib.c @@ -0,0 +1,622 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)crib.c 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include <curses.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(argc, argv) + int argc; + char *argv[]; +{ + BOOLEAN playing; + FILE *f; + int ch; + + while ((ch = getopt(argc, argv, "eqr")) != EOF) + 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, rint); + crmode(); + 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(); + crmode(); + 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 = fopen(_PATH_LOG, "a")) { + (void)fprintf(f, "%s: won %5.5d, lost %5.5d\n", + getlogin(), cgames, pgames); + (void) fclose(f); + } + bye(); + if (!f) { + (void) fprintf(stderr, "\ncribbage: can't open %s.\n", + _PATH_LOG); + exit(1); + } + 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() +{ + extern int Lastscore[]; + + 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() +{ + register int i, j; + BOOLEAN flag; + BOOLEAN compcrib; + + 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? "); + 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); + clear(); + makeboard(); + refresh(); + } else { + 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; +{ + register int deckpos; + + werase(Compwin); + + 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; +{ + register 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; +{ + register 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; +{ + register 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? "); + 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; +{ + register 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, " "); +} + +/* + * peg: + * Handle all the pegging... + */ +static CARD Table[14]; +static int Tcnt; + +int +peg(mycrib) + BOOLEAN mycrib; +{ + static CARD ch[CINHAND], ph[CINHAND]; + register int i, j, k; + register int l; + register int cnum, pnum, sum; + register BOOLEAN myturn, mego, ugo, last, played; + CARD crd; + + 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"); + 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 (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"); + 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); + } else { + if (comphand(chand, "hand")) + return (TRUE); + if (plyrhand(phand, "hand")) + return (TRUE); + if (plyrhand(crib, "crib")) + return (TRUE); + } + return (FALSE); +} diff --git a/games/cribbage/cribbage.6 b/games/cribbage/cribbage.6 new file mode 100644 index 0000000..af7924c --- /dev/null +++ b/games/cribbage/cribbage.6 @@ -0,0 +1,129 @@ +.\" 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. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. 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.6 8.1 (Berkeley) 5/31/93 +.\" +.TH CRIBBAGE 6 "May 31, 1993" +.UC 4 +.SH NAME +cribbage \- the card game cribbage +.SH SYNOPSIS +.B /usr/games/cribbage +[ +.B \-req +] +.I name ... +.SH DESCRIPTION +.I Cribbage +plays the card game cribbage, with the program playing one hand +and the user the other. The program will initially ask the user if +the rules of the game are needed \- if so, it will print out +the appropriate section from +.I According to Hoyle +with +.I more (I). +.PP +.I Cribbage +options include: +.TP +.B \-e +When the player makes a mistake scoring his hand or crib, provide an +explanation of the correct score. (This is especially useful for +beginning players.) +.TP +.B \-q +Print a shorter form of all messages \- this is only recommended for +users who have played the game without specifying this option. +.TP +.B \-r +Instead of asking the player to cut the deck, the program will randomly +cut the deck. +.PP +.I Cribbage +first asks the player whether he wishes to play a short game +(\*(lqonce around\*(rq, to 61) or a long game (\*(lqtwice around\*(rq, to 121). A +response of `s' will result in a short game, any other response will +play a long game. +.PP +At the start of the first game, the program +asks the player to cut the deck to determine who gets the +first crib. The user should respond with a number between 0 and +51, indicating how many cards down the deck is to be cut. The player +who cuts the lower ranked card gets the first crib. +If more than one game is played, the +loser of the previous game gets the first crib in the current game. +.PP +For each hand, the program first prints the player's hand, +whose crib it is, and then asks the player +to discard two cards into the crib. The cards are prompted for +one per line, and are typed as explained below. +.PP +After discarding, the program cuts the deck (if it is the player's +crib) or asks the player to cut the deck (if it's its crib); in the latter +case, the appropriate response is a number from 0 to 39 indicating +how far down the remaining 40 cards are to be cut. +.PP +After cutting the deck, play starts with the non-dealer (the person +who doesn't have the crib) leading the first card. +Play continues, as per cribbage, until all cards are exhausted. The +program keeps track of the scoring of all points and the total of +the cards on the table. +.PP +After play, the hands are scored. The program requests the player to +score his hand (and the crib, if it is his) by printing out the +appropriate cards (and the cut card enclosed in brackets). +Play continues until one player reaches the game limit (61 or 121). +.PP +A carriage return when a numeric input is expected is equivalent +to typing the lowest legal value; when cutting the deck this +is equivalent to choosing the top card. +.PP +Cards are specified as rank followed by suit. The ranks may be specified +as one of: +`a', `2', `3', `4', `5', `6', `7', `8', `9', `t', `j', `q', and `k', +or alternatively, one of: \*(lqace\*(rq, \*(lqtwo\*(rq, \*(lqthree\*(rq, \*(lqfour\*(rq, \*(lqfive\*(rq, \*(lqsix\*(rq, +\*(lqseven\*(rq, \*(lqeight\*(rq, \*(lqnine\*(rq, \*(lqten\*(rq, \*(lqjack\*(rq, \*(lqqueen\*(rq, and \*(lqking\*(rq. +Suits may be specified as: `s', `h', `d', and `c', or alternatively as: +\*(lqspades\*(rq, \*(lqhearts\*(rq, \*(lqdiamonds\*(rq, and \*(lqclubs\*(rq. +A card may be specified as: <rank> \*(lq \*(rq <suit>, or: <rank> \*(lq of \*(rq <suit>. +If the single letter rank and suit designations are used, the space +separating the suit and rank may be left out. Also, if only one card +of the desired rank is playable, typing the rank is sufficient. +For example, if your hand was \*(lq2H, 4D, 5C, 6H, JC, KD\*(rq and it was +desired to discard the king of diamonds, any of the following could be typed: +\*(lqk\*(rq, \*(lqking\*(rq, \*(lqkd\*(rq, \*(lqk d\*(rq, \*(lqk of d\*(rq, \*(lqking d\*(rq, \*(lqking of d\*(rq, \*(lqk diamonds\*(rq, +\*(lqk of diamonds\*(rq, \*(lqking diamonds\*(rq, or \*(lqking of diamonds\*(rq. +.SH FILES +.ta 2i +/usr/games/cribbage +.SH AUTHORS +Earl T. Cohen wrote the logic. +Ken Arnold added the screen oriented interface. diff --git a/games/cribbage/cribbage.h b/games/cribbage/cribbage.h new file mode 100644 index 0000000..dae270c --- /dev/null +++ b/games/cribbage/cribbage.h @@ -0,0 +1,112 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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 expl[]; /* string for explanation */ + +void addmsg __P((const char *, ...)); +int adjust __P((CARD [], CARD)); +int anymove __P((CARD [], int, int)); +int anysumto __P((CARD [], int, int, int)); +void bye __P((void)); +int cchose __P((CARD [], int, int)); +void cdiscard __P((BOOLEAN)); +int chkscr __P((int *, int)); +int comphand __P((CARD [], char *)); +void cremove __P((CARD, CARD [], int)); +int cut __P((BOOLEAN, int)); +int deal __P((int)); +void discard __P((BOOLEAN)); +void do_wait __P((void)); +void endmsg __P((void)); +int eq __P((CARD, CARD)); +int fifteens __P((CARD [], int)); +void game __P((void)); +void gamescore __P((void)); +char *getline __P((void)); +int getuchar __P((void)); +int incard __P((CARD *)); +int infrom __P((CARD [], int, char *)); +void instructions __P((void)); +int isone __P((CARD, CARD [], int)); +void makeboard __P((void)); +void makedeck __P((CARD [])); +void makeknown __P((CARD [], int)); +void msg __P((const char *, ...)); +int msgcard __P((CARD, BOOLEAN)); +int msgcrd __P((CARD, BOOLEAN, char *, BOOLEAN)); +int number __P((int, int, char *)); +int numofval __P((CARD [], int, int)); +int pairuns __P((CARD [], int)); +int peg __P((BOOLEAN)); +int pegscore __P((CARD, CARD [], int, int)); +int playhand __P((BOOLEAN)); +int plyrhand __P((CARD [], char *)); +void prcard __P((WINDOW *, int, int, CARD, BOOLEAN)); +void prcrib __P((BOOLEAN, BOOLEAN)); +void prhand __P((CARD [], int, WINDOW *, BOOLEAN)); +void printcard __P((WINDOW *, int, CARD, BOOLEAN)); +void prpeg __P((int, int, BOOLEAN)); +void prtable __P((int)); +int readchar __P((void)); +void rint __P((int)); +int score __P((BOOLEAN)); +int scorehand __P((CARD [], CARD, int, BOOLEAN, BOOLEAN)); +void shuffle __P((CARD [])); +void sorthand __P((CARD [], int)); +void wait_for __P((int)); diff --git a/games/cribbage/cribbage.n b/games/cribbage/cribbage.n new file mode 100644 index 0000000..084e091 --- /dev/null +++ b/games/cribbage/cribbage.n @@ -0,0 +1,226 @@ + + CRIBBAGE + from + According to Hoyle + +Cribbage is believed to have been invented by Sir John Suckling (1609-1642). +Probably it is an elaboration of an older game, Noddy. The original game +was played with hands of five cards; the modern game gives each player +six. That is virtually the only change from Suckling's directions. + +Players: + + Two. There are variants for three and four players, described + later. + +Cards: + + The pack of 52. The cards in each suit rank: K (high), Q, J, 10, +9, 8, 7, 6, 5, 4, 3, 2, A. The counting values are: K, Q, J, 10, each 10 +(wherefore these are called tenth cards); ace, 1; each other card, its +index value. + +Cribbage Board: + + Indispensable to scoring (unless you have a computer!, ed.) is +the device known as the cribbage board. This is a rectangular panel, long +and narrow, in which are four rows of 30 holes each. (See illustration.) +At one end, or in the center, are two or four additional holes, called +game holes. The board is placed between the two players, and each keeps +his own score on the two rows of holes nearest himself. Each is supplied +with two pegs. Before the first hand, the pegs are placed in the game +holes. On making his first score, the player advances one peg an +appropriate number of holes (one per point) away from the game end of the +board. The second score is recorded by placing the second peg an +appropriate distance ahead of the first. For each subsequent score, the +rear peg is jumped ahead of the other, the distance between the two pegs +always showing the amount of this last score. + + The traditional mode of scoring is down (away from the game end) +the outer row, and up the inner row. "Once around" is a game of 61 points. +"Twice around" is a game of 121 points. + +Preliminaries: + + Cards are drawn; the lower deals first. If cards of equal rank +are drawn, both players draw again. Dealer has the right to shuffle last. +Nondealer cuts, and must leave at least four cards in each packet. + +Dealing: + + Each player receives six cards, dealt one at a time face down, +beginning with the nondealer. The turn to deal alternates. The dealer +has an advantage. + +Laying Away: + + After seeing his hand, each player lays away two cards face down. +The four cards laid away, placed in one pile, form the crib. The crib +counts for the dealer. Nondealer therefore tries to lay away balking +cards -- cards that are least likely to create a score in the crib. + +The Starter: + + After both hands have laid away, nondealer lifts off a packet from +the top of the stock (the rest of the pack). Again, each packet must +contain at least four cards. Dealer turns up the top card of the lower +packer, which is then placed on top of the stock when the packets are +reunited. The card thus turned up is called 1 the starter. If it is a +jack, dealer immediately pegs 2, called 2 for his heels. + +The Play: + + Nondealer begins the play by laying a card from his hand face up +on the table, announcing its counting value. Dealer then shows a card, +announcing the total count of the two cards. Play continues in the same +way, by alternate exposure of cards, each player announcing the new total +count. The total may be carried only to 31, no further. If a player adds +a card that brings the total exactly to 31, he pegs 2. If a player is +unable to play another card without exceeding 31, he must say "Go," and +his opponent pegs 1, but before doing so, opponent must lay down any +additional cards he can without exceeding 31. If such additional cards +bring the total to exactly 31, he pegs 2 instead of 1. + + Whenever a go occurs, the opponent of the player who played the +last card must lead for a new count starting at zero. Playing the last +card of all counts as a go. (Since nondealer makes the opening lead, +dealer is bound to peg at least 1 in play.) + + Besides pegging for 31 and go, the player may also peg for certain +combinations made in play, as follows: + + Fifteen: + Making the count total 15 pegs 2. + Pair: + Playing a card of same rank as that previously played pegs + 2. Playing a third card of the same rank makes pair royal + and pegs 6. Playing the fourth card of the same rank + makes double pair royal and pegs 12. + + The tenth cards pair strictly by rank, a king with a king, + a queen with a queen, and so on. (King and jack do not + make a pair, although each has the counting value 10.) + Run: + Playing a card which, with the two or more played + immediately previously, makes a sequence of three or more + cards, pegs 1 for each card in the run. Runs depend on + rank alone; the suits do not matter. Nor does the score + for run depend upon playing the cards in strict sequence, + so long as the three or more last cards played can be + arranged in a run. Example: 7, 6, 8 played in that order + score 3 for run; 5, 2, 4, 3 played in that order score 4 + for run. + + Any of the foregoing combinations count, whether the cards + are played alternately or one player plays several times + in succession in consequence of a go. But a combination + does not score if it is interrupted by a go. + + Showing: + After the play, the hands are shown (counted). Nondealer + shows first, then dealer's hand, then crib. The starter + is deemed to belong to each hand, so that each hand includes + five cards. Combinations of scoring value are as follows: + + Fifteen: + Each combinations of two or more cards that total + fifteen scores 2. + Pair: + Each pair of cards of the same rank scores 2. + + Run: + Each combination of three or more cards in sequence + scores 1 for each card in the run. + Flush: + Four cards of the same suit in hand score 4; four + cards in hand or crib of same suit as the starter + score 5. (No count for four-flush in crib.) + His Nobs: + Jack of same suit as the starter, in hand or crib, + scores 1. + + It is important to note that every separate grouping of cards that +makes a fifteen, pair, or run counts separately. Three of a kind, pair +royal, counts 6 because three sets of pairs can be made; similarly, four +of a kind, double pair royal, contain six pairs and count 12. + + The highest possible hand is J, 5, 5, 5 with the starter the 5 of +the same suit as the jack. There are four fifteens by combining the jack +with a five, four more by combinations of three fives (a total of 16 for +fifteens); the double pair royal adds 12 for a total of 28; and his nobs +adds 1 for a maximum score of 29. (the score of 2 for his heels does not +count in the total of the hand, since it is pegged before the play.) + + A double run is a run with one card duplicated, as 4-3-3-2. +Exclusive of fifteens, a double run of three cards counts 8; of four cards, +10. A triple run is a run of three with one card triplicated, as K-K-K-Q-J. +Exclusive of fifteens, it counts 15. A quadruple run is a run of three +with two different cards duplicated, as the example 8-8-7-6-6 previously +given. Exclusive of fifteens, it counts 16. + + No hand can be constructed that counts 19, 25, 26 or 27. A +time-honored way of showing a hand with not a single counting combination +is to say "I have nineteen." + + The customary order in showing is to count fifteens first, then +runs, then pairs, but there is no compulsion of law. Example: A hand +(with starter) of 9-6-5-4-4 will usually be counted "Fifteen 2, fifteen +4, fifteen 6 and double run makes 14," or simply "Fifteen 6 and 8 is 14." + +Muggins: + + The hands and crib are counted aloud, and if a player claims a +greater total than is due him, his opponent may require correction. In +some localities, if a player claims less than is due, his opponent may +say "Muggins" and himself score the points overlooked. + +Scoring: + + The usual game is 121, but it may be set at 61 by agreement. +Since the player wins who first returns to the game hole by going "twice +around," the scores must be pegged strictly in order: his heels, pegging +in play, non-dealer's hand, dealer's hand, crib. Thus, if nondealer goes +out on showing his hand, he wins, even though dealer might have gone out +with a greater total if allowed to count his hand and crib. + + When the game of 121 is played for a stake, a player wins a single +game if the loser makes 61 points or more. If the loser fails to reach +61, he is lurched, and the other wins a double game. + +Irregularities: + + Misdeal. There must be a new deal by the same dealer if a card +is found faced in the pack, if a card is exposed in dealing, or if the +pack be found imperfect. + + Wrong Number of Cards. If one hand (not crib) is found to have +the wrong number of cards after laying away for the crib, the other hand +and crib being correct, the opponent may either demand a new deal or may +peg 2 and rectify the hand. If the crib is incorrect, both hands being +correct, nondealer pegs 2 and the crib is corrected. + +Error in Pegging: + + If a player places a peg short of the amount to which he is +entitled, he may not correct his error after he has played the next card +or after the cut for the next deal. If he pegs more than his announced +score, the error must be corrected on demand at any time before the cut +for the next deal and his opponent pegs 2. + +Strategy: + + The best balking cards are kings and aces, because they have the +least chance of producing sequences. Tenth cards are generally good, +provided that the two cards laid away are not too near (likely to make a +sequence). When nothing better offers, give two wide cards -- at least +three apart in rank. + + Proverbially the safest lead is a 4. The next card cannot make +a 15. Lower cards are also safe from this point of view, but are better +treasured for go and 31. The most dangerous leads are 7 and 8, but may +be made to trap the opponent when they are backed with other close cards. +Generally speaking, play on (toward a sequence) when you have close cards +and off when you do not. However, the state of the score is a +consideration. If far behind, play on when there is any chance of building +a score for yourself; if well ahead, balk your opponent by playing off +unless you will surely peg as much as he by playing on. diff --git a/games/cribbage/cribcur.h b/games/cribbage/cribcur.h new file mode 100644 index 0000000..5e8bfd4 --- /dev/null +++ b/games/cribbage/cribcur.h @@ -0,0 +1,57 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)cribcur.h 8.1 (Berkeley) 5/31/93 + */ + +# define PLAY_Y 15 /* size of player's hand window */ +# define PLAY_X 12 +# define TABLE_Y 21 /* size of table window */ +# define TABLE_X 14 +# define COMP_Y 15 /* size of computer's hand window */ +# define COMP_X 12 +# define Y_SCORE_SZ 9 /* Y size of score board */ +# define X_SCORE_SZ 41 /* X size of score board */ +# define SCORE_Y 0 /* starting position of scoring board */ +# define SCORE_X (PLAY_X + TABLE_X + COMP_X) +# define CRIB_Y 17 /* position of crib (cut card) */ +# define CRIB_X (PLAY_X + TABLE_X) +# define MSG_Y (LINES - (Y_SCORE_SZ + 1)) +# define MSG_X (COLS - SCORE_X - 1) +# define Y_MSG_START (Y_SCORE_SZ + 1) + +# define PEG '*' /* what a peg looks like on the board */ + +extern WINDOW *Compwin; /* computer's hand window */ +extern WINDOW *Msgwin; /* message window */ +extern WINDOW *Playwin; /* player's hand window */ +extern WINDOW *Tablewin; /* table window */ diff --git a/games/cribbage/deck.h b/games/cribbage/deck.h new file mode 100644 index 0000000..60a307d --- /dev/null +++ b/games/cribbage/deck.h @@ -0,0 +1,85 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)deck.h 8.1 (Berkeley) 5/31/93 + */ + +/* + * define structure of a deck of cards and other related things + */ + + +#define CARDS 52 /* number cards in deck */ +#define RANKS 13 /* number ranks in deck */ +#define SUITS 4 /* number suits in deck */ + +#define CINHAND 4 /* # cards in cribbage hand */ +#define FULLHAND 6 /* # cards in dealt hand */ + +#define LGAME 121 /* number points in a game */ +#define SGAME 61 /* # points in a short game */ + +#define SPADES 0 /* value of each suit */ +#define HEARTS 1 +#define DIAMONDS 2 +#define CLUBS 3 + +#define ACE 0 /* value of each rank */ +#define TWO 1 +#define THREE 2 +#define FOUR 3 +#define FIVE 4 +#define SIX 5 +#define SEVEN 6 +#define EIGHT 7 +#define NINE 8 +#define TEN 9 +#define JACK 10 +#define QUEEN 11 +#define KING 12 +#define EMPTY 13 + +#define VAL(c) ( (c) < 9 ? (c)+1 : 10 ) /* val of rank */ + + +#ifndef TRUE +# define TRUE 1 +# define FALSE 0 +#endif + +typedef struct { + int rank; + int suit; + } CARD; + +typedef char BOOLEAN; + diff --git a/games/cribbage/extern.c b/games/cribbage/extern.c new file mode 100644 index 0000000..9083cc8 --- /dev/null +++ b/games/cribbage/extern.c @@ -0,0 +1,68 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)extern.c 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include <curses.h> + +#include "deck.h" +#include "cribbage.h" + +bool explain = FALSE; /* player mistakes explained */ +bool iwon = FALSE; /* if comp won last game */ +bool quiet = FALSE; /* if suppress random mess */ +bool rflag = FALSE; /* if all cuts random */ + +char expl[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 */ diff --git a/games/cribbage/instr.c b/games/cribbage/instr.c new file mode 100644 index 0000000..a0414d8 --- /dev/null +++ b/games/cribbage/instr.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 1990, 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)instr.c 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/errno.h> +#include <sys/stat.h> + +#include <curses.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "deck.h" +#include "cribbage.h" +#include "pathnames.h" + +void +instructions() +{ + extern int errno; + struct stat sb; + union wait pstat; + pid_t pid; + char *pager, *path; + + if (stat(_PATH_INSTR, &sb)) { + (void)fprintf(stderr, "cribbage: %s: %s.\n", _PATH_INSTR, + strerror(errno)); + exit(1); + } + switch (pid = vfork()) { + case -1: + (void)fprintf(stderr, "cribbage: %s.\n", strerror(errno)); + exit(1); + case 0: + if (!(path = getenv("PAGER"))) + path = _PATH_MORE; + if (pager = rindex(path, '/')) + ++pager; + pager = path; + execlp(path, pager, _PATH_INSTR, (char *)NULL); + (void)fprintf(stderr, "cribbage: %s.\n", strerror(errno)); + _exit(1); + default: + do { + pid = waitpid(pid, (int *)&pstat, 0); + } while (pid == -1 && errno == EINTR); + if (pid == -1 || pstat.w_status) + exit(1); + } +} diff --git a/games/cribbage/io.c b/games/cribbage/io.c new file mode 100644 index 0000000..c38c119 --- /dev/null +++ b/games/cribbage/io.c @@ -0,0 +1,624 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include <ctype.h> +#include <curses.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> + +#if __STDC__ +#include <stdarg.h> +#else +#include <varargs.h> +#endif + +#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]; + +char *rankname[RANKS] = { + "ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", + "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING" +}; + +char *rankchar[RANKS] = { + "A", "2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K" +}; + +char *suitname[SUITS] = {"SPADES", "HEARTS", "DIAMONDS", "CLUBS"}; + +char *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; + 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) + CARD h[]; + int n; + WINDOW *win; + BOOLEAN blank; +{ + register 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) + CARD hand[]; + int n; + char *prompt; +{ + register 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 (!isone(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: isone 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; +{ + register int i; + int rnk, sut; + char *line, *p, *p1; + BOOLEAN retval; + + retval = FALSE; + rnk = sut = EMPTY; + if (!(line = getline())) + goto gotit; + p = p1 = line; + while (*p1 != ' ' && *p1 != NULL) + ++p1; + *p1++ = NULL; + if (*p == NULL) + 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 != NULL) + ++p1; + *p1++ = NULL; + if (*p == NULL) + goto gotit; + if (!strcmp("OF", p)) { + p = p1; + while (*p1 != ' ' && *p1 != NULL) + ++p1; + *p1++ = NULL; + if (*p == NULL) + 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() +{ + register 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; + char *prompt; +{ + register char *p; + register int sum; + + for (sum = 0;;) { + msg(prompt); + if (!(p = getline()) || *p == NULL) { + msg(quiet ? "Not a number" : + "That doesn't look like a number"); + continue; + } + sum = 0; + + if (!isdigit(*p)) + sum = lo - 1; + else + while (isdigit(*p)) { + sum = 10 * sum + (*p - '0'); + ++p; + } + + if (*p != ' ' && *p != '\t' && *p != NULL) + 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 +#if __STDC__ +msg(const char *fmt, ...) +#else +msg(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vsprintf(&Msgbuf[Newpos], fmt, ap); + va_end(ap); + endmsg(); +} + +/* + * addmsg: + * Add things to the current message + */ +void +#if __STDC__ +addmsg(const char *fmt, ...) +#else +addmsg(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ap; + +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)vsprintf(&Msgbuf[Newpos], fmt, ap); + va_end(ap); +} + +/* + * endmsg: + * Display a new msg. + */ +int Lineno = 0; + +void +endmsg() +{ + static int lastline = 0; + register int len; + register char *mp, *omp; + + /* All messages should start with uppercase */ + mvaddch(lastline + Y_MSG_START, SCORE_X, ' '); + if (islower(Msgbuf[0]) && Msgbuf[1] != ')') + Msgbuf[0] = toupper(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 char prompt[] = {'-', '-', 'M', 'o', 'r', 'e', '-', '-', '\0'}; + + if (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) + register int ch; +{ + register 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() +{ + register 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 * +getline() +{ + register char *sp; + register int c, oy, ox; + register 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) { + register 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 +rint(signo) + int signo; +{ + 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'); +} diff --git a/games/cribbage/pathnames.h b/games/cribbage/pathnames.h new file mode 100644 index 0000000..5c30f73 --- /dev/null +++ b/games/cribbage/pathnames.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 1990, 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)pathnames.h 8.1 (Berkeley) 5/31/93 + */ + +#define _PATH_INSTR "/usr/share/games/cribbage.instr" +#define _PATH_LOG "/var/games/criblog" +#define _PATH_MORE "/usr/bin/more" diff --git a/games/cribbage/score.c b/games/cribbage/score.c new file mode 100644 index 0000000..239e26d --- /dev/null +++ b/games/cribbage/score.c @@ -0,0 +1,367 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)score.c 8.1 (Berkeley) 5/31/93"; +#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 + */ +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 +}; + +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 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) + register CARD hand[]; + CARD starter; + int n; + BOOLEAN crb; /* true if scoring crib */ + BOOLEAN do_explain; /* true if must explain this hand */ +{ + register int i, k; + register int score; + register BOOLEAN flag; + CARD h[(CINHAND + 1)]; + char buf[32]; + + expl[0] = NULL; /* 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(expl, "His Nobs"); + } + h[i] = hand[i]; + } + + if (flag && n >= CINHAND) { + if (do_explain && expl[0] != NULL) + strcat(expl, ", "); + if (starter.suit == k) { + score += 5; + if (do_explain) + strcat(expl, "Five-flush"); + } else + if (!crb) { + score += 4; + if (do_explain && expl[0] != NULL) + strcat(expl, ", Four-flush"); + else + strcpy(expl, "Four-flush"); + } + } + if (do_explain && expl[0] != NULL) + strcat(expl, ", "); + 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(expl, buf); + } else + strcat(expl, "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(expl, buf); + } else + strcat(expl, ", No pairs/runs"); + return (score); +} + +/* + * fifteens: + * Return number of fifteens in hand of n cards + */ +int +fifteens(hand, n) + register CARD hand[]; + int n; +{ + register int *sp, *np; + register int i; + register 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) + CARD h[]; + int n; +{ + register 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, tbl[]; + int n, sum; +{ + BOOLEAN got[RANKS]; + register 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) + CARD cb[], tnv; +{ + 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); +} diff --git a/games/cribbage/support.c b/games/cribbage/support.c new file mode 100644 index 0000000..a350004 --- /dev/null +++ b/games/cribbage/support.c @@ -0,0 +1,358 @@ +/*- + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)support.c 8.1 (Berkeley) 5/31/93"; +#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 */ +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) + CARD h[]; + int n, s; +{ + register 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) + CARD hand[]; + char *s; +{ + static char prompt[BUFSIZ]; + register int i, j; + register 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", expl); + do_wait(); + } else + win = chkscr(&pscore, i); + return (win); +} + +/* + * comphand: + * Handle scoring and displaying the computers hand + */ +int +comphand(h, s) + CARD h[]; + char *s; +{ + register 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[myturn], '.', myturn); + Lastscore[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) + register int score; + int peg; + BOOLEAN myturn; +{ + register 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]; + register 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) + CARD hand[]; + int n, sum; +{ + register 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) + CARD hand[]; + int n, s, t; +{ + register 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) + CARD h[]; + int n, v; +{ + register 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) + CARD h[]; + int n; +{ + register int i; + + for (i = 0; i < n; i++) + known[knownum++] = h[i]; +} |