mirror of
https://github.com/vattam/BSDGames.git
synced 2025-12-20 19:04:49 +00:00
Initial revision
git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
15
cribbage/Makefile.bsd
Normal file
15
cribbage/Makefile.bsd
Normal file
@@ -0,0 +1,15 @@
|
||||
# $NetBSD: Makefile,v 1.10 1998/02/18 22:37:31 jtc Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 5/31/93
|
||||
|
||||
PROG= cribbage
|
||||
DPADD= ${LIBCURSES}
|
||||
LDADD= -lcurses
|
||||
SRCS= extern.c crib.c cards.c instr.c io.c score.c support.c
|
||||
MAN= cribbage.6
|
||||
HIDEGAME=hidegame
|
||||
SETGIDGAME=yes
|
||||
FILES= cribbage.n
|
||||
FILESNAME=cribbage.instr
|
||||
FILESDIR=/usr/share/games
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
12
cribbage/Makefrag
Normal file
12
cribbage/Makefrag
Normal file
@@ -0,0 +1,12 @@
|
||||
# Makefrag - makefile fragment for cribbage
|
||||
|
||||
cribbage_DIRS := $(GAMESDIR) $(MAN6DIR) $(shell dirname $(CRIBBAGE_INSTRFILE))
|
||||
|
||||
cribbage_all: cribbage/cribbage cribbage/cribbage.n cribbage/cribbage.6
|
||||
|
||||
cribbage_install: cribbage_all
|
||||
$(INSTALL_SCORE_GAME) cribbage/cribbage $(INSTALL_PREFIX)$(GAMESDIR)/cribbage
|
||||
$(HIDE_GAME) cribbage
|
||||
$(INSTALL_DATA) cribbage/cribbage.n $(INSTALL_PREFIX)$(CRIBBAGE_INSTRFILE)
|
||||
$(INSTALL_SCORE_FILE) $(CRIBBAGE_SCOREFILE)
|
||||
$(INSTALL_MANUAL) cribbage/cribbage.6
|
||||
157
cribbage/cards.c
Normal file
157
cribbage/cards.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/* $NetBSD: cards.c,v 1.4 1997/10/10 12:32:22 lukem 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. 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)cards.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: cards.c,v 1.4 1997/10/10 12:32:22 lukem Exp $");
|
||||
#endif
|
||||
#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[];
|
||||
{
|
||||
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[];
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
* is_one returns TRUE if a is in the set of cards b
|
||||
*/
|
||||
int
|
||||
is_one(a, b, n)
|
||||
CARD a;
|
||||
const CARD b[];
|
||||
int n;
|
||||
{
|
||||
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;
|
||||
{
|
||||
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)
|
||||
CARD h[];
|
||||
int n;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
662
cribbage/crib.c
Normal file
662
cribbage/crib.c
Normal file
@@ -0,0 +1,662 @@
|
||||
/* $NetBSD: crib.c,v 1.10 1998/08/30 09:19:37 veego 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. 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.
|
||||
*/
|
||||
|
||||
#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.10 1998/08/30 09:19:37 veego 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 __P((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);
|
||||
|
||||
/* 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, 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 != 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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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? ");
|
||||
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? ");
|
||||
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);
|
||||
}
|
||||
187
cribbage/cribbage.6.in
Normal file
187
cribbage/cribbage.6.in
Normal file
@@ -0,0 +1,187 @@
|
||||
.\" $NetBSD: cribbage.6,v 1.5 1997/10/10 12:32:26 lukem 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. 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
|
||||
.\"
|
||||
.Dd May 31, 1993
|
||||
.Dt CRIBBAGE 6
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm cribbage
|
||||
.Nd the card game cribbage
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl eqr
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
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
|
||||
.Em According to Hoyle
|
||||
with
|
||||
.Xr more 1 .
|
||||
.Pp
|
||||
.Nm
|
||||
options include:
|
||||
.Bl -tag -width indent
|
||||
.It Fl 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.)
|
||||
.It Fl q
|
||||
Print a shorter form of all messages \- this is only recommended for
|
||||
users who have played the game without specifying this option.
|
||||
.It Fl r
|
||||
Instead of asking the player to cut the deck, the program will randomly
|
||||
cut the deck.
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
first asks the player whether he wishes to play a short game (
|
||||
.Dq once around ,
|
||||
to 61) or a long game (
|
||||
.Dq twice around ,
|
||||
to 121). A
|
||||
response of
|
||||
.Sq Ic 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:
|
||||
.Sq a ,
|
||||
.Sq 2 ,
|
||||
.Sq 3 ,
|
||||
.Sq 4 ,
|
||||
.Sq 5 ,
|
||||
.Sq 6 ,
|
||||
.Sq 7 ,
|
||||
.Sq 8 ,
|
||||
.Sq 9 ,
|
||||
.Sq t ,
|
||||
.Sq j ,
|
||||
.Sq q ,
|
||||
and
|
||||
.Sq k ,
|
||||
or alternatively, one of:
|
||||
.Sq ace ,
|
||||
.Sq two ,
|
||||
.Sq three ,
|
||||
.Sq four ,
|
||||
.Sq five ,
|
||||
.Sq six ,
|
||||
.Sq seven ,
|
||||
.Sq eight ,
|
||||
.Sq nine ,
|
||||
.Sq ten ,
|
||||
.Sq jack ,
|
||||
.Sq queen ,
|
||||
and
|
||||
.Sq king .
|
||||
Suits may be specified as:
|
||||
.Sq s ,
|
||||
.Sq h ,
|
||||
.Sq d ,
|
||||
and
|
||||
.Sq c ,
|
||||
or alternatively as:
|
||||
.Sq spades ,
|
||||
.Sq hearts ,
|
||||
.Sq diamonds ,
|
||||
and
|
||||
.Sq clubs .
|
||||
A card may be specified as:
|
||||
.Dq Ao rank Ac \ Aq suit ,
|
||||
or:
|
||||
.Dq Ao rank Ac of Aq 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
|
||||
.Dq 2H, 4D, 5C, 6H, JC, and KD
|
||||
and it was desired to discard the king of diamonds, any of
|
||||
the following could be typed:
|
||||
.Sq k ,
|
||||
.Sq king ,
|
||||
.Sq kd ,
|
||||
.Sq k d ,
|
||||
.Sq k of d ,
|
||||
.Sq king d ,
|
||||
.Sq king of d ,
|
||||
.Sq k diamonds ,
|
||||
.Sq k of diamonds ,
|
||||
.Sq king diamonds ,
|
||||
.Sq king of diamonds .
|
||||
.Sh FILES
|
||||
.Bl -tag -width @gamesdir@/cribbage -compact
|
||||
.It Pa @gamesdir@/cribbage
|
||||
.It Pa @cribbage_scorefile@
|
||||
.It Pa @cribbage_instrfile@
|
||||
.El
|
||||
.Sh AUTHORS
|
||||
Earl T. Cohen wrote the logic.
|
||||
Ken Arnold added the screen oriented interface.
|
||||
114
cribbage/cribbage.h
Normal file
114
cribbage/cribbage.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/* $NetBSD: cribbage.h,v 1.4 1998/09/13 15:27:27 hubertf 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. 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((const CARD [], CARD));
|
||||
int anymove __P((const CARD [], int, int));
|
||||
int anysumto __P((const CARD [], int, int, int));
|
||||
void bye __P((void));
|
||||
int cchose __P((const CARD [], int, int));
|
||||
void cdiscard __P((BOOLEAN));
|
||||
int chkscr __P((int *, int));
|
||||
int comphand __P((const CARD [], const 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((const 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((const CARD [], int, const char *));
|
||||
void instructions __P((void));
|
||||
int is_one __P((CARD, const CARD [], int));
|
||||
void makeboard __P((void));
|
||||
void makedeck __P((CARD []));
|
||||
void makeknown __P((const CARD [], int));
|
||||
void msg __P((const char *, ...));
|
||||
int msgcard __P((CARD, BOOLEAN));
|
||||
int msgcrd __P((CARD, BOOLEAN, const char *, BOOLEAN));
|
||||
int number __P((int, int, const char *));
|
||||
int numofval __P((const CARD [], int, int));
|
||||
int pairuns __P((const CARD [], int));
|
||||
int peg __P((BOOLEAN));
|
||||
int pegscore __P((CARD, const CARD [], int, int));
|
||||
int playhand __P((BOOLEAN));
|
||||
int plyrhand __P((const CARD [], const char *));
|
||||
void prcard __P((WINDOW *, int, int, CARD, BOOLEAN));
|
||||
void prcrib __P((BOOLEAN, BOOLEAN));
|
||||
void prhand __P((const 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)) __attribute__((__noreturn__));
|
||||
int score __P((BOOLEAN));
|
||||
int scorehand __P((const CARD [], CARD, int, BOOLEAN, BOOLEAN));
|
||||
void shuffle __P((CARD []));
|
||||
void sorthand __P((CARD [], int));
|
||||
void wait_for __P((int));
|
||||
226
cribbage/cribbage.n
Normal file
226
cribbage/cribbage.n
Normal file
@@ -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.
|
||||
59
cribbage/cribcur.h
Normal file
59
cribbage/cribcur.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* $NetBSD: cribcur.h,v 1.3 1995/03/21 15:08:48 cgd 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. 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 */
|
||||
87
cribbage/deck.h
Normal file
87
cribbage/deck.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* $NetBSD: deck.h,v 1.3 1995/03/21 15:08:49 cgd 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. 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;
|
||||
|
||||
75
cribbage/extern.c
Normal file
75
cribbage/extern.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* $NetBSD: extern.c,v 1.4 1997/10/10 12:32:29 lukem 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. 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.
|
||||
*/
|
||||
|
||||
#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.4 1997/10/10 12:32:29 lukem 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 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 */
|
||||
102
cribbage/instr.c
Normal file
102
cribbage/instr.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/* $NetBSD: instr.c,v 1.7 1997/10/11 02:44:31 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)instr.c 8.1 (Berkeley) 5/31/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: instr.c,v 1.7 1997/10/11 02:44:31 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <curses.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "deck.h"
|
||||
#include "cribbage.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
void
|
||||
instructions()
|
||||
{
|
||||
int pstat;
|
||||
int fd;
|
||||
pid_t pid;
|
||||
const char *path;
|
||||
|
||||
switch (pid = vfork()) {
|
||||
case -1:
|
||||
err(1, "vfork");
|
||||
case 0:
|
||||
/* Follow the same behaviour for pagers as defined in POSIX.2
|
||||
* for mailx and man. We only use a pager if stdout is
|
||||
* a terminal, and we pass the file on stdin to sh -c pager.
|
||||
*/
|
||||
if (!isatty(1))
|
||||
path = "cat";
|
||||
else {
|
||||
if (!(path = getenv("PAGER")) || (*path == 0))
|
||||
path = _PATH_MORE;
|
||||
}
|
||||
if ((fd = open(_PATH_INSTR, O_RDONLY)) == -1) {
|
||||
warn("open %s", _PATH_INSTR);
|
||||
_exit(1);
|
||||
}
|
||||
if (dup2(fd, 0) == -1) {
|
||||
warn("dup2");
|
||||
_exit(1);
|
||||
}
|
||||
execl("/bin/sh", "sh", "-c", path, NULL);
|
||||
warn("%s", "");
|
||||
_exit(1);
|
||||
default:
|
||||
do {
|
||||
pid = waitpid(pid, &pstat, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
if (pid == -1 || WEXITSTATUS(pstat))
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
633
cribbage/io.c
Normal file
633
cribbage/io.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/* $NetBSD: io.c,v 1.10 1997/10/10 12:32:32 lukem 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. 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.
|
||||
*/
|
||||
|
||||
#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.10 1997/10/10 12:32:32 lukem Exp $");
|
||||
#endif
|
||||
#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];
|
||||
|
||||
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 = 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 = getline()) || *p == '\0') {
|
||||
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 != '\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
|
||||
#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);
|
||||
Newpos = strlen(Msgbuf);
|
||||
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);
|
||||
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(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 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 *
|
||||
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
|
||||
rint(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');
|
||||
}
|
||||
40
cribbage/pathnames.h.in
Normal file
40
cribbage/pathnames.h.in
Normal file
@@ -0,0 +1,40 @@
|
||||
/* $NetBSD: pathnames.h,v 1.3 1995/03/21 15:08:56 cgd Exp $ */
|
||||
|
||||
/*-
|
||||
* 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 "@cribbage_instrfile@"
|
||||
#define _PATH_LOG "@cribbage_scorefile@"
|
||||
#define _PATH_MORE "@pager@"
|
||||
378
cribbage/score.c
Normal file
378
cribbage/score.c
Normal file
@@ -0,0 +1,378 @@
|
||||
/* $NetBSD: score.c,v 1.6 1998/08/30 09:19:37 veego 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. 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.
|
||||
*/
|
||||
|
||||
#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.6 1998/08/30 09:19:37 veego 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];
|
||||
|
||||
expl[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(expl, "His Nobs");
|
||||
}
|
||||
h[i] = hand[i];
|
||||
}
|
||||
|
||||
if (flag && n >= CINHAND) {
|
||||
if (do_explain && expl[0] != '\0')
|
||||
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] != '\0')
|
||||
strcat(expl, ", Four-flush");
|
||||
else
|
||||
strcpy(expl, "Four-flush");
|
||||
}
|
||||
}
|
||||
if (do_explain && expl[0] != '\0')
|
||||
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)
|
||||
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);
|
||||
}
|
||||
365
cribbage/support.c
Normal file
365
cribbage/support.c
Normal file
@@ -0,0 +1,365 @@
|
||||
/* $NetBSD: support.c,v 1.4 1997/10/10 12:32:36 lukem 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. 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.
|
||||
*/
|
||||
|
||||
#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.4 1997/10/10 12:32:36 lukem 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", expl);
|
||||
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];
|
||||
}
|
||||
Reference in New Issue
Block a user