[comp.sources.games] v02i030: sol2 - solitaire games

games-request@tekred.TEK.COM (08/05/87)

Submitted by: allbery%ncoast.UUCP@cwruecmp.UUCP (Brandon S. Allbery)
Comp.sources.games: Volume 2, Issue 30
Archive-name: sol2

	[From the author...	-br]

[[I've done some work on the solitaire games posted to this newsgroup in late
July.  Included below is a "shar" of the modified sources.  (The linting made
the diffs bigger than the originals.)

Summary of changes to the programs:

(1) Fixed a bug in getting the backspace character from the termcap.
(2) Added code for System III and System V, and derivatives thereof, for the
    terminal I/O library used by these systems.
(3) Added code to make ^Z work in these games even on systems without job
    control; instead of returning to the parent shell, you get a subshell.
    (This is independent of the terminal stuff, as I know of BSD lookalikes
    that don't have job control (Pixel) and System V's that have job control
    (Callan).)
(4) Changed the gettimeofday() to a localtime().  The game only uses the
    "seconds" portion of the returned data, and that only to do an srand().
    I figure localtime() is good enough for the games' purpose.
(5) Linted.  --Partially, as System III lint isn't as smart as System V
    lint and therefore probably missed some things.  However, it *did* catch
    an operator precedence bug.

Detailed information is in the README.  (The author's original README is
included at the end of my README.)

Quick compile commands:
-	edit Makefile; comment and/or uncomment lines at the top depending
	on whether your system uses the terminfo/curses termcap emulation
	or real termcap;
-	type "make" and wait for it to finish

Have fun!

++Brandon]]
----------------------
#! /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 shell archive."
# Contents:  README Makefile sol.c solx.c
# Wrapped by billr@tekred on Wed Aug  5 10:20:00 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(2976 characters\)
sed "s/^X//" >README <<'END_OF_README'
XI've done some work on "sol.c" to make it portable to more systems than
Xjust BSD.  The only thing that needs to be specified is whether System V
Xterminfo/curses's termcap emulation is being used; compile with -DTERMINFO if
Xso. (The Makefile has been modified for this.)  The other conditionals are
Xbased on SIGTSTP (independent of others; some System V's have job control) and
Xon TCGETA from sys/ioctl.h. With no special compile #define's aside from the
Xterminfo stuff, sol.c will make itself at home on your system.
X
XI ripped the gettimeofday() calls out of both programs and used localtime()
Xinstead.  It does the job, since the returned value is used only to seed
Xthe random number generator, and it's portable.
X
XI installed a bugfix in the termcap stuff while I was at it; the original
Xauthor apparently didn't understand how the "bs" and "bc" attributes work.
XI've fixed that so it should work as per termcap(4).
X
XThrough the magic of "sdiff" and the fact that "sol" and "solx" are basically
Xderived from the same original source code, I have made the same changes to
X"solx".  Again, they work here.
X
XI haven't tested this under BSD (I don't have a BSD system available to me)
Xso I may have broken something under BSD.  The game does successfully auto-
Xconfigure for System III and System V, and works fine.  (It also uses termio
Xon these systems, so "echoe" gets reset properly.) Presumably it will work
Xproperly under Xenix 3 and Xenix 5, but I can't test it.
X
XHave fun with "sol" and "solx".
X
X++Brandon
X
X(author's original README included below)
X===============================================================================
X
XSources for two solitaire games - a while back someone posted some sources
Xin some language or other that played solitaire. With about two evenings
Xwoth of work that became sol.c - standard solitaire. To compile either game
X(under BSD4.3) use a command like 'cc -o sol sol.c -ltermcap' or
X'cc -o solx solx.c -ltermcap' - you'll have to adjust on Xenix for termcap
Xetc. etc. etc. solx.c is a different solitaire game, and a lot more
Xdifficult to get out. You start with 1 run containing a single card
X(#1 in the game), then hidden piles 2 thru 7, containing 2 thru 7 cards
Xrespectively. The remaining 24 cards are dealt on runs 2 thru 7 - four
Xin each run. There is no deck - all you can do is to move runs around.
XUnlike regular solitaire, runs can be split, hence the altered move
Xcommand, and since runs can get a bit long (I've seen them as big as
X22-23 cards) I've turned the display on it's side. Both games have several
Xcheats, and an autopilot, although the autopilot for solx is not very clever.
XIn order to prevent thrashing of runs I coded it so that it will only move
Xa run if the top card being moved was not already placed. However there
Xare times when such an apparently redundant move is necessary to get out.
X
XBest of luck, and have fun.
X--
X		dg@wrs.UUCP - David Goodenough
X
X					+---+
X					| +-+-+
X					+-+-+ |
X					  +---+
END_OF_README
if test 2976 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(450 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X# Makefile for soliaire games
XSHELL = /bin/sh
XCFLAGS = -O
X# TERMINFOFLAGS = -DTERMINFO
X# TERMINFOLIBS = -lcurses
XTERMINFOLIBS = -ltermcap
X#
X# Uncomment the top two TERMINFO lines above and comment the third out if
X# you compile this with terminfo's termcap emulation.
X#
X
XGAMES = sol solx
X
Xall:	$(GAMES)
Xsol:	sol.c
X	cc $(CFLAGS) $(TERMINFOFLAGS) -o sol sol.c $(TERMINFOLIBS)
X
Xsolx:	solx.c
X	cc $(CFLAGS) $(TERMINFOFLAGS) -o solx solx.c $(TERMINFOLIBS)
END_OF_Makefile
if test 450 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sol.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"sol.c\"
else
echo shar: Extracting \"sol.c\" \(18166 characters\)
sed "s/^X//" >sol.c <<'END_OF_sol.c'
X#include	<stdio.h>
X#include	<signal.h>
X#ifdef SIGVTALRM
X#include	<sys/time.h>
X#else
X#include	<time.h>
X#endif SIGVTALRM
X#include	<sys/types.h>
X#include	<sys/stat.h>
X#include	<sys/ioctl.h>
X#ifdef TCGETA
X#include	<termio.h>
X#define		sgttyb	termio
X#endif TCGETA
X
X#define 	TRUE	1
X#define		FALSE	0
X
Xint	amode;
Xint	cnt;
Xint	cheat;
Xint	deck[53];
Xint	over[53];
Xint	ace[4][14];
Xint	run[7][14];
Xint	hidden[7][8];
Xchar	cmd[40], *cp;
Xchar	*resgb;
X
Xextern	char	PC;
Xextern	char	BC[2];
Xextern	char	UP[2];
X
Xchar	*sc_bs;
Xchar	*sc_move;
Xchar	*sc_clear;
Xchar	*sc_cleol;
Xchar	*sc_init;
Xchar	*sc_deinit;
Xchar	*sc_s_in;
Xchar	*sc_s_out;
X
X#ifndef TERMINFO
Xextern	short	ospeed;
X#endif  TERMINFO
X
Xextern	struct tm	*localtime();
Xextern	char		*getenv();
Xextern	unsigned int	sleep();
Xextern	long		time();
X
Xmain(n, a)
Xchar **a;
X {
X    int i, p, c, r, s;
X    long now;
X    struct tm *tp;
X    int from;
X    int dest;
X    int brkflg;
X
X    amode = 0;
X    (void) time(&now);
X    tp = localtime(&now);
X    srand((unsigned) (getpid() + tp->tm_sec));
X    rawmode(TRUE);
X    setsig(TRUE);
X    getterm();
X    init();
X    for (i = 0; i < 52; i++)
X      deck[i] = i;
X    deck[52] = -1;
X    shuffle(deck);
X    for (i = 0; i < 4; i++)
X      ace[i][0] = -1;
X    for (i = 0; i < 7; i++)
X      hidden[i][0] = run[i][0] = -1;
X    over[0] = -1;
X    for (p = 0; p < 7; p++)
X      for (c = p; c < 7; c++)
X	put(hidden[c],get(deck));
X    for (r = 0; r < 7; r++)
X      put(run[r],get(hidden[r]));
X    redraw(TRUE);
X    for (r = 0; r < 7; r++)
X     {
X	while (getvalue(run[r][0]) == 0)
X	 {
X	    s = getsuit(run[r][0]);
X	    put(ace[s],get(run[r]));
X	    put(run[r],get(hidden[r]));
X	    redraw(FALSE);
X	 }
X     }
X    cnt = cheat = 0;
X    if (n > 1 && !strcmp(a[1], "auto"))
X      autopilot();
X    brkflg = 1;
X    while (brkflg)
X     {
X	cnt++;
X	do
X	 {
X	    moveto(17, 0);
X	    (void) printf("cmd:%d> ", cnt);
X	    cleol();
X	    (void) fflush(stdout);
X	 } while (!getst(cp = cmd));
X	while (*cp == ' ' || *cp == '\t')
X	  cp++;
X	switch (*cp++)
X	 {
X	    case 'a':
X	      autopilot();
X	    break;
X	    case 'm':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(from = *cp++) || ((from < '1' || from > '7') &&
X								from != 'd'))
X		 {
X		    whoops();
X		    continue;
X		 }
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
X				dest != 'a') || !movecard(from, dest, FALSE))
X		 {
X		    whoops();
X		    continue;
X		 }
X		if (cardsleft() == 0)
X		  finish();
X	     }
X	    break;
X	    case 't':
X	    case 0:
X	      thumb();
X	    break;
X	    case 'h':
X	    case '?':
X	      disphelp();
X	    break;
X	    case 'r':
X	      disprules();
X	    break;
X	    case 'q':
X	      brkflg = 0;
X	    break;
X	    case 's':
X	     {
X		while (peek(over) != -1)
X		  put(deck, get(over));
X		shuffle(deck);
X		redraw(FALSE);
X		cheat++;
X	     }
X	    break;
X	    case 'p':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(from = *cp++) || from < '1' || from > '7')
X		 {
X		    whoops();
X		    continue;
X		 }
X	        if (hidden[from -= '1'][0] != -1)
X		 {
X		    while (hidden[from][0] != -1)
X		      put(deck, get(hidden[from]));
X		    redraw(FALSE);
X		    cheat++;
X		 }
X		else
X		  whoops();
X	     }
X	    break;
X	    case 'd':
X	     {
X		moveto(19, 0);
X		(void) printf("%d cards in deck:\n", lstlen(deck) + lstlen(over));
X		i = lstlen(deck);
X		while (--i != -1)
X		 {
X		    pcard(deck[i]);
X		    (void) putchar(' ');
X		 }
X		(void) putchar('\n');
X		for (i = 0; over[i] != -1; i++)
X		 {
X		    pcard(over[i]);
X		    (void) putchar(' ');
X		 }
X		(void) printf("\nHit return -");
X		(void) fflush(stdout);
X		(void) getcx();
X		moveto(19, 0);
X		for (i = 0; i < 4; i++)
X		 {
X		    cleol();
X		    (void) putchar('\n');
X		 }
X		cheat++;
X	     }
X	    break;
X	    case 'w':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(from = *cp++) || from < '1' || from > '7')
X		 {
X		    whoops();
X		    continue;
X		 }
X		moveto(19, 0);
X		from -= '1';
X		(void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
X								from + '1');
X		for (i = 0; hidden[from][i] != -1; i++)
X		 {
X		    pcard(hidden[from][i]);
X		    (void) putchar(' ');
X		 }
X		(void) printf("\nHit return -");
X		(void) fflush(stdout);
X		(void) getcx();
X		moveto(19,0);
X		for (i = 0; i < 4; i++)
X		 {
X		    cleol();
X		    (void) putchar('\n');
X		 }
X		cheat++;
X	     }
X	    break;
X	    default:
X	      whoops();
X	    break;
X	 }
X     }
X    moveto(19, 0);
X    cleol();
X    (void) printf("I see you gave up\n");
X    if (cheat > 0)
X      (void) printf("    ... even after you cheated %d times!\n", cheat);
X    else
X      (void) printf("    ... but at least you didn't cheat...congratulations!\n");
X    unwind();
X }
X
Xunwind()
X {
X    moveto(23, 0);
X    deinit();
X    rawmode(FALSE);
X    exit(0);
X }
X
Xmovecard(from,dest,limitmove)
X {
X    if (from == dest)
X      return(FALSE);
X    if (from == 'd')
X      return(dest == 'a' ? deck2ace() : deck2run(dest));
X    else
X      return(dest == 'a' ? run2ace(from) : run2run(from,dest,limitmove));
X }
X
Xdeck2run(dest)
X {
X    int fcard, dcard, s, ok;
X
X    if ((fcard = peek(over)) == -1)
X      return(FALSE);
X    dcard = peek(run[dest -= '1']);
X    if (ok = chk2run(fcard,dcard))
X     {
X	put(run[dest],get(over));
X	redraw(FALSE);
X	while (getvalue(peek(over)) == 0)
X	 {
X	    s = getsuit(peek(over));
X	    put(ace[s],get(over));
X	    redraw(FALSE);
X	 }
X     }
X    return(ok);
X }
X
Xdeck2ace()
X {
X    int fcard, s, ok;
X
X    if (ok = (fcard = peek(over)) != -1 &&
X		getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
X     {
X	put(ace[s], get(over));
X	redraw(FALSE);
X	while (getvalue(peek(over)) == 0)
X	 {
X	    s = getsuit(peek(over));
X	    put(ace[s],get(over));
X	    redraw(FALSE);
X	 }
X     }
X    return(ok);
X }
X
Xrun2ace(from)
X {
X    int fcard, s, ok;
X
X    fcard = peek(run[from -= '1']);
X    if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
X     {
X	put(ace[s], get(run[from]));
X	redraw(FALSE);
X	if (run[from][0] == -1 && hidden[from][0] >= 0)
X	 {
X	    while (getvalue(peek(hidden[from])) == 0)
X	     {
X		s = getsuit(peek(hidden[from]));
X		put(ace[s],get(hidden[from]));
X		redraw(FALSE);
X	     }
X	    put(run[from],get(hidden[from]));
X	    redraw(FALSE);
X	 }
X     }
X    return(ok);
X }
X
Xrun2run(from,dest,limitmove)
X {
X    int fcard, dcard, i, ok, s;
X
X    if ((fcard = run[from -= '1'][0]) == -1)
X      return(FALSE);
X    dcard = peek(run[dest -= '1']);
X    if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
X						lstlen(hidden[from]) == 0)
X      return(FALSE);
X    if (amode > 0 && !limitmove && lstlen(hidden[from]) == 0)
X      return(FALSE);
X    if (ok = chk2run(fcard,dcard))
X     {
X	for (i = 0; run[from][i] != -1; i++)
X	  put(run[dest], run[from][i]);
X	run[from][0] = -1;
X	redraw(FALSE);
X	if (lstlen(hidden[from]) > 0)
X	 {
X	    while (getvalue(peek(hidden[from])) == 0)
X	     {
X		s = getsuit(peek(hidden[from]));
X		put(ace[s],get(hidden[from]));
X		redraw(FALSE);
X	     }
X	    put(run[from],get(hidden[from]));
X	    redraw(FALSE);
X	 }
X     }
X    return(ok);
X }
X
Xchk2run(fcard,dcard)
X {
X    if (dcard == -1 && getvalue(fcard) == 12)
X      return(TRUE);
X    return(getvalue(dcard) - 1 == getvalue(fcard) &&
X				getcolour(dcard) != getcolour(fcard));
X }
X
Xfinish()
X {
X    int i, k;
X
X    moveto(19,0);
X    (void) printf("\007I'll finish for you now\007");
X    (void) fflush(stdout);
X    do
X     {
X	k = FALSE;
X	for (i = 0; i < 7; i++)
X	  k = movecard(i + '1', 'a', FALSE) || k;
X     } while (k);
X    moveto(20,0);
X    cleol();
X    (void) printf("\007You WIN\007\n");
X    if (cheat > 0)
X      (void) printf("    ... but you cheated %d times!", cheat);
X    else
X      (void) printf("    ... and without cheating ... congratulations!");
X    unwind();
X }
X
Xautopilot()
X {
X    int i, j, k;
X    int iter;
X
X    moveto(19,0);
X    (void) printf("Going into automatic mode...");
X    (void) fflush(stdout);
X    amode = TRUE;
X    while (cardsleft() > 0)
X     {
X	k = FALSE;
X     	iter = 0;
X	for (i = 0; i < 7; i++)
X	  for (j = 0; j < 7; j++)
X	    k = movecard(i + '1', j + '1', TRUE) || k;
X	for (i = 0; i < 7; i++)
X	 {
X	    k = movecard(i + '1', 'a', FALSE) || k;
X	    k = movecard('d', i + '1', FALSE) || k;
X	 }
X	k = movecard('d', 'a', FALSE) || k;
X	if (!k)
X	 {
X	    if (iter--)
X	      thumb();
X	    else
X	      break;
X	 }
X	else
X	  iter = lstlen(over) + lstlen(deck);
X     }
X    do
X     {
X	k = FALSE;
X	for (i = 0; i < 7; i++)
X	  k = movecard(i + '1', 'a', FALSE) || k;
X     } while (k);
X    moveto(19, 28);
X    if (cardsleft() == 0)
X     {
X	(void) printf("\007YEA...\007");
X	(void) fflush(stdout);
X	for (i = 0; i < 7; i++)
X	  if (movecard(i + '1', 'a', FALSE));
X	moveto(19, 34);
X	(void) printf("I won!!!!!");
X     }
X    else
X     {
X	(void) printf("I couldn't win this time");
X	moveto(20, 0);
X	(void) printf("%d cards in deck", lstlen(deck) + lstlen(over));
X     }
X    unwind();
X }
X
Xredraw(display)
X {
X    static long_run[7];
X    static long_hide[7];
X    static long_ace[4];
X    static base_run[7];
X
X    int i, j;
X
X    if (display)
X     {
X	clear();
X	for (i = 0; i < 7; i++)
X	 {
X	    long_run[i] = long_hide[i] = base_run[i] = -1;
X	    moveto(0, 8 + i * 5);
X	    (void) putchar(i + '1');
X	 }
X	for (i = 0; i < 4; i++)
X	  long_ace[i] = -1;
X	moveto(0,56);
X	(void) printf("ACES");
X	moveto(6,56);
X	(void) printf("DECK");
X     }
X    for (i = 0; i < 7; i++)
X     {
X	if (long_hide[i] != lstlen(hidden[i]))
X	 {
X	    moveto(2, 8 + i * 5);
X	    (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
X	    long_hide[i] = lstlen(hidden[i]);
X	 }
X     }
X    for (i = 0; i < 4; i++)
X     {
X	if (long_ace[i] != lstlen(ace[i]))
X	 {
X	    moveto(2, 49 + i * 5);
X	    if (ace[i][0] != -1)
X	      pcard(peek(ace[i]));
X	    else
X	      (void) printf("--");
X	    long_ace[i] = lstlen(ace[i]);
X	 }
X     }
X    moveto(8, 55);
X    (void) printf(lstlen(deck) ? "##  " : "    ");
X    if (lstlen(over))
X      pcard(peek(over));
X    else
X      (void) printf("  ");
X    for (i = 0; i < 7; i++)
X     {
X	if (long_run[i] != lstlen(run[i]) ||
X				(long_run[i] == 1 && base_run[i] != run[i][0]))
X	 {
X	    for (j = 0; run[i][j] != -1; j++)
X	     {
X		moveto(j + 4, 7 + i * 5);
X		if (run[i][j] == -1)
X		  (void) printf("  ");
X		else
X		  pcard(run[i][j]);
X	     }
X	    while (j < long_run[i])
X	     {
X		moveto(j++ + 4, 7 + i * 5);
X		(void) printf("  ");
X	     }
X	    long_run[i] = lstlen(run[i]);
X	    base_run[i] = run[i][0];
X	 }
X     }
X    (void) fflush(stdout);
X    (void) sleep(1);
X }
X
Xthumb()
X {
X    int i, s;
X
X    if (deck[0] == -1)
X     {
X	if (over[0] == -1)
X	  return;
X	while (over[0] != -1)
X	  put(deck, get(over));
X     }
X    for (i = 0; i < 3; i++)
X      if (deck[0] != -1)
X	put(over,get(deck));
X    redraw(FALSE);
X    while (getvalue(peek(over)) == 0)
X     {
X	s = getsuit(peek(over));
X	put(ace[s], get(over));
X	redraw(FALSE);
X     }
X    if (over[0] == -1 && deck[0] != -1)
X      thumb();
X }
X
Xpcard(card)
X {
X    int i;
X
X    if ((i = getcolour(card)) != 0)
X      standout();
X    (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
X    if (i)
X      standend();
X }
X
X
Xgetvalue(card)
X {
X    return(card % 13);
X }
X
Xgetsuit(card)
X {
X    return(card / 13);
X }
X
Xgetcolour(card)
X {
X    return(card / 26);
X }
X
Xcardsleft()
X {
X    int i, t;
X
X    t = lstlen(deck) + lstlen(over);
X    for (i = 0; i < 7; i++)
X      t += lstlen(hidden[i]);
X    return(t);
X }
X
Xwhoops()
X {
X    moveto(17,0);
X    (void) printf("\007Invalid Command: '%s'\007", cmd);
X    (void) fflush(stdout);
X    (void) sleep(4);
X }
X
X
Xdisphelp()
X {
X    clear();
X    (void) printf("\
XCommands: t or RETURN     : thumb the deck 3 cards at a time\n\
X          m [d1-7] [1-7a] : move cards or runs\n\
X          a               : turn on the auto pilot (in case you get stuck)\n\
X          s               : shuffle the deck (cheat!)\n\
X          p [2-7]         : put a hidden pile into the deck (cheat!)\n\
X          d               : print the cards in the deck (cheat!)\n\
X          w [2-7]         : print the cards in a hidden pile (cheat!)\n\
X          h or ?          : print this command summary\n\
X          r               : print the rules of the game\n\
X          q               : quit\n\n");
X    (void) printf("\
XMoving:   1-7, 'd', or 'a' select the source and destination for a move.\n\
X          Valid moves are from a run to a run, from the deck to a run,\n\
X          from a run to an ace pile, and from the deck to an ace pile.\n\n\
XCheating: Commands that allow cheating are available but they will count\n\
X          against you in your next life!\n\n\nHit Return -");
X    (void) fflush(stdout);
X    (void) getcx();
X    redraw(TRUE);
X }
X
Xdisprules()
X {
X    clear();
X    (void) printf("\
XObject:   The object of this game is to get all of the cards in each suit\n\
X          in order on the proper ace pile.\n\n\
XRules:    Cards are played on the ace piles in ascending order: A,2,...,K. \n\
X          All aces are automatically placed in the correct aces pile as\n\
X          they're found in the deck or in a pile of hidden cards.  Once a\n\
X          card is placed in an ace pile it can't be removed.\n\n");
X    (void) printf("\
X          Cards must be played in descending order: K,Q,..,2, on the seven\n\
X          runs which are initially dealt.  They must always be played on a\n\
X          card of the opposite color.  Runs must always be moved as a\n\
X          whole, unless you're moving the lowest card on a run to the\n\
X          correct ace pile.\n\n");
X    (void) printf("\
X          Whenever a whole run is moved, the top hidden card is turned\n\
X          over, thus becoming the beginning of a new run.  If there are no\n\
X          hidden cards left, a space is created which can only be filled by\n\
X          a king.\n\n\
X          The rest of the deck is thumbed 3 cards at a time, until you spot a\n\
X          valid move.  Whenever the bottom of the deck is reached, the cards\n\
X          are turned over and you can continue thumbing.\n\n\nHit Return -");
X    (void) fflush(stdout);
X    (void) getcx();
X    redraw(TRUE);
X }
X
Xgetst(getbuf)
Xchar *getbuf;
X {
X    int ch;
X    int nc;
X
X    *(resgb = getbuf) = nc = 0;
X    for (;;)
X     {
X	if ((((ch = getcx()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
X	 {
X	    *getbuf++ = ch;
X	    *getbuf = 0;
X	    nc++;
X	    (void) putchar(ch);
X	    (void) fflush(stdout);
X	 }
X	else if (ch == '\b')
X	 {
X	    if (nc--)
X	     {
X	        *--getbuf = 0;
X		(void) printf("\b \b");
X		(void) fflush(stdout);
X	     }
X	    else
X	      return(FALSE);
X	 }
X	else if (ch == ('r' & 0x1f))
X	  redraw(TRUE);
X	else if (ch == '\n')
X	  return(TRUE);
X     }
X }
X
Xshuffle(cards)
Xint *cards;
X {
X    int i, j, k, t;
X
X    for (i = 0; cards[i] != -1; i++)
X      ;
X    if (i)
X     {
X	for (j = 0; j < i; j++)
X	 {
X	    do
X	      k = rnd(i);
X	     while (k == j);
X	    t = cards[j];
X	    cards[j] = cards[k];
X	    cards[k] = t;
X	 }
X     }
X }
X
Xrnd(n)
X {
X    return(((rand() >> 12 | rand() >> 24) & (unsigned) ~0 >> 1) % n);
X }
X
Xlstlen(list)
Xint *list;
X {
X    int i;
X
X    for (i = 0; list[i] != -1; i++)
X      ;
X    return(i);
X }
X
X#ifdef SIGTSTP
X
Xrestart()
X {
X    setsig(TRUE);
X    rawmode(TRUE);
X    redraw(TRUE);
X    moveto(17, 0);
X    (void) printf("cmd:%d> ", cnt);
X    cleol();
X    (void) printf("%s", resgb);
X    (void) fflush(stdout);
X }
X
X#endif SIGTSTP
X
Xsetsig(on)
X {
X    (void) signal(SIGINT, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGQUIT, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGTERM, on ? SIG_IGN : SIG_DFL);
X#ifdef SIGTSTP
X    (void) signal(SIGTSTP, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGCONT, on ? restart : SIG_DFL);
X#endif
X }
X
Xstop()
X {
X    setsig(FALSE);
X    rawmode(FALSE);
X#ifdef SIGTSTP
X    (void) signal(SIGCONT, restart);
X    kill(getpid(), SIGTSTP);
X#else
X    (void) system("eval exec ${SHELL-/bin/sh}");
X#endif SIGTSTP
X }
X
Xgetcx()
X {
X    char ch;
X
X#ifdef SIGTSTP
X    (void) signal(SIGTSTP, stop);
X#else
X    for (;;) {
X#endif SIGTSTP
X        (void) read(0, &ch, 1);
X#ifdef SIGTSTP
X        (void) signal(SIGTSTP, SIG_IGN);
X#else
X        if (ch != '\032')
X            break;
X        stop();
X    }
X#endif SIGTSTP
X    return(ch);
X }
X
Xrawmode(on)
X {
X    struct sgttyb s;
X    static struct sgttyb saveterm;
X    static int saved = FALSE;
X
X    if (on)
X     {
X#ifdef TCGETA
X     	(void) ioctl(0, TCGETA, &s);
X#else
X	(void) ioctl(0, TIOCGETP, &s);
X#endif TCGETA
X	if (saved == FALSE)
X	 {
X	    saveterm = s;
X	    saved = TRUE;
X	 }
X#ifdef TCGETA
X#ifndef TERMINFO
X     	ospeed = s.c_cflag & CBAUD;
X#endif  TERMINFO
X     	s.c_lflag &= ~(ECHO|ICANON);
X     	s.c_oflag &= ~TAB3;
X     	s.c_cc[VMIN] = 1;
X     	s.c_cc[VTIME] = 1;
X#else
X	ospeed = s.sg_ospeed;
X	s.sg_flags |= CBREAK;
X	s.sg_flags &= ~(ECHO|XTABS);
X#endif TCGETA
X     }
X    else
X      s = saveterm;
X#ifdef TCGETA
X    (void) ioctl(0, TCSETAW, &s);
X#else
X    (void) ioctl(0, TIOCSETN, &s);
X#endif
X }
X
Xgetterm()
X {
X    char termbuf[1024];
X    char *sp;
X    static char sbuf[150];
X    char *tgetstr();
X
X    tgetent(termbuf, getenv("TERM"));
X    sp = sbuf;
X
X    PC = *(tgetstr("pc", &sp));
X    *UP = *(tgetstr("pc", &sp));
X    UP[1] = 0;
X    if (!tgetflag("bs"))
X    	*BC = *(sc_bs = tgetstr("bc", &sp));
X    else {
X    	*BC = '\b';
X    	sc_bs = BC;
X    }
X    BC[1] = 0;
X    sc_init = tgetstr("ti", &sp);
X    sc_deinit = tgetstr("te", &sp);
X    sc_cleol = tgetstr("ce", &sp);
X    sc_clear = tgetstr("cl", &sp);
X    sc_move = tgetstr("cm", &sp);
X    sc_s_in = tgetstr("so", &sp);
X    sc_s_out = tgetstr("se", &sp);
X }
X
Xxputc(c)
Xregister c;
X {
X    (void) putchar(c);
X }
X
Xinit()
X {
X    tputs(sc_init, 24, xputc);
X }
X
Xdeinit()
X {
X    tputs(sc_deinit, 24, xputc);
X }
X
Xclear()
X {
X    tputs(sc_clear, 24, xputc);
X }
X
Xcleol()
X {
X    tputs(sc_cleol, 1, xputc);
X }
X
Xstandout()
X {
X    tputs(sc_s_in, 1, xputc);
X }
X
Xstandend()
X {
X    tputs(sc_s_out, 1, xputc);
X }
X
Xmoveto(y, x)
X {
X    char *tgoto();
X
X    tputs(tgoto(sc_move, x, y), 1, xputc);
X }
X
Xput(dest, item)
Xint *dest;
X {
X    if (item == -1)
X      return;
X    while (*dest != -1)
X      dest++;
X    *dest++ = item;
X    *dest = -1;
X }
X
Xget(source)
Xint *source;
X {
X    int i;
X
X    for (i = 0; *source != -1; i++, source++)
X      ;
X    if (i)
X     {
X	i = *--source;
X	*source = -1;
X	return(i);
X     }
X    return(-1);
X }
X
Xpeek(source)
Xint *source;
X {
X    int i;
X
X    for (i = 0; source[i] != -1; i++)
X      ;
X    return(i ? source[i - 1] : -1);
X }
END_OF_sol.c
if test 18166 -ne `wc -c <sol.c`; then
    echo shar: \"sol.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f solx.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"solx.c\"
else
echo shar: Extracting \"solx.c\" \(16202 characters\)
sed "s/^X//" >solx.c <<'END_OF_solx.c'
X#include	<stdio.h>
X#include	<ctype.h>
X#include	<signal.h>
X#ifdef SIGVTALRM
X#include	<sys/time.h>
X#else
X#include	<time.h>
X#endif SIGVTALRM
X#include	<sys/types.h>
X#include	<sys/stat.h>
X#include	<sys/ioctl.h>
X#ifdef TCGETA
X#include	<termio.h>
X#define		sgttyb	termio
X#endif TCGETA
X
X#define 	TRUE	1
X#define		FALSE	0
X
Xint	amode;
Xint	cnt;
Xint	cheat;
Xint	deck[53];
Xint	ace[4][14];
Xint	run[7][53];
Xint	hidden[7][8];
Xchar	cmd[40], *cp;
Xchar	*resgb;
X
Xextern	char	PC;
Xextern	char	BC[2];
Xextern	char	UP[2];
X
Xchar	*sc_bs;
Xchar	*sc_move;
Xchar	*sc_clear;
Xchar	*sc_cleol;
Xchar	*sc_init;
Xchar	*sc_deinit;
Xchar	*sc_s_in;
Xchar	*sc_s_out;
X
X#ifndef TERMINFO
Xextern	short	ospeed;
X#endif  TERMINFO
X
Xint	long_run[7];
Xint	long_hide[7];
Xint	long_ace[4];
Xint	base_run[7];
X
Xextern	struct tm	*localtime();
Xextern	char		*getenv();
Xextern	long		time();
Xextern	unsigned int	sleep();
X
Xmain(n, a)
Xchar **a;
X {
X    int i, p, c, r, s;
X    long now;
X    struct tm *tp;
X    int from;
X    int split;
X    int dest;
X    int brkflg;
X
X    amode = 0;
X    (void) time(&now);
X    tp = localtime(&now);
X    srand((unsigned) (getpid() + tp->tm_sec));
X    rawmode(TRUE);
X    setsig(TRUE);
X    getterm();
X    init();
X    for (i = 0; i < 52; i++)
X      deck[i] = i;
X    deck[52] = -1;
X    shuffle(deck);
X    for (i = 0; i < 4; i++)
X      ace[i][0] = -1;
X    for (i = 0; i < 7; i++)
X      hidden[i][0] = run[i][0] = -1;
X    for (p = 0; p < 7; p++)
X      for (c = p; c < 7; c++)
X	put(hidden[c],get(deck));
X    put(run[0], get(hidden[0]));
X    for (r = 1; r < 7; r++)
X      for (i = 0; i < 4; i++)
X        put(run[r],get(deck));
X    redraw(TRUE);
X    for (r = 0; r < 7; r++)
X     {
X	while (getvalue(peek(run[r])) == 0)
X	 {
X	    s = getsuit(peek(run[r]));
X	    put(ace[s],get(run[r]));
X	    if (run[r][0] == -1)
X	      put(run[r],get(hidden[r]));
X	    redraw(FALSE);
X	 }
X     }
X    cnt = cheat = 0;
X    if (n > 1 && !strcmp(a[1], "auto"))
X      autopilot();
X    brkflg = 1;
X    while (brkflg)
X     {
X	cnt++;
X	do
X	 {
X	    moveto(19, 0);
X	    (void) printf("cmd:%d> ", cnt);
X	    cleol();
X	    (void) fflush(stdout);
X	 } while (!getst(cp = cmd));
X	while (*cp == ' ' || *cp == '\t')
X	  cp++;
X	switch (*cp++)
X	 {
X	    case 'a':
X	      autopilot();
X	    break;
X	    case 'm':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(from = *cp++) || from < '1' || from > '7')
X		 {
X		    whoops();
X		    continue;
X		 }
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		for (split = 0; isdigit(*cp); split = split * 10 + *cp++ - '0')
X		  ;
X		if (split < 1 || split > lstlen(run[from - '1']))
X		 {
X		    whoops();
X		    continue;
X		 }
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
X			dest != 'a') || !movecard(from, split, dest, FALSE))
X		 {
X		    whoops();
X		    continue;
X		 }
X		if (ordered())
X		  finish();
X	     }
X	    break;
X	    case 'h':
X	    case '?':
X	      disphelp();
X	    break;
X	    case 'r':
X	      disprules();
X	    break;
X	    case 'q':
X	      brkflg = 0;
X	    break;
X	    case 'w':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if ((from = *cp - '1') < 0 || from > 6)
X		 {
X		    whoops();
X		    continue;
X		 }
X		moveto(21, 0);
X		(void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
X								from + '1');
X		for (i = 0; hidden[from][i] != -1; i++)
X		 {
X		    pcard(hidden[from][i]);
X		    (void) putchar(' ');
X		 }
X		(void) printf("\nHit return -");
X		(void) fflush(stdout);
X		(void) getcx();
X		moveto(21, 0);
X		cleol();
X		(void) putchar('\n');
X		cleol();
X		cheat++;
X	     }
X	    break;
X	    case 'p':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if ((from = *cp - '1') < 0 || from > 6)
X		 {
X		    whoops();
X		    continue;
X		 }
X		while (hidden[from][0] != -1)
X		  put(run[from], get(hidden[from]));
X		redraw(FALSE);
X		cheat++;
X	     }
X	    break;
X	    case 's':
X	     {
X		while (*cp == ' ' || *cp == '\t')
X		  cp++;
X		if ((from = *cp - '1') < 0 || from > 6)
X		 {
X		    whoops();
X		    continue;
X		 }
X		shuffle(run[from]);
X		long_run[from] = -1;
X		redraw(FALSE);
X		cheat++;
X	     }
X	    break;
X	    default:
X	      whoops();
X	    break;
X	 }
X     }
X    moveto(21, 0);
X    cleol();
X    (void) printf("I see you gave up\n");
X    if (cheat > 0)
X      (void) printf("    ... even after you cheated %d times!\n", cheat);
X    else
X      (void) printf("    ... but at least you didn't cheat...congratulations!\n");
X    unwind();
X }
X
Xunwind()
X {
X    moveto(23, 0);
X    deinit();
X    rawmode(FALSE);
X    exit(0);
X }
X
Xmovecard(from, split, dest, limitmove)
X {
X    if (from == dest)
X      return(FALSE);
X    return(dest == 'a' ? run2ace(from) : run2run(from, split, dest, limitmove));
X }
X
Xrun2ace(from)
X {
X    int fcard, s, ok;
X
X    fcard = peek(run[from -= '1']);
X    if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
X     {
X	put(ace[s], get(run[from]));
X	redraw(FALSE);
X	tidy(from);
X     }
X    return(ok);
X }
X
Xrun2run(from, split, dest, limitmove)
X {
X    int fcard, dcard, i, ok;
X
X    if ((fcard = run[from -= '1'][--split]) == -1)
X      return(FALSE);
X    dcard = peek(run[dest -= '1']);
X    if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
X						lstlen(hidden[from]) == 0)
X      return(FALSE);
X    if (amode > 0 && limitmove && split && chk2run(fcard, run[from][split - 1]))
X      return(FALSE);
X    if (ok = chk2run(fcard, dcard))
X     {
X	for (i = split; run[from][i] != -1; i++)
X	  put(run[dest], run[from][i]);
X	run[from][split] = -1;
X	redraw(FALSE);
X	tidy(from);
X     }
X    return(ok);
X }
X
Xtidy(from)
X {
X    int s;
X
X    while (getvalue(peek(run[from])) == 0)
X     {
X	s = getsuit(peek(run[from]));
X	put(ace[s],get(run[from]));
X	redraw(FALSE);
X     }
X    if (lstlen(hidden[from]) != 0 && lstlen(run[from]) == 0)
X     {
X	while (getvalue(peek(hidden[from])) == 0)
X	 {
X	    s = getsuit(peek(hidden[from]));
X	    put(ace[s],get(hidden[from]));
X	    redraw(FALSE);
X	 }
X	put(run[from],get(hidden[from]));
X	redraw(FALSE);
X     }
X }
X
Xchk2run(fcard,dcard)
X {
X    if (dcard == -1 && getvalue(fcard) == 12)
X      return(TRUE);
X    return(getvalue(dcard) - 1 == getvalue(fcard) &&
X				getcolour(dcard) != getcolour(fcard));
X }
X
Xordered()
X {
X    int i, j;
X
X    for (i = 0; i < 7; i++)
X      if (hidden[i][0] != -1)
X	return(FALSE);
X      else if (run[i][0] != -1)
X	for (j = 1; run[i][j] != -1; j++)
X	  if (getvalue(run[i][j]) != getvalue(run[i][j - 1]) - 1 ||
X			getcolour(run[i][j]) == getcolour(run[i][j - 1]))
X	    return(FALSE);
X    return(TRUE);
X }
X
Xcardsleft()
X {
X    int i;
X    for (i = 0; i < 7; i++)
X      if (run[i][0] != -1)
X	return(TRUE);
X    return(FALSE);
X }
X
Xfinish()
X {
X    int i;
X
X    moveto(21, 0);
X    (void) printf("\007I'll finish for you now\007");
X    (void) fflush(stdout);
X    do
X      for (i = 0; i < 7; i++)
X	while (movecard(i + '1', 0, 'a', FALSE))
X	  ;
X     while (cardsleft());
X    moveto(21, 40);
X    cleol();
X    (void) printf("\007You WIN\007\n");
X    if (cheat > 0)
X      (void) printf("    ... but you cheated %d times!", cheat);
X    else
X      (void) printf("    ... and without cheating ... congratulations!");
X    unwind();
X }
X
Xautopilot()
X {
X    int i, j, k, l;
X
X    moveto(21, 0);
X    (void) printf("Going into automatic mode...");
X    (void) fflush(stdout);
X    amode = TRUE;
X    do
X     {
X	l = 0;
X	for (i = 0; i < 7; i++)
X	  for (j = 0; j < 7; j++)
X	    for (k = 0; k < lstlen(run[i]); k++)
X	      l = movecard(i + '1', k, j + '1', TRUE) || l;
X	for (i = 0; i < 7; i++)
X	  l = movecard(i + '1', 0, 'a', FALSE) || l;
X     } while (l);
X    moveto(21, 28);
X    if (!cardsleft())
X     {
X	(void) printf("\007YEA...\007");
X	(void) fflush(stdout);
X	for (i = 0; i < 7; i++)
X	  if (movecard(i + '1', 0, 'a', FALSE))
X	moveto(21, 34);
X	(void) printf("I won!!!!!");
X     }
X    else
X      (void) printf("I couldn't win this time");
X    unwind();
X }
X
Xredraw(display)
X {
X    int i, j;
X
X    if (display)
X     {
X	clear();
X	for (i = 0; i < 7; i++)
X	 {
X	    long_run[i] = long_hide[i] = base_run[i] = -1;
X	    moveto(i + i + 2, 1);
X	    (void) putchar(i + '1');
X	 }
X	moveto(0, 6);
X	for (i = 1; i < 21; i++)
X	  (void) printf("%3d", i);
X	for (i = 0; i < 4; i++)
X	  long_ace[i] = -1;
X	moveto(17, 1);
X	(void) printf("ACES:");
X     }
X    for (i = 0; i < 7; i++)
X     {
X	if (long_hide[i] != lstlen(hidden[i]))
X	 {
X	    moveto(i + i + 2, 4);
X	    (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
X	    long_hide[i] = lstlen(hidden[i]);
X	 }
X     }
X    for (i = 0; i < 4; i++)
X     {
X	if (long_ace[i] != lstlen(ace[i]))
X	 {
X	    moveto(17, 8 + i * 5);
X	    if (ace[i][0] != -1)
X	      pcard(peek(ace[i]));
X	    else
X	      (void) printf("--");
X	    long_ace[i] = lstlen(ace[i]);
X	 }
X     }
X    for (i = 0; i < 7; i++)
X     {
X	if (long_run[i] != lstlen(run[i]) ||
X				(long_run[i] == 1 && base_run[i] != run[i][0]))
X	 {
X	    moveto(i + i +  2, 7);
X	    for (j = 0; run[i][j] != -1; j++)
X	     {
X		if (run[i][j] == -1)
X		  (void) printf("  ");
X		else
X		  pcard(run[i][j]);
X		(void) putchar(' ');
X	     }
X	    while (j++ < long_run[i])
X	      (void) printf("   ");
X	    long_run[i] = lstlen(run[i]);
X	    base_run[i] = run[i][0];
X	 }
X     }
X    (void) fflush(stdout);
X    (void) sleep(1);
X }
X
Xpcard(card)
X {
X    int i;
X
X    if ((i = getcolour(card)) != 0)
X      standout();
X    (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
X    if (i)
X      standend();
X }
X
Xgetvalue(card)
X {
X    return(card % 13);
X }
X
Xgetsuit(card)
X {
X    return(card / 13);
X }
X
Xgetcolour(card)
X {
X    return(card / 26);
X }
X
Xwhoops()
X {
X    moveto(19, 0);
X    (void) printf("\007Invalid Command: '%s'\007", cmd);
X    (void) fflush(stdout);
X    (void) sleep(4);
X }
X
Xdisphelp()
X {
X    clear();
X    (void) printf("\
XCommands: m [1-7] [pos] [1-7a] : move cards or runs\n\
X          a                    : turn on the auto pilot\n\
X          s [1-7]              : shuffle the cards in a run (cheat!)\n\
X          p [1-7]              : put a hidden pile onto the run (cheat!)\n\
X          w [1-7]              : print the cards in a hidden pile (cheat!)\n\
X          h or ?               : print this command summary\n\
X          r                    : print the rules of the game\n\
X          q                    : quit\n\n");
X    (void) printf("\
XMoving:   There are three parameters in the m command: the first is the\n\
X          run to be moved from, the second is the card number to split\n\
X          the run at (check numbers along the top), and the third is\n\
X	  the destination run (or 'a' if an ace pile). Since only one card\n\
X	  can be moved to an ace at a time, the pos paramter is ignored\n\
X	  in this case. To give a couple of examples 'm 6 1 4 would move\n\
X	  all cards from run 6 to run 4, and m 3 5 7 would split run 3\n\
X	  before the fifth card (leaving 4) and move the rest to run 7.\n\n\
XCheating: Commands that allow cheating are available but they will count\n\
X          against you in your next life!\n\n\nHit Return -");
X    (void) fflush(stdout);
X    (void) getcx();
X    redraw(TRUE);
X }
X
Xdisprules()
X {
X    clear();
X    (void) printf("\
XObject:   The object of this game is to get all of the cards in each suit\n\
X          in order on the proper ace pile.\n\n\
XRules:    Cards are played on the ace piles in ascending order: A,2,...,K.\n\
X          All aces are automatically placed in the correct aces pile as\n\
X          they're uncovered in runs or from a pile of hidden cards. Once a\n\
X          card is placed in an ace pile it can't be removed.\n\n");
X    (void) printf("\
X          When moving runs, they can be split anywhere, but the top card\n\
X	  in the run moved must be placed on a card one higher (i.e. 5 on\n\
X	  a 6) and always on a card of the opposite color.\n\n");
X    (void) printf("\
X          Whenever a whole run is moved, the top hidden card is turned\n\
X          over, thus becoming the beginning of a new run.  If there are no\n\
X          hidden cards left, a space is created which can only be filled by\n\
X          a king.\n\n\nHit Return -");
X    (void) fflush(stdout);
X    (void) getcx();
X    redraw(TRUE);
X }
X
Xgetst(getbuf)
Xchar *getbuf;
X {
X    int ch;
X    int nc;
X
X    *(resgb = getbuf) = nc = 0;
X    for (;;)
X     {
X	if ((((ch = getcx()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
X	 {
X	    *getbuf++ = ch;
X	    *getbuf = 0;
X	    nc++;
X	    (void) putchar(ch);
X	    (void) fflush(stdout);
X	 }
X	else if (ch == '\b')
X	 {
X	    if (nc--)
X	     {
X	        *--getbuf = 0;
X		(void) printf("\b \b");
X		(void) fflush(stdout);
X	     }
X	    else
X	      return(FALSE);
X	 }
X	else if (ch == ('r' & 0x1f))
X	  redraw(TRUE);
X	else if (ch == '\n')
X	  return(TRUE);
X     }
X }
X
Xshuffle(cards)
Xint *cards;
X {
X    int i, j, k, t;
X
X    for (i = 0; cards[i] != -1; i++)
X      ;
X    if (i)
X     {
X	for (j = 0; j < i; j++)
X	 {
X	    do
X	      k = rnd(i);
X	     while (k == j);
X	    t = cards[j];
X	    cards[j] = cards[k];
X	    cards[k] = t;
X	 }
X     }
X }
X
Xrnd(n)
X {
X    return(((rand() >> 12 | rand() >> 24) & (unsigned) ~0 >> 1) % n);
X }
X
Xlstlen(list)
Xint *list;
X {
X    int i;
X
X    for (i = 0; list[i] != -1; i++)
X      ;
X    return(i);
X }
X
X#ifdef SIGTSTP
X
Xrestart()
X {
X    setsig(TRUE);
X    rawmode(TRUE);
X    redraw(TRUE);
X    moveto(19, 0);
X    (void) printf("cmd:%d> ", cnt);
X    cleol();
X    (void) printf("%s", resgb);
X    (void) fflush(stdout);
X }
X
X#endif SIGTSTP
X
Xsetsig(on)
X {
X    (void) signal(SIGINT, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGQUIT, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGTERM, on ? SIG_IGN : SIG_DFL);
X#ifdef SIGTSTP
X    (void) signal(SIGTSTP, on ? SIG_IGN : SIG_DFL);
X    (void) signal(SIGCONT, on ? restart : SIG_DFL);
X#endif
X }
X
Xstop()
X {
X    setsig(FALSE);
X    rawmode(FALSE);
X#ifdef SIGTSTP
X    (void) signal(SIGCONT, restart);
X    kill(getpid(), SIGTSTP);
X#else
X    (void) system("eval exec ${SHELL-/bin/sh}");
X#endif SIGTSTP
X }
X
Xgetcx()
X {
X    char ch;
X
X#ifdef SIGTSTP
X    (void) signal(SIGTSTP, stop);
X#else
X    for (;;) {
X#endif SIGTSTP
X    (void) read(0, &ch, 1);
X#ifdef SIGTSTP
X    (void) signal(SIGTSTP, SIG_IGN);
X#else
X        if (ch != '\032')
X            break;
X        stop();
X    }
X#endif SIGTSTP
X    return(ch);
X }
X
Xrawmode(on)
X {
X    struct sgttyb s;
X    static struct sgttyb saveterm;
X    static int saved = FALSE;
X
X    if (on)
X     {
X#ifdef TCGETA
X     	(void) ioctl(0, TCGETA, &s);
X#else
X	(void) ioctl(0, TIOCGETP, &s);
X#endif TCGETA
X	if (saved == FALSE)
X	 {
X	    saveterm = s;
X	    saved = TRUE;
X	 }
X#ifdef TCGETA
X#ifndef TERMINFO
X     	ospeed = s.c_cflag & CBAUD;
X#endif  TERMINFO
X     	s.c_lflag &= ~(ECHO|ICANON);
X     	s.c_oflag &= ~TAB3;
X     	s.c_cc[VMIN] = 1;
X     	s.c_cc[VTIME] = 1;
X#else
X	ospeed = s.sg_ospeed;
X	s.sg_flags |= CBREAK;
X	s.sg_flags &= ~(ECHO|XTABS);
X#endif TCGETA
X     }
X    else
X      s = saveterm;
X#ifdef TCGETA
X    (void) ioctl(0, TCSETAW, &s);
X#else
X    (void) ioctl(0, TIOCSETN, &s);
X#endif
X }
X
Xgetterm()
X {
X    char termbuf[1024];
X    char *sp;
X    static char sbuf[150];
X    char *tgetstr();
X
X    tgetent(termbuf, getenv("TERM"));
X    sp = sbuf;
X
X    PC = *(tgetstr("pc", &sp));
X    *UP = *(tgetstr("pc", &sp));
X    UP[1] = 0;
X    if (!tgetflag("bs"))
X    	*BC = *(sc_bs = tgetstr("bc", &sp));
X    else {
X    	*BC = '\b';
X    	sc_bs = BC;
X    }
X    BC[1] = 0;
X    sc_init = tgetstr("ti", &sp);
X    sc_deinit = tgetstr("te", &sp);
X    sc_cleol = tgetstr("ce", &sp);
X    sc_clear = tgetstr("cl", &sp);
X    sc_move = tgetstr("cm", &sp);
X    sc_s_in = tgetstr("so", &sp);
X    sc_s_out = tgetstr("se", &sp);
X }
X
Xxputc(c)
Xregister c;
X {
X    (void) putchar(c);
X }
X
Xinit()
X {
X    tputs(sc_init, 24, xputc);
X }
X
Xdeinit()
X {
X    tputs(sc_deinit, 24, xputc);
X }
X
Xclear()
X {
X    tputs(sc_clear, 24, xputc);
X }
X
Xcleol()
X {
X    tputs(sc_cleol, 1, xputc);
X }
X
Xstandout()
X {
X    tputs(sc_s_in, 1, xputc);
X }
X
Xstandend()
X {
X    tputs(sc_s_out, 1, xputc);
X }
X
Xmoveto(y, x)
X {
X    char *tgoto();
X
X    tputs(tgoto(sc_move, x, y), 1, xputc);
X }
X
Xput(dest, item)
Xint *dest;
X {
X    if (item == -1)
X      return;
X    while (*dest != -1)
X      dest++;
X    *dest++ = item;
X    *dest = -1;
X }
X
Xget(source)
Xint *source;
X {
X    int i;
X
X    for (i = 0; *source != -1; i++, source++)
X      ;
X    if (i)
X     {
X	i = *--source;
X	*source = -1;
X	return(i);
X     }
X    return(-1);
X }
X
Xpeek(source)
Xint *source;
X {
X    int i;
X
X    for (i = 0; source[i] != -1; i++)
X      ;
X    return(i ? source[i - 1] : -1);
X }
END_OF_solx.c
if test 16202 -ne `wc -c <solx.c`; then
    echo shar: \"solx.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0