[comp.sources.games] v08i070: yahtzee2 - curses based game of yahtzee

billr@saab.CNA.TEK.COM (Bill Randle) (11/23/89)

Submitted-by: Stacey Campbell <staceyc@uunet.uu.net>
Posting-number: Volume 8, Issue 70
Archive-name: yahtzee2/Part02

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  Makefile eval.c help.c port.h yahtzee.6 yz_macros.h
#   yz_types.h
# Wrapped by billr@saab on Wed Nov 22 14:54:30 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(883 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Makefile for Yahtzee 2.1
X#
X
X# A path for the high score file
XHS_FILE="$(HOME)/lib/yahtzee2.hs"
X
X# system dependent flags
X
X# Xenix - some Xenix folks may have to add -lx
XLDLIBS= -ltinfo -lm
XLDOPT= -O
XCCOPT= -O
XCPFLAGS= -DM_TERMINFO
X
X# System 5
X# LDLIBS= -lcurses -lm
X# LDOPT= -O
X# CCOPT= -O
X
X# BSD, SunOS 3.5
X# LDLIBS= -lcurses -ltermlib -lm
X# LDOPT= -O
X# CCOPT= -O
X
XSRC= admin.c book.c comp.c eval.c help.c main.c score.c scr.c
XOBJS= help.o main.o scr.o admin.o comp.o eval.o book.o score.o
XINCS= yz_consts.h yz_costs.h yz_funcs.h yz_macros.h yz_types.h port.h
XEXE= yahtzee
XPFLAGS= -DYZ_HS_FILE='$(HS_FILE)' $(CPFLAGS)
XCFLAGS= $(PFLAGS) $(CCOPT)
X
Xall: $(EXE)
X
X$(EXE): $(OBJS)
X	cc $(LDOPT) -o $(EXE) $(OBJS) $(LDLIBS)
X
Xcomp.o: yz_costs.h
X
Xlint:
X	lint -u $(PFLAGS) $(SRC) > lint.out
X
Xclean:
X	rm -f $(OBJS) $(EXE)
X
Xshar:
X	xshar README Makefile $(EXE).6 $(SRC) $(INCS) > $(EXE).shar
END_OF_FILE
if test 883 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'eval.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'eval.c'\"
else
echo shar: Extracting \"'eval.c'\" \(3207 characters\)
sed "s/^X//" >'eval.c' <<'END_OF_FILE'
X#include <curses.h>
X#include "yz_consts.h"
X#include "yz_types.h"
X#include "yz_macros.h"
X#include "yz_funcs.h"
X
Xvoid EvOne2Six(), EvOne2Six(), EvOne2Six(), EvOne2Six(), EvOne2Six(),
X    EvOne2Six(), EvOaK(), EvFullHouse(), EvStraight(), EvYahtzee(), EvChance();
X
Xstatic int StraightScore[] = {SC_SMALL_STRAIGHT, SC_LARGE_STRAIGHT};
X
Xvoid Eval(cat, dice, score, bonus, bonus63, players, player)
X
Xint cat;
Xdice_t dice[YZ_DICE];
Xint *score;
Xint *bonus;
Xint *bonus63;
Xplayers_t players[YZ_PLAYERS_MAX];
Xint player;
X
X	{
X	int yz_score = 0;
X	int total63;
X	static void (*eval_funs[])() = {
X	    EvOne2Six, EvOne2Six, EvOne2Six, EvOne2Six, EvOne2Six, EvOne2Six,
X	    EvOaK, EvOaK, EvFullHouse, EvStraight, EvStraight,
X	    EvYahtzee, EvChance};
X
X	*bonus63 = *bonus = *score = 0;
X	if (cat != YZ_CAT && players[player].score[YZ_CAT])
X		{
X		EvYahtzee(dice, &yz_score, cat);
X		if (yz_score == SC_YAHTZEE)
X			{
X			*bonus = SC_YAHTZEE_BONUS;
X			if (cat == YZ_LG_CAT || cat == YZ_SM_CAT)
X				{
X				cat -= SC_STR_SCORE_NORM + SC_STRAIGHT_NORMAL;
X				*score = StraightScore[cat];
X				return;
X				}
X			}
X		}
X	(*eval_funs[cat])(dice, score, cat);
X	if (cat <= YZ_CAT63 && ! players[player].bonus63)
X		{
X		total63 = players[player].total63 + *score;
X		if (total63 >= YZ_63BONUS_LIMIT)
X			*bonus63 = YZ_63BONUS_VAL;
X		}
X	}
X
Xstatic void EvOne2Six(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	int i;
X	int bump;
X
X	bump = cat + 1;
X	for (i = 0; i < YZ_DICE; ++i)
X		if (dice[i].dice == cat)
X			*score += bump;
X	}
X
Xstatic void EvOaK(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	int i;
X	int reps[YZ_DICE_MAX];
X
X	cat -= SC_OAK_NORMAL;
X	for (i = 0; i < YZ_DICE_MAX; ++i)
X		reps[i] = 0;
X	for (i = 0; i < YZ_DICE; ++i)
X		if (++reps[dice[i].dice] >= cat)
X			{
X			EvChance(dice, score, cat);
X			return;
X			}
X	}
X
Xstatic void EvFullHouse(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	int new_dice[YZ_DICE];
X	int i;
X
X	for (i = 0; i < YZ_DICE; ++i)
X		new_dice[i] = dice[i].dice;
X	DICE_SORT(new_dice);
X	if ((new_dice[0] == new_dice[1] && new_dice[1] == new_dice[2] &&
X	     new_dice[3] == new_dice[4]) ||
X	    (new_dice[2] == new_dice[3] && new_dice[3] == new_dice[4] &&
X	     new_dice[0] == new_dice[1]))
X		*score = SC_FULL_HOUSE;
X	}
X
Xstatic void EvStraight(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	int new_dice[YZ_DICE];
X	int i, j, run, conseq;
X	int next;
X
X	cat -= SC_STRAIGHT_NORMAL;
X	for (i = 0; i < YZ_DICE; ++i)
X		new_dice[i] = dice[i].dice;
X	DICE_SORT(new_dice);
X	for (i = 0; i < YZ_DICE - 1; i = j)
X		{
X		j = i;
X		run = 0;
X		do	{
X			next = j + 1;
X			if (conseq = new_dice[j] + 1 == new_dice[next])
X				++run;
X			if (! conseq)
X				conseq = new_dice[j] == new_dice[next];
X			++j;
X			} while (conseq && j < YZ_DICE - 1);
X		if (run >= cat)
X			{
X			*score = StraightScore[cat - SC_STR_SCORE_NORM];
X			return;
X			}
X		}
X	}
X
Xstatic void EvYahtzee(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	EvOaK(dice, score, YZ_DICE + SC_OAK_NORMAL);
X	if (*score)
X		*score = SC_YAHTZEE;
X	}
X
Xstatic void EvChance(dice, score, cat)
X
Xdice_t dice[YZ_DICE];
Xint *score;
Xint cat;
X
X	{
X	int i;
X
X	for (i = 0; i < YZ_DICE; ++i)
X		*score += dice[i].dice + 1;
X	}
END_OF_FILE
if test 3207 -ne `wc -c <'eval.c'`; then
    echo shar: \"'eval.c'\" unpacked with wrong size!
fi
# end of 'eval.c'
fi
if test -f 'help.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'help.c'\"
else
echo shar: Extracting \"'help.c'\" \(2802 characters\)
sed "s/^X//" >'help.c' <<'END_OF_FILE'
X#include <curses.h>
X#include "yz_consts.h"
X#include "yz_types.h"
X#include "yz_macros.h"
X#include "yz_funcs.h"
X
Xstatic char *Also[] = {
X	"Also press:",
X	"   '?'  - for help any time",
X	"   's'  - current scores",
X	"   'b'  - display rules",
X	"   '^L' - redraw current screen",
X	"   '!'  - to fork shell",
X	"   'q'  - to quit"};
X
Xstatic char Help[HLP_LAST_VALID + 1][YZ_HLP_LINES][YZ_HLP_COLS] = {
X	{"Player Count",
X	"Input the number of players,",
X	"maximum is six, minimum is one."},
X	{"Continue",
X	"Press:",
X	"    'y'  - to play another game.",
X	"    'n'  - to exit yahtzee."},
X	{"Player Selection",
X	"Select which players will be human",
X	"and which will be simulated.",
X	"Press:",
X	"  space  - to toggle human/computer",
X	"    'j'  - to move cursor down",
X	"    'k'  - to move cursor up",
X	"    'n'  - to change name",
X	" return  - to start game"},
X	{"Name Input",
X	"Type in an alphanumeric string,",
X	"then press return."},
X	{"Holding Dice",
X	"Stop dice from being rolled.",
X	"Press:",
X	"     ' '  - toggle hold on die",
X	"'1'..'5'  - toggle hold on die N",
X	"     'l'  - move cursor right",
X	"     'h'  - move cursor left",
X	"     'r'  - computer recommendation",
X        "     'a'  - hold all dice",
X	"     'o'  - order dice",
X	"     't'  - toggle all dice",
X	"Press return when finished."},
X	{"Category Selection",
X	"Select the desired category by",
X	"moving cursor next to category",
X	"and pressing return.",
X	"Press:",
X	"    'j'  - to move cursor down",
X	"    'k'  - to move cursor up",
X	"    'r'  - computer recommendation",
X	" return  - select current category"},
X	{"Rules",
X	"These are the rules for Yahtzee",
X	"(also known as dice poker).",
X	"Press:",
X	"    'm'  - for next page",
X	"    'b'  - for previous page",
X	"    'g'  - exit rule display"},
X	{"High Score",
X	"This is the current high score file."},
X	{"Help",
X	"Exit the help window by pressing",
X	"space."}};
X
Xvoid HelpOut(old_win, hlp_no)
X
XWINDOW *old_win;
Xint hlp_no;
X
X	{
X	WINDOW *win;
X	int ch;
X	int len;
X	int i, j;
X	char msg[YZ_STR_MAX];
X
X	if (hlp_no > HLP_LAST_VALID || hlp_no == HLP_NONE)
X		{
X		PopError(old_win, "No help available");
X		return;
X		}
X	win = GrabWindow(old_win, YZ_HLP_LINES + 2, YZ_HLP_COLS + 2, 0, 32);
X	sprintf(msg, "Help - %s", Help[hlp_no][0]);
X	len = strlen(msg);
X	wstandout(win);
X	mvwaddstr(win, 1, (YZ_HLP_COLS + 2 - len) / 2, msg);
X	wstandend(win);
X	i = 1;
X	while (Help[hlp_no][i][0])
X		{
X		mvwaddstr(win, i + 2, 2, Help[hlp_no][i]);
X		++i;
X		}
X	for (j = 0; j < sizeof(Also) / sizeof(Also[0]); ++j)
X		mvwaddstr(win, i + 3 + j, 2, Also[j]);
X	mvwaddstr(win, YZ_HLP_LINES, 1, "--press space--");
X#ifndef SYS5_3_CURSES
X	wrefresh(win);
X#endif
X	while ((ch = wgetch(win)) != ' ')
X		ExtraCheck(win, ch, HLP_HLP);
X	mvwaddstr(win, YZ_HLP_LINES, 1, "               ");
X	wrefresh(win);
X	DropWindow(old_win, win);
X	}
END_OF_FILE
if test 2802 -ne `wc -c <'help.c'`; then
    echo shar: \"'help.c'\" unpacked with wrong size!
fi
# end of 'help.c'
fi
if test -f 'port.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'port.h'\"
else
echo shar: Extracting \"'port.h'\" \(1260 characters\)
sed "s/^X//" >'port.h' <<'END_OF_FILE'
X/* Establish curses version and random number generator */
X
X#ifndef ACS_PLUS                            /* must not be System 5.3 curses */
X#ifdef A_DIM                                       /* probably System 5.[12] */
X#define SYS5_2_CURSES
X#else                                                 /* probably BSD curses */
X#define BSD_CURSES
X#endif
X#else
X#define SYS5_3_CURSES
X#endif
X
X#ifndef BSD_CURSES
X#include <term.h>
X#endif
X
X#ifdef BSD_CURSES
X#define A_DIM A_STANDOUT           /* this works for BSD curses on Xenix 2.3 */
X#define flushinp()
X#define resetterm() system("stty intr '^c' erase '^?' echo")
X#define flash() putchar(7)
X#ifdef sun
X#define wattron(win, attr) wstandout(win)
X#define wattroff(win, attr) wstandend(win)
X#else
X#define cbreak crmode
X#endif
X#endif
X
X#ifndef SYS5_3_CURSES
X#define ACS_HLINE '-'
X#define ACS_VLINE '|'
X#define ACS_URCORNER '.'
X#define ACS_ULCORNER '.'
X#define ACS_LLCORNER '`'
X#define ACS_LRCORNER '\''
X#endif
X
X#if defined(SYS5_2_CURSES) || defined(BSD_CURSES)
X#define box(win, a, b) BSDbox(win)
X#endif
X
X#if defined(BSD_CURSES) && ! defined(sun)
X#define YZ_CR '\r'
X#else
X#define YZ_CR '\n'
X#endif
X
X#if defined(BSD_RANDOM) || (defined(BSD_CURSES) && ! defined(M_XENIX))
X#define lrand48 random
X#define srand48 srandom
X#endif
END_OF_FILE
if test 1260 -ne `wc -c <'port.h'`; then
    echo shar: \"'port.h'\" unpacked with wrong size!
fi
# end of 'port.h'
fi
if test -f 'yahtzee.6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'yahtzee.6'\"
else
echo shar: Extracting \"'yahtzee.6'\" \(1059 characters\)
sed "s/^X//" >'yahtzee.6' <<'END_OF_FILE'
X.TH Yahtzee 6l
X.SH NAME
Xyahtzee \- the game of Yahtzee
X.SH SYNOPSIS
X.B yahtzee
X.B [\-nshfd]
X.SH DESCRIPTION
X.I Yahtzee
Xis a computer simulation of the game of the same name.
XThis version of
X.I Yahtzee
Xallows up to six players, where
Xplayers can be either users at the same terminal
Xor a computer simulation of a player.
X.PP
XFull on\-line help is available at all times by pressing
Xthe question mark character. If you are unfamiliar with
Xthe rules a rule book is also available at all times
Xby pressing the 'b' key.
X.PP
XOptions are:
X.TP
X.B  \-n
Xplay
X.I Yahtzee
Xnon-stop, good if all players are computer simulations
X.TP
X.B  \-s
Xdisplay the high score file
X.TP
X.B  \-h
Xgive command line options
X.TP
X.B  \-f
Xdon't sleep between simulation plays
X.TP
X.B  \-d
Xdon't use the dim mode of the terminal (System 5)
X.PP
XAt the end of each game the high score file is updated if necessary.
X.SH BUGS
XUnknown, but please send bug problems to {uunet,ucscc,decwrl,sun}!sco!staceyc
Xor staceyc@sco.com.
X.SH AUTHOR
XStacey Campbell \- Santa Cruz, California, USA \- November 1989
END_OF_FILE
if test 1059 -ne `wc -c <'yahtzee.6'`; then
    echo shar: \"'yahtzee.6'\" unpacked with wrong size!
fi
# end of 'yahtzee.6'
fi
if test -f 'yz_macros.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'yz_macros.h'\"
else
echo shar: Extracting \"'yz_macros.h'\" \(1102 characters\)
sed "s/^X//" >'yz_macros.h' <<'END_OF_FILE'
X#define ROLL_DICE(dice_struct) \
X	{ \
X	int i; \
X	extern long lrand48(); \
X	for (i = 0; i < YZ_DICE; ++i) \
X		if (! (dice_struct)[i].hold) \
X			(dice_struct)[i].dice = lrand48() % YZ_DICE_MAX; \
X	}
X
X#define CLEAR_HOLD(dice) \
X	{ \
X	int i; \
X	for (i = 0; i < YZ_DICE; ++i) \
X		(dice)[i].hold = 0; \
X	}
X
X#define DICE_SORT(dice) GEN_SORT(dice, >)
X#define RDICE_SORT(dice) GEN_SORT(dice, <)
X#define SWAP(a, b, tmp) ((tmp) = (a), (a) = (b), (b) = (tmp))
X
X#define GEN_SORT(dice, order) \
X	{ \
X	int i, j; \
X	int tmp; \
X	for (i = 0; i < YZ_DICE; ++i) \
X		for (j = i; j < YZ_DICE; ++j) \
X			if ((dice)[i] order (dice)[j]) \
X				SWAP((dice)[i], (dice)[j], tmp); \
X	}
X
X#define DSTRUCT_SORT(d) \
X	{ \
X	int i, j; \
X	dice_t tmp; \
X	for (i = 0; i < YZ_DICE; ++i) \
X		for (j = i; j < YZ_DICE; ++j) \
X			if ((d)[i].dice > (d)[j].dice) \
X				SWAP((d)[i], (d)[j], tmp); \
X	}
X
X#define YZ_SIDE(str) (sizeof(YZ_LG_STRAIGHT) - strlen(str) - 1)
X
X#define DICEATTRON(win, dim) ((dim) ? wattron(win, A_STANDOUT) : wattron(win, \
X	A_DIM))
X#define DICEATTROFF(win, dim) ((dim) ? wattroff(win, A_STANDOUT) : \
X	wattroff(win, A_DIM))
END_OF_FILE
if test 1102 -ne `wc -c <'yz_macros.h'`; then
    echo shar: \"'yz_macros.h'\" unpacked with wrong size!
fi
# end of 'yz_macros.h'
fi
if test -f 'yz_types.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'yz_types.h'\"
else
echo shar: Extracting \"'yz_types.h'\" \(317 characters\)
sed "s/^X//" >'yz_types.h' <<'END_OF_FILE'
Xtypedef struct players_t {
X	int computer;
X	int score[YZ_CAT_COUNT];
X	int bonus;
X	int bonus63;
X	int total63;
X	int total;
X	int used[YZ_CAT_COUNT];
X	char name[YZ_NAME_MAX];
X	} players_t;
X
Xtypedef struct dice_t {
X	int dice;
X	int hold;
X	} dice_t;
X
Xtypedef struct score_t {
X	char name[YZ_NAME_MAX];
X	int score;
X	} score_t;
END_OF_FILE
if test 317 -ne `wc -c <'yz_types.h'`; then
    echo shar: \"'yz_types.h'\" unpacked with wrong size!
fi
# end of 'yz_types.h'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0