[comp.sources.games] v08i023: choice - two handed trick-taking card game, Part02/02

billr@saab.CNA.TEK.COM (Bill Randle) (09/14/89)

Submitted-by: Scott Turner <srt@lanai.cs.ucla.edu>
Posting-number: Volume 8, Issue 23
Archive-name: choice/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:  defs.h instruct.c my_wgets.c my_wgets.h utils.c
# Wrapped by billr@saab on Thu Sep 14 09:46:47 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'defs.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'defs.h'\"
else
echo shar: Extracting \"'defs.h'\" \(1890 characters\)
sed "s/^X//" >'defs.h' <<'END_OF_FILE'
X/*
X *  defs.h
X *  Wed Sep 14 14:57:01 1988 -- Scott R. Turner
X *
X *  This file contains the definitions for Choice.
X *
X *  Choice uses an interesting data structure for a set of
X *  cards.  The data structure consists of a 4 X 13 array of
X *  integers.  Marking the integers can indicate either their
X *  presence (as in a hand held by a player) or their order
X *  (as in a deck).  Shuffling can be done by marking a deck
X *  in order and then exchanging two randomly selected cards
X *  a number of times.
X *
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <curses.h>
X
X/*  Constants */
X
X#define SPADES 0
X#define HEARTS 1
X#define DIAMONDS 2
X#define CLUBS 3
X
X#define JACK 11
X#define QUEEN 12
X#define KING 13
X#define ACE 14
X
X/*  Interface Values */
X
X#define REFRESHKEY 12
X#define SHOWKEY '!'
X#define DEBUGKEY '*'
X#define QUITKEY 'X'
X#define IOLINE1 11
X#define IOLINE2 12
X#define IOLINE3 13
X
X/*  Card Values */
X
X#define UNKNOWN 0
X#define MINE 1
X#define PLAYED 2
X#define HEPLAYED 3
X#define BURIED 4
X
X/*  Scorefile */
X
X#define SCOREFILE "/u/gs8/srt/.choice"
X
X
X/*  Data Definitions */
X
Xtypedef struct sdeck {
X  int top;                 /* Top card in deck */
X  int cards[4][15];        /* For convenience, 0 & 1 are ignored */
X} deckt;
X
Xtypedef struct splayer {
X  int tricks;              /* How many tricks player has taken */
X  int score;
X  int games;
X  int computer;            /* TRUE if the computer player. */
X  int whose, num;          /* Whose contract, num needed. */
X  int trump;               /* Trump suit. */
X  int shownout[4];         /* Shown out?  (for computer) */
X  int len[4];              /* Initial lengths. (for computer) */
X  int cards[4][15];        /* Player's holding. */
X} player;
X
Xextern deckt deck;
Xextern player players[2];
Xextern int lead, trump;
Xextern int debug;
X
Xstatic char suitchars[4] = {'S','H','D','C'};
Xstatic char honorchars[4] = {'J','Q','K','A'};
X
X 
END_OF_FILE
if test 1890 -ne `wc -c <'defs.h'`; then
    echo shar: \"'defs.h'\" unpacked with wrong size!
fi
# end of 'defs.h'
fi
if test -f 'instruct.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'instruct.c'\"
else
echo shar: Extracting \"'instruct.c'\" \(6774 characters\)
sed "s/^X//" >'instruct.c' <<'END_OF_FILE'
X/*
X * This program (called "Choice") is copyright 1989 to Scott R. Turner,
X * in both source code and executable form.  Permission is given to 
X * copy both the source code and the executable under the following
X * conditions:
X * 
X *   1. You may copy and distribute verbatim copies of Choice code as you
X * receive it, in any medium, provided that you conspicuously and
X * appropriately publish on each file a valid copyright notice such as
X * "Copyright (C) 1989 Scott R. Turner", and keep intact the copyright
X * and license notices on all files.  You may charge a distribution fee
X * for the physical act of transferring a copy, but that fee may not
X * exceed your actual costs in creating and delivering the copy.
X * 
X *   2. You may modify your copy or copies of Choice or any portion of it,
X * and copy and distribute such modifications under the terms of
X * Paragraph 1 above, provided that you also do the following:
X * 
X *     a) cause the modified files to carry prominent notices stating
X *     who last changed such files and the date of any change; and
X * 
X *     b) cause the whole of any work that you distribute or publish,
X *     that in whole or in part contains or is a derivative of Choice
X *     or any part thereof, to be licensed at no charge to all third
X *     parties on terms identical to those contained in this License
X *     Agreement (except that you may choose to grant more extensive
X *     warranty protection to third parties, at your option).
X *
X *   3. You may not copy, sublicense, distribute or transfer Choice
X * except as expressly provided under this License Agreement.  Any attempt
X * otherwise to copy, sublicense, distribute or transfer Choice is void and
X * your rights to use Choice under this License agreement shall be
X * automatically terminated.  However, parties who have received computer
X * software programs from you with this License Agreement will not have
X * their licenses terminated so long as such parties remain in full compliance.
X * 
X *   4.  Under no circumstances may you charge for copies of Choice, for copies
X * of any program containing code from Choice in whole or in part, or for 
X * any software package or collection of programs or code that contains Choice
X * in whole or part.
X *
X */
X
X/*
X *  instruct.c
X *  Mon Sep 19 11:01:18 1988 -- Scott Turner
X *
X *  instruct contains a routine for printing out how to play the
X *  game.
X *
X */
X#include "defs.h"
X
Xinstruct()
X{
X  clear();
X  move(0,0);
X  printw("                  The Game of Choice\n\n");
X  printw("  Choice is a two-handed trick-taking game with trump, similar\n");
X  printw("to Bridge, Spades and (in particular) two-handed Spades.\n\n");
X  printw("  In the first part of the game, the two players take turns drawing\n");
X  printw("one card from the top of the deck.  If the player likes the card, he\n");
X  printw("can choose to keep it (and the next card is discarded sight unseen).\n");
X  printw("If he doesn't want it, he discards it, and takes the next\n");
X  printw("card from the deck.  In this way, both players build up hands of\n");
X  printw("thirteen cards.\n\n");
X  printw("  In the second part of the game, the two players take turns bidding.\n");
X  printw("Each player bids the number of tricks he thinks he can win, if he is\n");
X  printw("allowed to name the trump suit.  Whoever bids the most tricks wins,\n");
X  printw("names the trump suit, and leads for the first trick.\n\n");
X  printw("  Whoever wins the first trick leads for the second trick, and so\n");
X  printw("on.\n\n");
X  move(24,0);
X  printw("---  Hit any key to continue ---");
X  refresh();
X  (void) getch();
X  clear();
X  move(0,0);
X  printw("                       Scoring\n\n");
X  printw("  The bidder scores ten times his bid if he makes, plus one point for\n");
X  printw("each overtrick.  The bidder scores negative ten times his bid if he\n");
X  printw("goes down.\n\n");
X  printw("  The winner is the first player to 250 points.\n\n");
X  printw("  Choice keeps track of the number of games you have won, and will\n");
X  printw("display your current standing at the end of each session.  You can also\n");
X  printw("display your score with the -s option.\n\n");
X  move(24,0);
X  printw("---  Hit any key to continue ---");
X  refresh();
X  (void) getch();
X  clear();
X  move(0,0);
X  printw("                   Using This Program\n\n");
X  printw("  This program is relatively simple to use.\n\n");
X  printw("  Use the 'y' and 'n' keys to answer yes/no questions such as\n");
X  printw("'Would you like the QS?'.\n\n");
X  printw("  When you are asked for a bid, simply type the number and hit a\n");
X  printw("carriage return.  A bid of 0 ends the bidding.\n\n");
X  printw("  To play a card from your hand type the rank of the card and possibly\n");
X  printw("its suit.  The program will try to differentiate as much as possible.\n");
X  printw("For instance, if you only have one '8' in your hand, typing an '8' will\n");
X  printw("play that card.\n\n");
X  printw("  Typing a ^L will redraw the screen and typing an 'X' will immediately\n");
X  printw("exit the program.\n\n");
X  move(24,0);
X  printw("---  Hit any key to continue ---");
X  refresh();
X  (void) getch();
X  clear();
X  move(0,0);
X  printw("                        Options\n\n");
X  printw("  Normally the computer bids using a rule-based strategy.  It isn't\n");
X  printw("very good, though you may find it challenging at first.  If Choice is\n");
X  printw("called with the -h option (for 'hard') it will play a more challenging\n");
X  printw("strategy.  Unfortunately, this strategy cheats a little - it looks at\n");
X  printw("your hand to determine a good bid.\n\n");
X  printw("  For people interested in modifying the program or developing new\n");
X  printw("strategies, there are several options which will help you collect statistics\n");
X  printw("and debug new strategies.  A look through the code will reveal these\n");
X  printw("options.\n\n");
X  move(24,0);
X  printw("---  Hit any key to continue ---");
X  refresh();
X  (void) getch();
X  clear();
X  move(0,0);
X  printw("                        Credits\n\n");
X  printw("  This program was designed and coded by Scott R. Turner (srt@cs.ucla.edu,\n");
X  printw("as of late 1989).\n\n");
X  printw("  Special thanks goes to John Reeves and Matthew Merzbacher, who helped\n");
X  printw("debug early versions of the program and suggested various improvements.\n\n");
X  printw("  Choice was inspired by Leslie Kim, a programmer and otherwise interesting\n");
X  printw("person.  Her electronic address is kim@aerospace.aero.org, and if you\n");
X  printw("enjoy using this program you might want to drop her a short note.\n\n");
X  move(24,0);
X  printw("--- Hit any key to continue ---");
X  refresh();
X  (void) getch();
X  clear();
X};
X
X  
X  
X
X  
X
X
X
X
X 
END_OF_FILE
if test 6774 -ne `wc -c <'instruct.c'`; then
    echo shar: \"'instruct.c'\" unpacked with wrong size!
fi
# end of 'instruct.c'
fi
if test -f 'my_wgets.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'my_wgets.c'\"
else
echo shar: Extracting \"'my_wgets.c'\" \(4384 characters\)
sed "s/^X//" >'my_wgets.c' <<'END_OF_FILE'
X/*
X * A possible replacement for curses' wgetstr(). Allows
X * line editing as in csh. 
X * Recognizes the erase, kill chars, word deleting.
X *
X * By Hung Le (mott@ucscb.ucsc.edu  ...!ucbvax!ucscc!ucscb!mott)
X * History:
X *	01/18/89 - Initial version 
X *	03/20/89 - Add control-w to delete word
X *  05/17/89 - add option to return immediately or to bell()
X *			when buffer is full.
X *
X * Release to Public Domain 
X */
X#include <curses.h>
X#ifdef UNIX
X#include <sys/ioctl.h>
X#include <sgtty.h>
X#endif UNIX
X
X#define STD_INPUT 0		/* standard input */
X#define NEWLINE '\n'
X#define SPACE ' '
X/* default for erase and kill characters */
X#define ERASE '\010'
X#define KILL '\025'
X#define WORD '\027'
X
X/* You bugger !!! you did something wrong */
X#define bell() printf("%c", '\007')
X
X/*
X * my_wgetstr(WINDOW *win, char *str, int size, int ret)
X *	win: the concerned window
X * 	str: buffer holding input
X *	size: (size -1) is the maximum chars to get
X *	ret: flag indicating what to do when (size -1) is reached
X *		0: ring bell()
X *		1: returns
X *		two macros are defined in "my_wgetstr.h" as RET=1 and NO_RET=0
X *
X * works same as wgetstr() in curses but allows editing.
X * Recognizes the erase character and the kill character and
X * WORD as the word deleting char.
X * Will try to get the erase and kill char from the terminal setting.
X * If failed, will use the default ERASE and KILL definitions.
X * Word char is set to WORD.
X *
X * DOES NOT check for illegal scrolling.
X * Returns
X *	. when received a new line character 
X *	. if ( (strlen(str) == (size - 1)) and (ret) )		
X *
X * str[size - 1] must be set to '\0' to end the string properly 
X * so my_wgetstr(errwin, str, 8) will get at most 7 characters.
X *
X * Returned value is the number of chars read. 
X */
X
Xmy_wgetstr(win, str, size, ret)
XWINDOW *win;
Xchar *str;
Xint size;
Xint ret;
X{
X#ifdef UNIX
X	struct sgttyb ttyb;
X#endif 	
X	char erase_char, kill_char;
X	register int x_pos, y_pos, index, in;
X
X#ifdef UNIX
X	if (ioctl(STD_INPUT, TIOCGETP, &ttyb) == -1)
X	{
X#endif UNIX	
X		/*
X		 * failed to get terminal setting. Let's use the default
X		 * ERASE and KILL 
X		 */
X		erase_char = ERASE;
X		kill_char = KILL;
X#ifdef UNIX		
X	}
X	else
X	{
X		erase_char = ttyb.sg_erase;
X		kill_char = ttyb.sg_kill;
X	}
X#endif UNIX	
X
X	/*
X	 * since we are going to set noecho() and crmode() let's be safe and
X	 * save the current tty 
X	 */
X	savetty();
X	noecho();
X	crmode();
X
X	/* get current position */
X	getyx(win, y_pos, x_pos);
X	/* intializing */
X	index = 0;
X	str[index] = '\0';
X
X	/* while input char is not NEWLINE */
X	while ((in = getch() & 0177) != NEWLINE)
X	{
X		/* if buffer is full (size -1) */
X		if (index >= size - 1)
X			if (ret)/* return flag set, return immediately */
X				break;
X			else	/* allows editing chars to pass through */
X			if ((in != erase_char) && (in != kill_char) && (in != WORD))
X			{
X				/* warns user that buffer is full */
X				bell();
X				continue;
X			}
X
X		if (in == erase_char)	/* ERASING */
X		{
X			if (index > 0)
X			{
X				mvwaddch(win, y_pos, --x_pos, SPACE);
X				str[--index] = SPACE;
X				wmove(win, y_pos, x_pos);
X			}
X			else
X				bell();
X		}
X		else
X		if (in == kill_char)	/* KILLING */
X		{
X			if (index > 0)
X				while (index > 0)
X				{
X					mvwaddch(win, y_pos, --x_pos, SPACE);
X					str[--index] = SPACE;
X					wmove(win, y_pos, x_pos);
X				}
X			else
X				bell();
X		}
X		else
X		if (in == WORD)	/* WORD DELETING */
X		{
X			if (index > 0)
X			{
X				/* throw away all spaces */
X				while ((index > 0) && (str[index - 1] == SPACE))
X				{
X					mvwaddch(win, y_pos, --x_pos, SPACE);
X					str[--index] = SPACE;
X					wmove(win, y_pos, x_pos);
X				}
X				/* move back until see another space */
X				while ((index > 0) && (str[index - 1] != SPACE))
X				{
X					mvwaddch(win, y_pos, --x_pos, SPACE);
X					str[--index] = SPACE;
X					wmove(win, y_pos, x_pos);
X				}
X			}
X			else
X				bell();
X		}
X		else
X		{
X			mvwaddch(win, y_pos, x_pos++, in);
X			str[index++] = in;
X		}
X		/* show result */
X		wrefresh(win);
X	}
X	/* ends the string properly */
X	str[index] = '\0';
X	/* restore the tty */
X	resetty();
X	/* returns number of chars read */
X	return (index);
X}
X
X/*
X *  Getint
X *
X *  Just a little function for Hotel that gets an integer
X *  using Le's wgetstr.
X *
X *
X */
X
X#include "my_wgets.h"
Xint getint()
X{
X  int x,y,num,ans;
X  char get[80];
X  
X  num = 0;
X  do {
X    my_getstr(get,80,0);
X    num = sscanf(get,"%d",&ans);
X  } while (num == 0);
X  return(ans);
X};
END_OF_FILE
if test 4384 -ne `wc -c <'my_wgets.c'`; then
    echo shar: \"'my_wgets.c'\" unpacked with wrong size!
fi
# end of 'my_wgets.c'
fi
if test -f 'my_wgets.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'my_wgets.h'\"
else
echo shar: Extracting \"'my_wgets.h'\" \(421 characters\)
sed "s/^X//" >'my_wgets.h' <<'END_OF_FILE'
X/*
X * A possible replacement for curses' wgetstr(). Allows
X * limited editing. Recognizes the erase and kill chars.
X *
X * By Hung Le (mott@ucscb.ucsc.edu  ...!ucbvax!ucscc!ucscb!mott)
X * History:
X *	05/18/89 - Initial version 
X *
X * Release to Public Domain 
X */
X
X/* following the curses's convention */
X#define my_getstr(str,size,ret) my_wgetstr(stdscr,str,size,ret)
X#define RET 1
X#define NO_RET 0
Xextern int getint();
X
END_OF_FILE
if test 421 -ne `wc -c <'my_wgets.h'`; then
    echo shar: \"'my_wgets.h'\" unpacked with wrong size!
fi
# end of 'my_wgets.h'
fi
if test -f 'utils.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utils.c'\"
else
echo shar: Extracting \"'utils.c'\" \(5660 characters\)
sed "s/^X//" >'utils.c' <<'END_OF_FILE'
X/*
X * This program (called "Choice") is copyright 1989 to Scott R. Turner,
X * in both source code and executable form.  Permission is given to 
X * copy both the source code and the executable under the following
X * conditions:
X * 
X *   1. You may copy and distribute verbatim copies of Choice code as you
X * receive it, in any medium, provided that you conspicuously and
X * appropriately publish on each file a valid copyright notice such as
X * "Copyright (C) 1989 Scott R. Turner", and keep intact the copyright
X * and license notices on all files.  You may charge a distribution fee
X * for the physical act of transferring a copy, but that fee may not
X * exceed your actual costs in creating and delivering the copy.
X * 
X *   2. You may modify your copy or copies of Choice or any portion of it,
X * and copy and distribute such modifications under the terms of
X * Paragraph 1 above, provided that you also do the following:
X * 
X *     a) cause the modified files to carry prominent notices stating
X *     who last changed such files and the date of any change; and
X * 
X *     b) cause the whole of any work that you distribute or publish,
X *     that in whole or in part contains or is a derivative of Choice
X *     or any part thereof, to be licensed at no charge to all third
X *     parties on terms identical to those contained in this License
X *     Agreement (except that you may choose to grant more extensive
X *     warranty protection to third parties, at your option).
X *
X *   3. You may not copy, sublicense, distribute or transfer Choice
X * except as expressly provided under this License Agreement.  Any attempt
X * otherwise to copy, sublicense, distribute or transfer Choice is void and
X * your rights to use Choice under this License agreement shall be
X * automatically terminated.  However, parties who have received computer
X * software programs from you with this License Agreement will not have
X * their licenses terminated so long as such parties remain in full compliance.
X * 
X *   4.  Under no circumstances may you charge for copies of Choice, for copies
X * of any program containing code from Choice in whole or in part, or for 
X * any software package or collection of programs or code that contains Choice
X * in whole or part.
X *
X */
X
X/*
X *  utils.c
X *  Wed Sep 14 15:13:40 1988 -- Scott R. Turner
X *
X *  This file contains some of the utility functions that set up
X *  the deck, shuffle the deck, get the next card from the deck, and
X *  so on.
X *
X */
X#include "defs.h"
X#ifdef UNIX
Xextern long random();
X#else
X#include <stdlib.h>
X#include <time.h>
X#endif
X/*
X *  randum is the standard 1-n random integer generator.
X *
X */
X
Xint randum(n)
X     int n;
X{
X#ifdef UNIX
X  return((random() % n) + 1);
X#else
X  return((rand() % n) + 1);
X#endif
X};
X
X/*
X *  shuffle
X *
X *  This function intializes the deck and then shuffles it.
X *
X */
X
Xshuffle(deck)
X     deckt *deck;
X{
X  int suit,rank,i,tmp;
X  extern long time();
X
X  (*deck).top = 1;
X  for(suit=0;suit<=3;suit++)
X    for(rank=2;rank<=14;rank++)
X      (*deck).cards[suit][rank] = (suit*13)+(rank-1);
X
X  /*  Now shuffle the deck by exchanging two cards some
X   *  number of times.
X   */
X
X  for(i=1;i<=500;i++)
X    {
X      suit = randum(4) - 1;
X      rank = randum(13) + 1;
X      tmp = (*deck).cards[suit][rank];
X      (*deck).cards[suit][rank] = (*deck).cards[0][2];
X      (*deck).cards[0][2] = tmp;
X    };
X};
X
X/*
X *  print_hand
X *
X *  A little debug function to print out a hand.
X *
X */
X
Xprint_hand(p,line)
X     player *p;
X     int line;
X{
X  int suit,rank;
X
X  for(suit=0;suit<=3;suit++)
X    {
X      move(line,0);
X      printw("                               ");
X      move(line++,0);
X      printw("%c: ",suitchars[suit]);
X      for(rank=14;rank>=2;rank--)
X	if ((*p).cards[suit][rank] == MINE) {
X	  if (rank <= 10) {
X	    printw("%d ",rank);
X	  } else {
X	    printw("%c ",honorchars[rank - JACK]);
X	  };
X	};
X    };
X};
X
X/*
X *  do_header fills the top part of the screen with
X *  the header.
X *
X */
X
Xdo_header()
X{
X  /* Title */
X  move(0,28);
X  printw("C*H*O*I*C*E");
X
X  /* Game info line. */
X
X  move(2,37);
X  printw("Trump:     Contract:    ");
X  /*      789012345678901234567890   */
X  /*      3  4         5           */
X
X  move(4,50);
X  printw("You        Me");
X  move(5,45);
X  printw("----------+----------");
X  move(6,37);
X  printw("Tricks");
X  move(7,37);
X  printw("Score");
X  move(8,37);
X  printw("Games");
X  
X};
X
X/*
X *  Update the score section of the board.
X *
X */
X
Xupdate_scores()
X{
X  move(6,43);
X  clrtoeol();
X  move(6,51);
X  printw("%d",players[0].tricks);
X  move(6,61);
X  printw("%d",players[1].tricks);
X  move(7,42);
X  clrtoeol();
X  move(7,51);
X  printw("%d",players[0].score);
X  move(7,61);
X  printw("%d",players[1].score);
X  move(8,42);
X  clrtoeol();
X  move(8,51);
X  printw("%d",players[0].games);
X  move(8,61);
X  printw("%d",players[1].games);
X};
X
X/*
X * get_card
X *
X * This function returns the Ith card of a deck.
X *
X */
X
Xget_card(i,deck,rank,suit)
X     int i, *rank, *suit;
X     deckt *deck;
X{
X  int j,k;
X
X  for(j=0;j<=3;j++)
X    for(k=2;k<=14;k++)
X      if((*deck).cards[j][k] == i) {
X	*suit = j;
X	*rank = k;
X	return(0);
X      };
X};
X
X/*
X *  init_player
X *
X *  This function initializes the player data structure.
X *
X */
X
Xinit_player(p)
X     player *p;
X{
X  int suit,rank;
X  
X  (*p).tricks = 0;
X  (*p).trump = -1;
X  for(suit=0;suit<=3;suit++)
X    for(rank=2;rank<=14;rank++)
X      (*p).cards[suit][rank] = 0;
X};
X
Xstatic char cardstr[5];
X
Xchar *card_string(suit,rank)
X     int rank,suit;
X{
X  if (rank < JACK) {
X    sprintf(cardstr,"%d%c",rank,suitchars[suit]);
X  } else {
X    sprintf(cardstr,"%c%c",honorchars[rank - JACK],suitchars[suit]);
X  };
X  return(cardstr);
X};
X  
X     
X  
END_OF_FILE
if test 5660 -ne `wc -c <'utils.c'`; then
    echo shar: \"'utils.c'\" unpacked with wrong size!
fi
# end of 'utils.c'
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