home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / games / volume02 / sol2 < prev   
Encoding:
Internet Message Format  |  1991-08-27  |  42.8 KB

  1. From mipos3!intelca!amd!amdcad!ames!ucbcad!ucbvax!decvax!tektronix!tekgen!tekred!games-request Thu Aug  6 15:03:28 PDT 1987
  2. Article 82 of comp.sources.games:
  3. Path: td2cad!mipos3!intelca!amd!amdcad!ames!ucbcad!ucbvax!decvax!tektronix!tekgen!tekred!games-request
  4. From: games-request@tekred.TEK.COM
  5. Newsgroups: comp.sources.games
  6. Subject: v02i030:  sol2 - solitaire games (revised)
  7. Message-ID: <1485@tekred.TEK.COM>
  8. Date: 5 Aug 87 17:23:04 GMT
  9. Sender: billr@tekred.TEK.COM
  10. Reply-To: allbery%ncoast.UUCP@cwruecmp.UUCP (Brandon S. Allbery)
  11. Lines: 1942
  12. Approved: billr@tekred.TEK.COM
  13.  
  14. Submitted by: allbery%ncoast.UUCP@cwruecmp.UUCP (Brandon S. Allbery)
  15. Comp.sources.games: Volume 2, Issue 30
  16. Archive-name: sol2
  17.  
  18.     [From the author...    -br]
  19.  
  20. [[I've done some work on the solitaire games posted to this newsgroup in late
  21. July.  Included below is a "shar" of the modified sources.  (The linting made
  22. the diffs bigger than the originals.)
  23.  
  24. Summary of changes to the programs:
  25.  
  26. (1) Fixed a bug in getting the backspace character from the termcap.
  27. (2) Added code for System III and System V, and derivatives thereof, for the
  28.     terminal I/O library used by these systems.
  29. (3) Added code to make ^Z work in these games even on systems without job
  30.     control; instead of returning to the parent shell, you get a subshell.
  31.     (This is independent of the terminal stuff, as I know of BSD lookalikes
  32.     that don't have job control (Pixel) and System V's that have job control
  33.     (Callan).)
  34. (4) Changed the gettimeofday() to a localtime().  The game only uses the
  35.     "seconds" portion of the returned data, and that only to do an srand().
  36.     I figure localtime() is good enough for the games' purpose.
  37. (5) Linted.  --Partially, as System III lint isn't as smart as System V
  38.     lint and therefore probably missed some things.  However, it *did* catch
  39.     an operator precedence bug.
  40.  
  41. Detailed information is in the README.  (The author's original README is
  42. included at the end of my README.)
  43.  
  44. Quick compile commands:
  45. -    edit Makefile; comment and/or uncomment lines at the top depending
  46.     on whether your system uses the terminfo/curses termcap emulation
  47.     or real termcap;
  48. -    type "make" and wait for it to finish
  49.  
  50. Have fun!
  51.  
  52. ++Brandon]]
  53. ----------------------
  54. #! /bin/sh
  55. # This is a shell archive.  Remove anything before this line, then unpack
  56. # it by saving it into a file and typing "sh file".  To overwrite existing
  57. # files, type "sh file -c".  You can also feed this as standard input via
  58. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  59. # will see the following message at the end:
  60. #        "End of shell archive."
  61. # Contents:  README Makefile sol.c solx.c
  62. # Wrapped by billr@tekred on Wed Aug  5 10:20:00 1987
  63. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  64. if test -f README -a "${1}" != "-c" ; then 
  65.   echo shar: Will not over-write existing file \"README\"
  66. else
  67. echo shar: Extracting \"README\" \(2976 characters\)
  68. sed "s/^X//" >README <<'END_OF_README'
  69. XI've done some work on "sol.c" to make it portable to more systems than
  70. Xjust BSD.  The only thing that needs to be specified is whether System V
  71. Xterminfo/curses's termcap emulation is being used; compile with -DTERMINFO if
  72. Xso. (The Makefile has been modified for this.)  The other conditionals are
  73. Xbased on SIGTSTP (independent of others; some System V's have job control) and
  74. Xon TCGETA from sys/ioctl.h. With no special compile #define's aside from the
  75. Xterminfo stuff, sol.c will make itself at home on your system.
  76. X
  77. XI ripped the gettimeofday() calls out of both programs and used localtime()
  78. Xinstead.  It does the job, since the returned value is used only to seed
  79. Xthe random number generator, and it's portable.
  80. X
  81. XI installed a bugfix in the termcap stuff while I was at it; the original
  82. Xauthor apparently didn't understand how the "bs" and "bc" attributes work.
  83. XI've fixed that so it should work as per termcap(4).
  84. X
  85. XThrough the magic of "sdiff" and the fact that "sol" and "solx" are basically
  86. Xderived from the same original source code, I have made the same changes to
  87. X"solx".  Again, they work here.
  88. X
  89. XI haven't tested this under BSD (I don't have a BSD system available to me)
  90. Xso I may have broken something under BSD.  The game does successfully auto-
  91. Xconfigure for System III and System V, and works fine.  (It also uses termio
  92. Xon these systems, so "echoe" gets reset properly.) Presumably it will work
  93. Xproperly under Xenix 3 and Xenix 5, but I can't test it.
  94. X
  95. XHave fun with "sol" and "solx".
  96. X
  97. X++Brandon
  98. X
  99. X(author's original README included below)
  100. X===============================================================================
  101. X
  102. XSources for two solitaire games - a while back someone posted some sources
  103. Xin some language or other that played solitaire. With about two evenings
  104. Xwoth of work that became sol.c - standard solitaire. To compile either game
  105. X(under BSD4.3) use a command like 'cc -o sol sol.c -ltermcap' or
  106. X'cc -o solx solx.c -ltermcap' - you'll have to adjust on Xenix for termcap
  107. Xetc. etc. etc. solx.c is a different solitaire game, and a lot more
  108. Xdifficult to get out. You start with 1 run containing a single card
  109. X(#1 in the game), then hidden piles 2 thru 7, containing 2 thru 7 cards
  110. Xrespectively. The remaining 24 cards are dealt on runs 2 thru 7 - four
  111. Xin each run. There is no deck - all you can do is to move runs around.
  112. XUnlike regular solitaire, runs can be split, hence the altered move
  113. Xcommand, and since runs can get a bit long (I've seen them as big as
  114. X22-23 cards) I've turned the display on it's side. Both games have several
  115. Xcheats, and an autopilot, although the autopilot for solx is not very clever.
  116. XIn order to prevent thrashing of runs I coded it so that it will only move
  117. Xa run if the top card being moved was not already placed. However there
  118. Xare times when such an apparently redundant move is necessary to get out.
  119. X
  120. XBest of luck, and have fun.
  121. X--
  122. X        dg@wrs.UUCP - David Goodenough
  123. X
  124. X                    +---+
  125. X                    | +-+-+
  126. X                    +-+-+ |
  127. X                      +---+
  128. END_OF_README
  129. if test 2976 -ne `wc -c <README`; then
  130.     echo shar: \"README\" unpacked with wrong size!
  131. fi
  132. # end of overwriting check
  133. fi
  134. if test -f Makefile -a "${1}" != "-c" ; then 
  135.   echo shar: Will not over-write existing file \"Makefile\"
  136. else
  137. echo shar: Extracting \"Makefile\" \(450 characters\)
  138. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  139. X# Makefile for soliaire games
  140. XSHELL = /bin/sh
  141. XCFLAGS = -O
  142. X# TERMINFOFLAGS = -DTERMINFO
  143. X# TERMINFOLIBS = -lcurses
  144. XTERMINFOLIBS = -ltermcap
  145. X#
  146. X# Uncomment the top two TERMINFO lines above and comment the third out if
  147. X# you compile this with terminfo's termcap emulation.
  148. X#
  149. X
  150. XGAMES = sol solx
  151. X
  152. Xall:    $(GAMES)
  153. Xsol:    sol.c
  154. X    cc $(CFLAGS) $(TERMINFOFLAGS) -o sol sol.c $(TERMINFOLIBS)
  155. X
  156. Xsolx:    solx.c
  157. X    cc $(CFLAGS) $(TERMINFOFLAGS) -o solx solx.c $(TERMINFOLIBS)
  158. END_OF_Makefile
  159. if test 450 -ne `wc -c <Makefile`; then
  160.     echo shar: \"Makefile\" unpacked with wrong size!
  161. fi
  162. # end of overwriting check
  163. fi
  164. if test -f sol.c -a "${1}" != "-c" ; then 
  165.   echo shar: Will not over-write existing file \"sol.c\"
  166. else
  167. echo shar: Extracting \"sol.c\" \(18166 characters\)
  168. sed "s/^X//" >sol.c <<'END_OF_sol.c'
  169. X#include    <stdio.h>
  170. X#include    <signal.h>
  171. X#ifdef SIGVTALRM
  172. X#include    <sys/time.h>
  173. X#else
  174. X#include    <time.h>
  175. X#endif SIGVTALRM
  176. X#include    <sys/types.h>
  177. X#include    <sys/stat.h>
  178. X#include    <sys/ioctl.h>
  179. X#ifdef TCGETA
  180. X#include    <termio.h>
  181. X#define        sgttyb    termio
  182. X#endif TCGETA
  183. X
  184. X#define     TRUE    1
  185. X#define        FALSE    0
  186. X
  187. Xint    amode;
  188. Xint    cnt;
  189. Xint    cheat;
  190. Xint    deck[53];
  191. Xint    over[53];
  192. Xint    ace[4][14];
  193. Xint    run[7][14];
  194. Xint    hidden[7][8];
  195. Xchar    cmd[40], *cp;
  196. Xchar    *resgb;
  197. X
  198. Xextern    char    PC;
  199. Xextern    char    BC[2];
  200. Xextern    char    UP[2];
  201. X
  202. Xchar    *sc_bs;
  203. Xchar    *sc_move;
  204. Xchar    *sc_clear;
  205. Xchar    *sc_cleol;
  206. Xchar    *sc_init;
  207. Xchar    *sc_deinit;
  208. Xchar    *sc_s_in;
  209. Xchar    *sc_s_out;
  210. X
  211. X#ifndef TERMINFO
  212. Xextern    short    ospeed;
  213. X#endif  TERMINFO
  214. X
  215. Xextern    struct tm    *localtime();
  216. Xextern    char        *getenv();
  217. Xextern    unsigned int    sleep();
  218. Xextern    long        time();
  219. X
  220. Xmain(n, a)
  221. Xchar **a;
  222. X {
  223. X    int i, p, c, r, s;
  224. X    long now;
  225. X    struct tm *tp;
  226. X    int from;
  227. X    int dest;
  228. X    int brkflg;
  229. X
  230. X    amode = 0;
  231. X    (void) time(&now);
  232. X    tp = localtime(&now);
  233. X    srand((unsigned) (getpid() + tp->tm_sec));
  234. X    rawmode(TRUE);
  235. X    setsig(TRUE);
  236. X    getterm();
  237. X    init();
  238. X    for (i = 0; i < 52; i++)
  239. X      deck[i] = i;
  240. X    deck[52] = -1;
  241. X    shuffle(deck);
  242. X    for (i = 0; i < 4; i++)
  243. X      ace[i][0] = -1;
  244. X    for (i = 0; i < 7; i++)
  245. X      hidden[i][0] = run[i][0] = -1;
  246. X    over[0] = -1;
  247. X    for (p = 0; p < 7; p++)
  248. X      for (c = p; c < 7; c++)
  249. X    put(hidden[c],get(deck));
  250. X    for (r = 0; r < 7; r++)
  251. X      put(run[r],get(hidden[r]));
  252. X    redraw(TRUE);
  253. X    for (r = 0; r < 7; r++)
  254. X     {
  255. X    while (getvalue(run[r][0]) == 0)
  256. X     {
  257. X        s = getsuit(run[r][0]);
  258. X        put(ace[s],get(run[r]));
  259. X        put(run[r],get(hidden[r]));
  260. X        redraw(FALSE);
  261. X     }
  262. X     }
  263. X    cnt = cheat = 0;
  264. X    if (n > 1 && !strcmp(a[1], "auto"))
  265. X      autopilot();
  266. X    brkflg = 1;
  267. X    while (brkflg)
  268. X     {
  269. X    cnt++;
  270. X    do
  271. X     {
  272. X        moveto(17, 0);
  273. X        (void) printf("cmd:%d> ", cnt);
  274. X        cleol();
  275. X        (void) fflush(stdout);
  276. X     } while (!getst(cp = cmd));
  277. X    while (*cp == ' ' || *cp == '\t')
  278. X      cp++;
  279. X    switch (*cp++)
  280. X     {
  281. X        case 'a':
  282. X          autopilot();
  283. X        break;
  284. X        case 'm':
  285. X         {
  286. X        while (*cp == ' ' || *cp == '\t')
  287. X          cp++;
  288. X        if (!(from = *cp++) || ((from < '1' || from > '7') &&
  289. X                                from != 'd'))
  290. X         {
  291. X            whoops();
  292. X            continue;
  293. X         }
  294. X        while (*cp == ' ' || *cp == '\t')
  295. X          cp++;
  296. X        if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
  297. X                dest != 'a') || !movecard(from, dest, FALSE))
  298. X         {
  299. X            whoops();
  300. X            continue;
  301. X         }
  302. X        if (cardsleft() == 0)
  303. X          finish();
  304. X         }
  305. X        break;
  306. X        case 't':
  307. X        case 0:
  308. X          thumb();
  309. X        break;
  310. X        case 'h':
  311. X        case '?':
  312. X          disphelp();
  313. X        break;
  314. X        case 'r':
  315. X          disprules();
  316. X        break;
  317. X        case 'q':
  318. X          brkflg = 0;
  319. X        break;
  320. X        case 's':
  321. X         {
  322. X        while (peek(over) != -1)
  323. X          put(deck, get(over));
  324. X        shuffle(deck);
  325. X        redraw(FALSE);
  326. X        cheat++;
  327. X         }
  328. X        break;
  329. X        case 'p':
  330. X         {
  331. X        while (*cp == ' ' || *cp == '\t')
  332. X          cp++;
  333. X        if (!(from = *cp++) || from < '1' || from > '7')
  334. X         {
  335. X            whoops();
  336. X            continue;
  337. X         }
  338. X            if (hidden[from -= '1'][0] != -1)
  339. X         {
  340. X            while (hidden[from][0] != -1)
  341. X              put(deck, get(hidden[from]));
  342. X            redraw(FALSE);
  343. X            cheat++;
  344. X         }
  345. X        else
  346. X          whoops();
  347. X         }
  348. X        break;
  349. X        case 'd':
  350. X         {
  351. X        moveto(19, 0);
  352. X        (void) printf("%d cards in deck:\n", lstlen(deck) + lstlen(over));
  353. X        i = lstlen(deck);
  354. X        while (--i != -1)
  355. X         {
  356. X            pcard(deck[i]);
  357. X            (void) putchar(' ');
  358. X         }
  359. X        (void) putchar('\n');
  360. X        for (i = 0; over[i] != -1; i++)
  361. X         {
  362. X            pcard(over[i]);
  363. X            (void) putchar(' ');
  364. X         }
  365. X        (void) printf("\nHit return -");
  366. X        (void) fflush(stdout);
  367. X        (void) getcx();
  368. X        moveto(19, 0);
  369. X        for (i = 0; i < 4; i++)
  370. X         {
  371. X            cleol();
  372. X            (void) putchar('\n');
  373. X         }
  374. X        cheat++;
  375. X         }
  376. X        break;
  377. X        case 'w':
  378. X         {
  379. X        while (*cp == ' ' || *cp == '\t')
  380. X          cp++;
  381. X        if (!(from = *cp++) || from < '1' || from > '7')
  382. X         {
  383. X            whoops();
  384. X            continue;
  385. X         }
  386. X        moveto(19, 0);
  387. X        from -= '1';
  388. X        (void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
  389. X                                from + '1');
  390. X        for (i = 0; hidden[from][i] != -1; i++)
  391. X         {
  392. X            pcard(hidden[from][i]);
  393. X            (void) putchar(' ');
  394. X         }
  395. X        (void) printf("\nHit return -");
  396. X        (void) fflush(stdout);
  397. X        (void) getcx();
  398. X        moveto(19,0);
  399. X        for (i = 0; i < 4; i++)
  400. X         {
  401. X            cleol();
  402. X            (void) putchar('\n');
  403. X         }
  404. X        cheat++;
  405. X         }
  406. X        break;
  407. X        default:
  408. X          whoops();
  409. X        break;
  410. X     }
  411. X     }
  412. X    moveto(19, 0);
  413. X    cleol();
  414. X    (void) printf("I see you gave up\n");
  415. X    if (cheat > 0)
  416. X      (void) printf("    ... even after you cheated %d times!\n", cheat);
  417. X    else
  418. X      (void) printf("    ... but at least you didn't cheat...congratulations!\n");
  419. X    unwind();
  420. X }
  421. X
  422. Xunwind()
  423. X {
  424. X    moveto(23, 0);
  425. X    deinit();
  426. X    rawmode(FALSE);
  427. X    exit(0);
  428. X }
  429. X
  430. Xmovecard(from,dest,limitmove)
  431. X {
  432. X    if (from == dest)
  433. X      return(FALSE);
  434. X    if (from == 'd')
  435. X      return(dest == 'a' ? deck2ace() : deck2run(dest));
  436. X    else
  437. X      return(dest == 'a' ? run2ace(from) : run2run(from,dest,limitmove));
  438. X }
  439. X
  440. Xdeck2run(dest)
  441. X {
  442. X    int fcard, dcard, s, ok;
  443. X
  444. X    if ((fcard = peek(over)) == -1)
  445. X      return(FALSE);
  446. X    dcard = peek(run[dest -= '1']);
  447. X    if (ok = chk2run(fcard,dcard))
  448. X     {
  449. X    put(run[dest],get(over));
  450. X    redraw(FALSE);
  451. X    while (getvalue(peek(over)) == 0)
  452. X     {
  453. X        s = getsuit(peek(over));
  454. X        put(ace[s],get(over));
  455. X        redraw(FALSE);
  456. X     }
  457. X     }
  458. X    return(ok);
  459. X }
  460. X
  461. Xdeck2ace()
  462. X {
  463. X    int fcard, s, ok;
  464. X
  465. X    if (ok = (fcard = peek(over)) != -1 &&
  466. X        getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  467. X     {
  468. X    put(ace[s], get(over));
  469. X    redraw(FALSE);
  470. X    while (getvalue(peek(over)) == 0)
  471. X     {
  472. X        s = getsuit(peek(over));
  473. X        put(ace[s],get(over));
  474. X        redraw(FALSE);
  475. X     }
  476. X     }
  477. X    return(ok);
  478. X }
  479. X
  480. Xrun2ace(from)
  481. X {
  482. X    int fcard, s, ok;
  483. X
  484. X    fcard = peek(run[from -= '1']);
  485. X    if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  486. X     {
  487. X    put(ace[s], get(run[from]));
  488. X    redraw(FALSE);
  489. X    if (run[from][0] == -1 && hidden[from][0] >= 0)
  490. X     {
  491. X        while (getvalue(peek(hidden[from])) == 0)
  492. X         {
  493. X        s = getsuit(peek(hidden[from]));
  494. X        put(ace[s],get(hidden[from]));
  495. X        redraw(FALSE);
  496. X         }
  497. X        put(run[from],get(hidden[from]));
  498. X        redraw(FALSE);
  499. X     }
  500. X     }
  501. X    return(ok);
  502. X }
  503. X
  504. Xrun2run(from,dest,limitmove)
  505. X {
  506. X    int fcard, dcard, i, ok, s;
  507. X
  508. X    if ((fcard = run[from -= '1'][0]) == -1)
  509. X      return(FALSE);
  510. X    dcard = peek(run[dest -= '1']);
  511. X    if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
  512. X                        lstlen(hidden[from]) == 0)
  513. X      return(FALSE);
  514. X    if (amode > 0 && !limitmove && lstlen(hidden[from]) == 0)
  515. X      return(FALSE);
  516. X    if (ok = chk2run(fcard,dcard))
  517. X     {
  518. X    for (i = 0; run[from][i] != -1; i++)
  519. X      put(run[dest], run[from][i]);
  520. X    run[from][0] = -1;
  521. X    redraw(FALSE);
  522. X    if (lstlen(hidden[from]) > 0)
  523. X     {
  524. X        while (getvalue(peek(hidden[from])) == 0)
  525. X         {
  526. X        s = getsuit(peek(hidden[from]));
  527. X        put(ace[s],get(hidden[from]));
  528. X        redraw(FALSE);
  529. X         }
  530. X        put(run[from],get(hidden[from]));
  531. X        redraw(FALSE);
  532. X     }
  533. X     }
  534. X    return(ok);
  535. X }
  536. X
  537. Xchk2run(fcard,dcard)
  538. X {
  539. X    if (dcard == -1 && getvalue(fcard) == 12)
  540. X      return(TRUE);
  541. X    return(getvalue(dcard) - 1 == getvalue(fcard) &&
  542. X                getcolour(dcard) != getcolour(fcard));
  543. X }
  544. X
  545. Xfinish()
  546. X {
  547. X    int i, k;
  548. X
  549. X    moveto(19,0);
  550. X    (void) printf("\007I'll finish for you now\007");
  551. X    (void) fflush(stdout);
  552. X    do
  553. X     {
  554. X    k = FALSE;
  555. X    for (i = 0; i < 7; i++)
  556. X      k = movecard(i + '1', 'a', FALSE) || k;
  557. X     } while (k);
  558. X    moveto(20,0);
  559. X    cleol();
  560. X    (void) printf("\007You WIN\007\n");
  561. X    if (cheat > 0)
  562. X      (void) printf("    ... but you cheated %d times!", cheat);
  563. X    else
  564. X      (void) printf("    ... and without cheating ... congratulations!");
  565. X    unwind();
  566. X }
  567. X
  568. Xautopilot()
  569. X {
  570. X    int i, j, k;
  571. X    int iter;
  572. X
  573. X    moveto(19,0);
  574. X    (void) printf("Going into automatic mode...");
  575. X    (void) fflush(stdout);
  576. X    amode = TRUE;
  577. X    while (cardsleft() > 0)
  578. X     {
  579. X    k = FALSE;
  580. X         iter = 0;
  581. X    for (i = 0; i < 7; i++)
  582. X      for (j = 0; j < 7; j++)
  583. X        k = movecard(i + '1', j + '1', TRUE) || k;
  584. X    for (i = 0; i < 7; i++)
  585. X     {
  586. X        k = movecard(i + '1', 'a', FALSE) || k;
  587. X        k = movecard('d', i + '1', FALSE) || k;
  588. X     }
  589. X    k = movecard('d', 'a', FALSE) || k;
  590. X    if (!k)
  591. X     {
  592. X        if (iter--)
  593. X          thumb();
  594. X        else
  595. X          break;
  596. X     }
  597. X    else
  598. X      iter = lstlen(over) + lstlen(deck);
  599. X     }
  600. X    do
  601. X     {
  602. X    k = FALSE;
  603. X    for (i = 0; i < 7; i++)
  604. X      k = movecard(i + '1', 'a', FALSE) || k;
  605. X     } while (k);
  606. X    moveto(19, 28);
  607. X    if (cardsleft() == 0)
  608. X     {
  609. X    (void) printf("\007YEA...\007");
  610. X    (void) fflush(stdout);
  611. X    for (i = 0; i < 7; i++)
  612. X      if (movecard(i + '1', 'a', FALSE));
  613. X    moveto(19, 34);
  614. X    (void) printf("I won!!!!!");
  615. X     }
  616. X    else
  617. X     {
  618. X    (void) printf("I couldn't win this time");
  619. X    moveto(20, 0);
  620. X    (void) printf("%d cards in deck", lstlen(deck) + lstlen(over));
  621. X     }
  622. X    unwind();
  623. X }
  624. X
  625. Xredraw(display)
  626. X {
  627. X    static long_run[7];
  628. X    static long_hide[7];
  629. X    static long_ace[4];
  630. X    static base_run[7];
  631. X
  632. X    int i, j;
  633. X
  634. X    if (display)
  635. X     {
  636. X    clear();
  637. X    for (i = 0; i < 7; i++)
  638. X     {
  639. X        long_run[i] = long_hide[i] = base_run[i] = -1;
  640. X        moveto(0, 8 + i * 5);
  641. X        (void) putchar(i + '1');
  642. X     }
  643. X    for (i = 0; i < 4; i++)
  644. X      long_ace[i] = -1;
  645. X    moveto(0,56);
  646. X    (void) printf("ACES");
  647. X    moveto(6,56);
  648. X    (void) printf("DECK");
  649. X     }
  650. X    for (i = 0; i < 7; i++)
  651. X     {
  652. X    if (long_hide[i] != lstlen(hidden[i]))
  653. X     {
  654. X        moveto(2, 8 + i * 5);
  655. X        (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
  656. X        long_hide[i] = lstlen(hidden[i]);
  657. X     }
  658. X     }
  659. X    for (i = 0; i < 4; i++)
  660. X     {
  661. X    if (long_ace[i] != lstlen(ace[i]))
  662. X     {
  663. X        moveto(2, 49 + i * 5);
  664. X        if (ace[i][0] != -1)
  665. X          pcard(peek(ace[i]));
  666. X        else
  667. X          (void) printf("--");
  668. X        long_ace[i] = lstlen(ace[i]);
  669. X     }
  670. X     }
  671. X    moveto(8, 55);
  672. X    (void) printf(lstlen(deck) ? "##  " : "    ");
  673. X    if (lstlen(over))
  674. X      pcard(peek(over));
  675. X    else
  676. X      (void) printf("  ");
  677. X    for (i = 0; i < 7; i++)
  678. X     {
  679. X    if (long_run[i] != lstlen(run[i]) ||
  680. X                (long_run[i] == 1 && base_run[i] != run[i][0]))
  681. X     {
  682. X        for (j = 0; run[i][j] != -1; j++)
  683. X         {
  684. X        moveto(j + 4, 7 + i * 5);
  685. X        if (run[i][j] == -1)
  686. X          (void) printf("  ");
  687. X        else
  688. X          pcard(run[i][j]);
  689. X         }
  690. X        while (j < long_run[i])
  691. X         {
  692. X        moveto(j++ + 4, 7 + i * 5);
  693. X        (void) printf("  ");
  694. X         }
  695. X        long_run[i] = lstlen(run[i]);
  696. X        base_run[i] = run[i][0];
  697. X     }
  698. X     }
  699. X    (void) fflush(stdout);
  700. X    (void) sleep(1);
  701. X }
  702. X
  703. Xthumb()
  704. X {
  705. X    int i, s;
  706. X
  707. X    if (deck[0] == -1)
  708. X     {
  709. X    if (over[0] == -1)
  710. X      return;
  711. X    while (over[0] != -1)
  712. X      put(deck, get(over));
  713. X     }
  714. X    for (i = 0; i < 3; i++)
  715. X      if (deck[0] != -1)
  716. X    put(over,get(deck));
  717. X    redraw(FALSE);
  718. X    while (getvalue(peek(over)) == 0)
  719. X     {
  720. X    s = getsuit(peek(over));
  721. X    put(ace[s], get(over));
  722. X    redraw(FALSE);
  723. X     }
  724. X    if (over[0] == -1 && deck[0] != -1)
  725. X      thumb();
  726. X }
  727. X
  728. Xpcard(card)
  729. X {
  730. X    int i;
  731. X
  732. X    if ((i = getcolour(card)) != 0)
  733. X      standout();
  734. X    (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
  735. X    if (i)
  736. X      standend();
  737. X }
  738. X
  739. X
  740. Xgetvalue(card)
  741. X {
  742. X    return(card % 13);
  743. X }
  744. X
  745. Xgetsuit(card)
  746. X {
  747. X    return(card / 13);
  748. X }
  749. X
  750. Xgetcolour(card)
  751. X {
  752. X    return(card / 26);
  753. X }
  754. X
  755. Xcardsleft()
  756. X {
  757. X    int i, t;
  758. X
  759. X    t = lstlen(deck) + lstlen(over);
  760. X    for (i = 0; i < 7; i++)
  761. X      t += lstlen(hidden[i]);
  762. X    return(t);
  763. X }
  764. X
  765. Xwhoops()
  766. X {
  767. X    moveto(17,0);
  768. X    (void) printf("\007Invalid Command: '%s'\007", cmd);
  769. X    (void) fflush(stdout);
  770. X    (void) sleep(4);
  771. X }
  772. X
  773. X
  774. Xdisphelp()
  775. X {
  776. X    clear();
  777. X    (void) printf("\
  778. XCommands: t or RETURN     : thumb the deck 3 cards at a time\n\
  779. X          m [d1-7] [1-7a] : move cards or runs\n\
  780. X          a               : turn on the auto pilot (in case you get stuck)\n\
  781. X          s               : shuffle the deck (cheat!)\n\
  782. X          p [2-7]         : put a hidden pile into the deck (cheat!)\n\
  783. X          d               : print the cards in the deck (cheat!)\n\
  784. X          w [2-7]         : print the cards in a hidden pile (cheat!)\n\
  785. X          h or ?          : print this command summary\n\
  786. X          r               : print the rules of the game\n\
  787. X          q               : quit\n\n");
  788. X    (void) printf("\
  789. XMoving:   1-7, 'd', or 'a' select the source and destination for a move.\n\
  790. X          Valid moves are from a run to a run, from the deck to a run,\n\
  791. X          from a run to an ace pile, and from the deck to an ace pile.\n\n\
  792. XCheating: Commands that allow cheating are available but they will count\n\
  793. X          against you in your next life!\n\n\nHit Return -");
  794. X    (void) fflush(stdout);
  795. X    (void) getcx();
  796. X    redraw(TRUE);
  797. X }
  798. X
  799. Xdisprules()
  800. X {
  801. X    clear();
  802. X    (void) printf("\
  803. XObject:   The object of this game is to get all of the cards in each suit\n\
  804. X          in order on the proper ace pile.\n\n\
  805. XRules:    Cards are played on the ace piles in ascending order: A,2,...,K. \n\
  806. X          All aces are automatically placed in the correct aces pile as\n\
  807. X          they're found in the deck or in a pile of hidden cards.  Once a\n\
  808. X          card is placed in an ace pile it can't be removed.\n\n");
  809. X    (void) printf("\
  810. X          Cards must be played in descending order: K,Q,..,2, on the seven\n\
  811. X          runs which are initially dealt.  They must always be played on a\n\
  812. X          card of the opposite color.  Runs must always be moved as a\n\
  813. X          whole, unless you're moving the lowest card on a run to the\n\
  814. X          correct ace pile.\n\n");
  815. X    (void) printf("\
  816. X          Whenever a whole run is moved, the top hidden card is turned\n\
  817. X          over, thus becoming the beginning of a new run.  If there are no\n\
  818. X          hidden cards left, a space is created which can only be filled by\n\
  819. X          a king.\n\n\
  820. X          The rest of the deck is thumbed 3 cards at a time, until you spot a\n\
  821. X          valid move.  Whenever the bottom of the deck is reached, the cards\n\
  822. X          are turned over and you can continue thumbing.\n\n\nHit Return -");
  823. X    (void) fflush(stdout);
  824. X    (void) getcx();
  825. X    redraw(TRUE);
  826. X }
  827. X
  828. Xgetst(getbuf)
  829. Xchar *getbuf;
  830. X {
  831. X    int ch;
  832. X    int nc;
  833. X
  834. X    *(resgb = getbuf) = nc = 0;
  835. X    for (;;)
  836. X     {
  837. X    if ((((ch = getcx()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
  838. X     {
  839. X        *getbuf++ = ch;
  840. X        *getbuf = 0;
  841. X        nc++;
  842. X        (void) putchar(ch);
  843. X        (void) fflush(stdout);
  844. X     }
  845. X    else if (ch == '\b')
  846. X     {
  847. X        if (nc--)
  848. X         {
  849. X            *--getbuf = 0;
  850. X        (void) printf("\b \b");
  851. X        (void) fflush(stdout);
  852. X         }
  853. X        else
  854. X          return(FALSE);
  855. X     }
  856. X    else if (ch == ('r' & 0x1f))
  857. X      redraw(TRUE);
  858. X    else if (ch == '\n')
  859. X      return(TRUE);
  860. X     }
  861. X }
  862. X
  863. Xshuffle(cards)
  864. Xint *cards;
  865. X {
  866. X    int i, j, k, t;
  867. X
  868. X    for (i = 0; cards[i] != -1; i++)
  869. X      ;
  870. X    if (i)
  871. X     {
  872. X    for (j = 0; j < i; j++)
  873. X     {
  874. X        do
  875. X          k = rnd(i);
  876. X         while (k == j);
  877. X        t = cards[j];
  878. X        cards[j] = cards[k];
  879. X        cards[k] = t;
  880. X     }
  881. X     }
  882. X }
  883. X
  884. Xrnd(n)
  885. X {
  886. X    return(((rand() >> 12 | rand() >> 24) & (unsigned) ~0 >> 1) % n);
  887. X }
  888. X
  889. Xlstlen(list)
  890. Xint *list;
  891. X {
  892. X    int i;
  893. X
  894. X    for (i = 0; list[i] != -1; i++)
  895. X      ;
  896. X    return(i);
  897. X }
  898. X
  899. X#ifdef SIGTSTP
  900. X
  901. Xrestart()
  902. X {
  903. X    setsig(TRUE);
  904. X    rawmode(TRUE);
  905. X    redraw(TRUE);
  906. X    moveto(17, 0);
  907. X    (void) printf("cmd:%d> ", cnt);
  908. X    cleol();
  909. X    (void) printf("%s", resgb);
  910. X    (void) fflush(stdout);
  911. X }
  912. X
  913. X#endif SIGTSTP
  914. X
  915. Xsetsig(on)
  916. X {
  917. X    (void) signal(SIGINT, on ? SIG_IGN : SIG_DFL);
  918. X    (void) signal(SIGQUIT, on ? SIG_IGN : SIG_DFL);
  919. X    (void) signal(SIGTERM, on ? SIG_IGN : SIG_DFL);
  920. X#ifdef SIGTSTP
  921. X    (void) signal(SIGTSTP, on ? SIG_IGN : SIG_DFL);
  922. X    (void) signal(SIGCONT, on ? restart : SIG_DFL);
  923. X#endif
  924. X }
  925. X
  926. Xstop()
  927. X {
  928. X    setsig(FALSE);
  929. X    rawmode(FALSE);
  930. X#ifdef SIGTSTP
  931. X    (void) signal(SIGCONT, restart);
  932. X    kill(getpid(), SIGTSTP);
  933. X#else
  934. X    (void) system("eval exec ${SHELL-/bin/sh}");
  935. X#endif SIGTSTP
  936. X }
  937. X
  938. Xgetcx()
  939. X {
  940. X    char ch;
  941. X
  942. X#ifdef SIGTSTP
  943. X    (void) signal(SIGTSTP, stop);
  944. X#else
  945. X    for (;;) {
  946. X#endif SIGTSTP
  947. X        (void) read(0, &ch, 1);
  948. X#ifdef SIGTSTP
  949. X        (void) signal(SIGTSTP, SIG_IGN);
  950. X#else
  951. X        if (ch != '\032')
  952. X            break;
  953. X        stop();
  954. X    }
  955. X#endif SIGTSTP
  956. X    return(ch);
  957. X }
  958. X
  959. Xrawmode(on)
  960. X {
  961. X    struct sgttyb s;
  962. X    static struct sgttyb saveterm;
  963. X    static int saved = FALSE;
  964. X
  965. X    if (on)
  966. X     {
  967. X#ifdef TCGETA
  968. X         (void) ioctl(0, TCGETA, &s);
  969. X#else
  970. X    (void) ioctl(0, TIOCGETP, &s);
  971. X#endif TCGETA
  972. X    if (saved == FALSE)
  973. X     {
  974. X        saveterm = s;
  975. X        saved = TRUE;
  976. X     }
  977. X#ifdef TCGETA
  978. X#ifndef TERMINFO
  979. X         ospeed = s.c_cflag & CBAUD;
  980. X#endif  TERMINFO
  981. X         s.c_lflag &= ~(ECHO|ICANON);
  982. X         s.c_oflag &= ~TAB3;
  983. X         s.c_cc[VMIN] = 1;
  984. X         s.c_cc[VTIME] = 1;
  985. X#else
  986. X    ospeed = s.sg_ospeed;
  987. X    s.sg_flags |= CBREAK;
  988. X    s.sg_flags &= ~(ECHO|XTABS);
  989. X#endif TCGETA
  990. X     }
  991. X    else
  992. X      s = saveterm;
  993. X#ifdef TCGETA
  994. X    (void) ioctl(0, TCSETAW, &s);
  995. X#else
  996. X    (void) ioctl(0, TIOCSETN, &s);
  997. X#endif
  998. X }
  999. X
  1000. Xgetterm()
  1001. X {
  1002. X    char termbuf[1024];
  1003. X    char *sp;
  1004. X    static char sbuf[150];
  1005. X    char *tgetstr();
  1006. X
  1007. X    tgetent(termbuf, getenv("TERM"));
  1008. X    sp = sbuf;
  1009. X
  1010. X    PC = *(tgetstr("pc", &sp));
  1011. X    *UP = *(tgetstr("pc", &sp));
  1012. X    UP[1] = 0;
  1013. X    if (!tgetflag("bs"))
  1014. X        *BC = *(sc_bs = tgetstr("bc", &sp));
  1015. X    else {
  1016. X        *BC = '\b';
  1017. X        sc_bs = BC;
  1018. X    }
  1019. X    BC[1] = 0;
  1020. X    sc_init = tgetstr("ti", &sp);
  1021. X    sc_deinit = tgetstr("te", &sp);
  1022. X    sc_cleol = tgetstr("ce", &sp);
  1023. X    sc_clear = tgetstr("cl", &sp);
  1024. X    sc_move = tgetstr("cm", &sp);
  1025. X    sc_s_in = tgetstr("so", &sp);
  1026. X    sc_s_out = tgetstr("se", &sp);
  1027. X }
  1028. X
  1029. Xxputc(c)
  1030. Xregister c;
  1031. X {
  1032. X    (void) putchar(c);
  1033. X }
  1034. X
  1035. Xinit()
  1036. X {
  1037. X    tputs(sc_init, 24, xputc);
  1038. X }
  1039. X
  1040. Xdeinit()
  1041. X {
  1042. X    tputs(sc_deinit, 24, xputc);
  1043. X }
  1044. X
  1045. Xclear()
  1046. X {
  1047. X    tputs(sc_clear, 24, xputc);
  1048. X }
  1049. X
  1050. Xcleol()
  1051. X {
  1052. X    tputs(sc_cleol, 1, xputc);
  1053. X }
  1054. X
  1055. Xstandout()
  1056. X {
  1057. X    tputs(sc_s_in, 1, xputc);
  1058. X }
  1059. X
  1060. Xstandend()
  1061. X {
  1062. X    tputs(sc_s_out, 1, xputc);
  1063. X }
  1064. X
  1065. Xmoveto(y, x)
  1066. X {
  1067. X    char *tgoto();
  1068. X
  1069. X    tputs(tgoto(sc_move, x, y), 1, xputc);
  1070. X }
  1071. X
  1072. Xput(dest, item)
  1073. Xint *dest;
  1074. X {
  1075. X    if (item == -1)
  1076. X      return;
  1077. X    while (*dest != -1)
  1078. X      dest++;
  1079. X    *dest++ = item;
  1080. X    *dest = -1;
  1081. X }
  1082. X
  1083. Xget(source)
  1084. Xint *source;
  1085. X {
  1086. X    int i;
  1087. X
  1088. X    for (i = 0; *source != -1; i++, source++)
  1089. X      ;
  1090. X    if (i)
  1091. X     {
  1092. X    i = *--source;
  1093. X    *source = -1;
  1094. X    return(i);
  1095. X     }
  1096. X    return(-1);
  1097. X }
  1098. X
  1099. Xpeek(source)
  1100. Xint *source;
  1101. X {
  1102. X    int i;
  1103. X
  1104. X    for (i = 0; source[i] != -1; i++)
  1105. X      ;
  1106. X    return(i ? source[i - 1] : -1);
  1107. X }
  1108. END_OF_sol.c
  1109. if test 18166 -ne `wc -c <sol.c`; then
  1110.     echo shar: \"sol.c\" unpacked with wrong size!
  1111. fi
  1112. # end of overwriting check
  1113. fi
  1114. if test -f solx.c -a "${1}" != "-c" ; then 
  1115.   echo shar: Will not over-write existing file \"solx.c\"
  1116. else
  1117. echo shar: Extracting \"solx.c\" \(16202 characters\)
  1118. sed "s/^X//" >solx.c <<'END_OF_solx.c'
  1119. X#include    <stdio.h>
  1120. X#include    <ctype.h>
  1121. X#include    <signal.h>
  1122. X#ifdef SIGVTALRM
  1123. X#include    <sys/time.h>
  1124. X#else
  1125. X#include    <time.h>
  1126. X#endif SIGVTALRM
  1127. X#include    <sys/types.h>
  1128. X#include    <sys/stat.h>
  1129. X#include    <sys/ioctl.h>
  1130. X#ifdef TCGETA
  1131. X#include    <termio.h>
  1132. X#define        sgttyb    termio
  1133. X#endif TCGETA
  1134. X
  1135. X#define     TRUE    1
  1136. X#define        FALSE    0
  1137. X
  1138. Xint    amode;
  1139. Xint    cnt;
  1140. Xint    cheat;
  1141. Xint    deck[53];
  1142. Xint    ace[4][14];
  1143. Xint    run[7][53];
  1144. Xint    hidden[7][8];
  1145. Xchar    cmd[40], *cp;
  1146. Xchar    *resgb;
  1147. X
  1148. Xextern    char    PC;
  1149. Xextern    char    BC[2];
  1150. Xextern    char    UP[2];
  1151. X
  1152. Xchar    *sc_bs;
  1153. Xchar    *sc_move;
  1154. Xchar    *sc_clear;
  1155. Xchar    *sc_cleol;
  1156. Xchar    *sc_init;
  1157. Xchar    *sc_deinit;
  1158. Xchar    *sc_s_in;
  1159. Xchar    *sc_s_out;
  1160. X
  1161. X#ifndef TERMINFO
  1162. Xextern    short    ospeed;
  1163. X#endif  TERMINFO
  1164. X
  1165. Xint    long_run[7];
  1166. Xint    long_hide[7];
  1167. Xint    long_ace[4];
  1168. Xint    base_run[7];
  1169. X
  1170. Xextern    struct tm    *localtime();
  1171. Xextern    char        *getenv();
  1172. Xextern    long        time();
  1173. Xextern    unsigned int    sleep();
  1174. X
  1175. Xmain(n, a)
  1176. Xchar **a;
  1177. X {
  1178. X    int i, p, c, r, s;
  1179. X    long now;
  1180. X    struct tm *tp;
  1181. X    int from;
  1182. X    int split;
  1183. X    int dest;
  1184. X    int brkflg;
  1185. X
  1186. X    amode = 0;
  1187. X    (void) time(&now);
  1188. X    tp = localtime(&now);
  1189. X    srand((unsigned) (getpid() + tp->tm_sec));
  1190. X    rawmode(TRUE);
  1191. X    setsig(TRUE);
  1192. X    getterm();
  1193. X    init();
  1194. X    for (i = 0; i < 52; i++)
  1195. X      deck[i] = i;
  1196. X    deck[52] = -1;
  1197. X    shuffle(deck);
  1198. X    for (i = 0; i < 4; i++)
  1199. X      ace[i][0] = -1;
  1200. X    for (i = 0; i < 7; i++)
  1201. X      hidden[i][0] = run[i][0] = -1;
  1202. X    for (p = 0; p < 7; p++)
  1203. X      for (c = p; c < 7; c++)
  1204. X    put(hidden[c],get(deck));
  1205. X    put(run[0], get(hidden[0]));
  1206. X    for (r = 1; r < 7; r++)
  1207. X      for (i = 0; i < 4; i++)
  1208. X        put(run[r],get(deck));
  1209. X    redraw(TRUE);
  1210. X    for (r = 0; r < 7; r++)
  1211. X     {
  1212. X    while (getvalue(peek(run[r])) == 0)
  1213. X     {
  1214. X        s = getsuit(peek(run[r]));
  1215. X        put(ace[s],get(run[r]));
  1216. X        if (run[r][0] == -1)
  1217. X          put(run[r],get(hidden[r]));
  1218. X        redraw(FALSE);
  1219. X     }
  1220. X     }
  1221. X    cnt = cheat = 0;
  1222. X    if (n > 1 && !strcmp(a[1], "auto"))
  1223. X      autopilot();
  1224. X    brkflg = 1;
  1225. X    while (brkflg)
  1226. X     {
  1227. X    cnt++;
  1228. X    do
  1229. X     {
  1230. X        moveto(19, 0);
  1231. X        (void) printf("cmd:%d> ", cnt);
  1232. X        cleol();
  1233. X        (void) fflush(stdout);
  1234. X     } while (!getst(cp = cmd));
  1235. X    while (*cp == ' ' || *cp == '\t')
  1236. X      cp++;
  1237. X    switch (*cp++)
  1238. X     {
  1239. X        case 'a':
  1240. X          autopilot();
  1241. X        break;
  1242. X        case 'm':
  1243. X         {
  1244. X        while (*cp == ' ' || *cp == '\t')
  1245. X          cp++;
  1246. X        if (!(from = *cp++) || from < '1' || from > '7')
  1247. X         {
  1248. X            whoops();
  1249. X            continue;
  1250. X         }
  1251. X        while (*cp == ' ' || *cp == '\t')
  1252. X          cp++;
  1253. X        for (split = 0; isdigit(*cp); split = split * 10 + *cp++ - '0')
  1254. X          ;
  1255. X        if (split < 1 || split > lstlen(run[from - '1']))
  1256. X         {
  1257. X            whoops();
  1258. X            continue;
  1259. X         }
  1260. X        while (*cp == ' ' || *cp == '\t')
  1261. X          cp++;
  1262. X        if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
  1263. X            dest != 'a') || !movecard(from, split, dest, FALSE))
  1264. X         {
  1265. X            whoops();
  1266. X            continue;
  1267. X         }
  1268. X        if (ordered())
  1269. X          finish();
  1270. X         }
  1271. X        break;
  1272. X        case 'h':
  1273. X        case '?':
  1274. X          disphelp();
  1275. X        break;
  1276. X        case 'r':
  1277. X          disprules();
  1278. X        break;
  1279. X        case 'q':
  1280. X          brkflg = 0;
  1281. X        break;
  1282. X        case 'w':
  1283. X         {
  1284. X        while (*cp == ' ' || *cp == '\t')
  1285. X          cp++;
  1286. X        if ((from = *cp - '1') < 0 || from > 6)
  1287. X         {
  1288. X            whoops();
  1289. X            continue;
  1290. X         }
  1291. X        moveto(21, 0);
  1292. X        (void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
  1293. X                                from + '1');
  1294. X        for (i = 0; hidden[from][i] != -1; i++)
  1295. X         {
  1296. X            pcard(hidden[from][i]);
  1297. X            (void) putchar(' ');
  1298. X         }
  1299. X        (void) printf("\nHit return -");
  1300. X        (void) fflush(stdout);
  1301. X        (void) getcx();
  1302. X        moveto(21, 0);
  1303. X        cleol();
  1304. X        (void) putchar('\n');
  1305. X        cleol();
  1306. X        cheat++;
  1307. X         }
  1308. X        break;
  1309. X        case 'p':
  1310. X         {
  1311. X        while (*cp == ' ' || *cp == '\t')
  1312. X          cp++;
  1313. X        if ((from = *cp - '1') < 0 || from > 6)
  1314. X         {
  1315. X            whoops();
  1316. X            continue;
  1317. X         }
  1318. X        while (hidden[from][0] != -1)
  1319. X          put(run[from], get(hidden[from]));
  1320. X        redraw(FALSE);
  1321. X        cheat++;
  1322. X         }
  1323. X        break;
  1324. X        case 's':
  1325. X         {
  1326. X        while (*cp == ' ' || *cp == '\t')
  1327. X          cp++;
  1328. X        if ((from = *cp - '1') < 0 || from > 6)
  1329. X         {
  1330. X            whoops();
  1331. X            continue;
  1332. X         }
  1333. X        shuffle(run[from]);
  1334. X        long_run[from] = -1;
  1335. X        redraw(FALSE);
  1336. X        cheat++;
  1337. X         }
  1338. X        break;
  1339. X        default:
  1340. X          whoops();
  1341. X        break;
  1342. X     }
  1343. X     }
  1344. X    moveto(21, 0);
  1345. X    cleol();
  1346. X    (void) printf("I see you gave up\n");
  1347. X    if (cheat > 0)
  1348. X      (void) printf("    ... even after you cheated %d times!\n", cheat);
  1349. X    else
  1350. X      (void) printf("    ... but at least you didn't cheat...congratulations!\n");
  1351. X    unwind();
  1352. X }
  1353. X
  1354. Xunwind()
  1355. X {
  1356. X    moveto(23, 0);
  1357. X    deinit();
  1358. X    rawmode(FALSE);
  1359. X    exit(0);
  1360. X }
  1361. X
  1362. Xmovecard(from, split, dest, limitmove)
  1363. X {
  1364. X    if (from == dest)
  1365. X      return(FALSE);
  1366. X    return(dest == 'a' ? run2ace(from) : run2run(from, split, dest, limitmove));
  1367. X }
  1368. X
  1369. Xrun2ace(from)
  1370. X {
  1371. X    int fcard, s, ok;
  1372. X
  1373. X    fcard = peek(run[from -= '1']);
  1374. X    if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  1375. X     {
  1376. X    put(ace[s], get(run[from]));
  1377. X    redraw(FALSE);
  1378. X    tidy(from);
  1379. X     }
  1380. X    return(ok);
  1381. X }
  1382. X
  1383. Xrun2run(from, split, dest, limitmove)
  1384. X {
  1385. X    int fcard, dcard, i, ok;
  1386. X
  1387. X    if ((fcard = run[from -= '1'][--split]) == -1)
  1388. X      return(FALSE);
  1389. X    dcard = peek(run[dest -= '1']);
  1390. X    if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
  1391. X                        lstlen(hidden[from]) == 0)
  1392. X      return(FALSE);
  1393. X    if (amode > 0 && limitmove && split && chk2run(fcard, run[from][split - 1]))
  1394. X      return(FALSE);
  1395. X    if (ok = chk2run(fcard, dcard))
  1396. X     {
  1397. X    for (i = split; run[from][i] != -1; i++)
  1398. X      put(run[dest], run[from][i]);
  1399. X    run[from][split] = -1;
  1400. X    redraw(FALSE);
  1401. X    tidy(from);
  1402. X     }
  1403. X    return(ok);
  1404. X }
  1405. X
  1406. Xtidy(from)
  1407. X {
  1408. X    int s;
  1409. X
  1410. X    while (getvalue(peek(run[from])) == 0)
  1411. X     {
  1412. X    s = getsuit(peek(run[from]));
  1413. X    put(ace[s],get(run[from]));
  1414. X    redraw(FALSE);
  1415. X     }
  1416. X    if (lstlen(hidden[from]) != 0 && lstlen(run[from]) == 0)
  1417. X     {
  1418. X    while (getvalue(peek(hidden[from])) == 0)
  1419. X     {
  1420. X        s = getsuit(peek(hidden[from]));
  1421. X        put(ace[s],get(hidden[from]));
  1422. X        redraw(FALSE);
  1423. X     }
  1424. X    put(run[from],get(hidden[from]));
  1425. X    redraw(FALSE);
  1426. X     }
  1427. X }
  1428. X
  1429. Xchk2run(fcard,dcard)
  1430. X {
  1431. X    if (dcard == -1 && getvalue(fcard) == 12)
  1432. X      return(TRUE);
  1433. X    return(getvalue(dcard) - 1 == getvalue(fcard) &&
  1434. X                getcolour(dcard) != getcolour(fcard));
  1435. X }
  1436. X
  1437. Xordered()
  1438. X {
  1439. X    int i, j;
  1440. X
  1441. X    for (i = 0; i < 7; i++)
  1442. X      if (hidden[i][0] != -1)
  1443. X    return(FALSE);
  1444. X      else if (run[i][0] != -1)
  1445. X    for (j = 1; run[i][j] != -1; j++)
  1446. X      if (getvalue(run[i][j]) != getvalue(run[i][j - 1]) - 1 ||
  1447. X            getcolour(run[i][j]) == getcolour(run[i][j - 1]))
  1448. X        return(FALSE);
  1449. X    return(TRUE);
  1450. X }
  1451. X
  1452. Xcardsleft()
  1453. X {
  1454. X    int i;
  1455. X    for (i = 0; i < 7; i++)
  1456. X      if (run[i][0] != -1)
  1457. X    return(TRUE);
  1458. X    return(FALSE);
  1459. X }
  1460. X
  1461. Xfinish()
  1462. X {
  1463. X    int i;
  1464. X
  1465. X    moveto(21, 0);
  1466. X    (void) printf("\007I'll finish for you now\007");
  1467. X    (void) fflush(stdout);
  1468. X    do
  1469. X      for (i = 0; i < 7; i++)
  1470. X    while (movecard(i + '1', 0, 'a', FALSE))
  1471. X      ;
  1472. X     while (cardsleft());
  1473. X    moveto(21, 40);
  1474. X    cleol();
  1475. X    (void) printf("\007You WIN\007\n");
  1476. X    if (cheat > 0)
  1477. X      (void) printf("    ... but you cheated %d times!", cheat);
  1478. X    else
  1479. X      (void) printf("    ... and without cheating ... congratulations!");
  1480. X    unwind();
  1481. X }
  1482. X
  1483. Xautopilot()
  1484. X {
  1485. X    int i, j, k, l;
  1486. X
  1487. X    moveto(21, 0);
  1488. X    (void) printf("Going into automatic mode...");
  1489. X    (void) fflush(stdout);
  1490. X    amode = TRUE;
  1491. X    do
  1492. X     {
  1493. X    l = 0;
  1494. X    for (i = 0; i < 7; i++)
  1495. X      for (j = 0; j < 7; j++)
  1496. X        for (k = 0; k < lstlen(run[i]); k++)
  1497. X          l = movecard(i + '1', k, j + '1', TRUE) || l;
  1498. X    for (i = 0; i < 7; i++)
  1499. X      l = movecard(i + '1', 0, 'a', FALSE) || l;
  1500. X     } while (l);
  1501. X    moveto(21, 28);
  1502. X    if (!cardsleft())
  1503. X     {
  1504. X    (void) printf("\007YEA...\007");
  1505. X    (void) fflush(stdout);
  1506. X    for (i = 0; i < 7; i++)
  1507. X      if (movecard(i + '1', 0, 'a', FALSE))
  1508. X    moveto(21, 34);
  1509. X    (void) printf("I won!!!!!");
  1510. X     }
  1511. X    else
  1512. X      (void) printf("I couldn't win this time");
  1513. X    unwind();
  1514. X }
  1515. X
  1516. Xredraw(display)
  1517. X {
  1518. X    int i, j;
  1519. X
  1520. X    if (display)
  1521. X     {
  1522. X    clear();
  1523. X    for (i = 0; i < 7; i++)
  1524. X     {
  1525. X        long_run[i] = long_hide[i] = base_run[i] = -1;
  1526. X        moveto(i + i + 2, 1);
  1527. X        (void) putchar(i + '1');
  1528. X     }
  1529. X    moveto(0, 6);
  1530. X    for (i = 1; i < 21; i++)
  1531. X      (void) printf("%3d", i);
  1532. X    for (i = 0; i < 4; i++)
  1533. X      long_ace[i] = -1;
  1534. X    moveto(17, 1);
  1535. X    (void) printf("ACES:");
  1536. X     }
  1537. X    for (i = 0; i < 7; i++)
  1538. X     {
  1539. X    if (long_hide[i] != lstlen(hidden[i]))
  1540. X     {
  1541. X        moveto(i + i + 2, 4);
  1542. X        (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
  1543. X        long_hide[i] = lstlen(hidden[i]);
  1544. X     }
  1545. X     }
  1546. X    for (i = 0; i < 4; i++)
  1547. X     {
  1548. X    if (long_ace[i] != lstlen(ace[i]))
  1549. X     {
  1550. X        moveto(17, 8 + i * 5);
  1551. X        if (ace[i][0] != -1)
  1552. X          pcard(peek(ace[i]));
  1553. X        else
  1554. X          (void) printf("--");
  1555. X        long_ace[i] = lstlen(ace[i]);
  1556. X     }
  1557. X     }
  1558. X    for (i = 0; i < 7; i++)
  1559. X     {
  1560. X    if (long_run[i] != lstlen(run[i]) ||
  1561. X                (long_run[i] == 1 && base_run[i] != run[i][0]))
  1562. X     {
  1563. X        moveto(i + i +  2, 7);
  1564. X        for (j = 0; run[i][j] != -1; j++)
  1565. X         {
  1566. X        if (run[i][j] == -1)
  1567. X          (void) printf("  ");
  1568. X        else
  1569. X          pcard(run[i][j]);
  1570. X        (void) putchar(' ');
  1571. X         }
  1572. X        while (j++ < long_run[i])
  1573. X          (void) printf("   ");
  1574. X        long_run[i] = lstlen(run[i]);
  1575. X        base_run[i] = run[i][0];
  1576. X     }
  1577. X     }
  1578. X    (void) fflush(stdout);
  1579. X    (void) sleep(1);
  1580. X }
  1581. X
  1582. Xpcard(card)
  1583. X {
  1584. X    int i;
  1585. X
  1586. X    if ((i = getcolour(card)) != 0)
  1587. X      standout();
  1588. X    (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
  1589. X    if (i)
  1590. X      standend();
  1591. X }
  1592. X
  1593. Xgetvalue(card)
  1594. X {
  1595. X    return(card % 13);
  1596. X }
  1597. X
  1598. Xgetsuit(card)
  1599. X {
  1600. X    return(card / 13);
  1601. X }
  1602. X
  1603. Xgetcolour(card)
  1604. X {
  1605. X    return(card / 26);
  1606. X }
  1607. X
  1608. Xwhoops()
  1609. X {
  1610. X    moveto(19, 0);
  1611. X    (void) printf("\007Invalid Command: '%s'\007", cmd);
  1612. X    (void) fflush(stdout);
  1613. X    (void) sleep(4);
  1614. X }
  1615. X
  1616. Xdisphelp()
  1617. X {
  1618. X    clear();
  1619. X    (void) printf("\
  1620. XCommands: m [1-7] [pos] [1-7a] : move cards or runs\n\
  1621. X          a                    : turn on the auto pilot\n\
  1622. X          s [1-7]              : shuffle the cards in a run (cheat!)\n\
  1623. X          p [1-7]              : put a hidden pile onto the run (cheat!)\n\
  1624. X          w [1-7]              : print the cards in a hidden pile (cheat!)\n\
  1625. X          h or ?               : print this command summary\n\
  1626. X          r                    : print the rules of the game\n\
  1627. X          q                    : quit\n\n");
  1628. X    (void) printf("\
  1629. XMoving:   There are three parameters in the m command: the first is the\n\
  1630. X          run to be moved from, the second is the card number to split\n\
  1631. X          the run at (check numbers along the top), and the third is\n\
  1632. X      the destination run (or 'a' if an ace pile). Since only one card\n\
  1633. X      can be moved to an ace at a time, the pos paramter is ignored\n\
  1634. X      in this case. To give a couple of examples 'm 6 1 4 would move\n\
  1635. X      all cards from run 6 to run 4, and m 3 5 7 would split run 3\n\
  1636. X      before the fifth card (leaving 4) and move the rest to run 7.\n\n\
  1637. XCheating: Commands that allow cheating are available but they will count\n\
  1638. X          against you in your next life!\n\n\nHit Return -");
  1639. X    (void) fflush(stdout);
  1640. X    (void) getcx();
  1641. X    redraw(TRUE);
  1642. X }
  1643. X
  1644. Xdisprules()
  1645. X {
  1646. X    clear();
  1647. X    (void) printf("\
  1648. XObject:   The object of this game is to get all of the cards in each suit\n\
  1649. X          in order on the proper ace pile.\n\n\
  1650. XRules:    Cards are played on the ace piles in ascending order: A,2,...,K.\n\
  1651. X          All aces are automatically placed in the correct aces pile as\n\
  1652. X          they're uncovered in runs or from a pile of hidden cards. Once a\n\
  1653. X          card is placed in an ace pile it can't be removed.\n\n");
  1654. X    (void) printf("\
  1655. X          When moving runs, they can be split anywhere, but the top card\n\
  1656. X      in the run moved must be placed on a card one higher (i.e. 5 on\n\
  1657. X      a 6) and always on a card of the opposite color.\n\n");
  1658. X    (void) printf("\
  1659. X          Whenever a whole run is moved, the top hidden card is turned\n\
  1660. X          over, thus becoming the beginning of a new run.  If there are no\n\
  1661. X          hidden cards left, a space is created which can only be filled by\n\
  1662. X          a king.\n\n\nHit Return -");
  1663. X    (void) fflush(stdout);
  1664. X    (void) getcx();
  1665. X    redraw(TRUE);
  1666. X }
  1667. X
  1668. Xgetst(getbuf)
  1669. Xchar *getbuf;
  1670. X {
  1671. X    int ch;
  1672. X    int nc;
  1673. X
  1674. X    *(resgb = getbuf) = nc = 0;
  1675. X    for (;;)
  1676. X     {
  1677. X    if ((((ch = getcx()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
  1678. X     {
  1679. X        *getbuf++ = ch;
  1680. X        *getbuf = 0;
  1681. X        nc++;
  1682. X        (void) putchar(ch);
  1683. X        (void) fflush(stdout);
  1684. X     }
  1685. X    else if (ch == '\b')
  1686. X     {
  1687. X        if (nc--)
  1688. X         {
  1689. X            *--getbuf = 0;
  1690. X        (void) printf("\b \b");
  1691. X        (void) fflush(stdout);
  1692. X         }
  1693. X        else
  1694. X          return(FALSE);
  1695. X     }
  1696. X    else if (ch == ('r' & 0x1f))
  1697. X      redraw(TRUE);
  1698. X    else if (ch == '\n')
  1699. X      return(TRUE);
  1700. X     }
  1701. X }
  1702. X
  1703. Xshuffle(cards)
  1704. Xint *cards;
  1705. X {
  1706. X    int i, j, k, t;
  1707. X
  1708. X    for (i = 0; cards[i] != -1; i++)
  1709. X      ;
  1710. X    if (i)
  1711. X     {
  1712. X    for (j = 0; j < i; j++)
  1713. X     {
  1714. X        do
  1715. X          k = rnd(i);
  1716. X         while (k == j);
  1717. X        t = cards[j];
  1718. X        cards[j] = cards[k];
  1719. X        cards[k] = t;
  1720. X     }
  1721. X     }
  1722. X }
  1723. X
  1724. Xrnd(n)
  1725. X {
  1726. X    return(((rand() >> 12 | rand() >> 24) & (unsigned) ~0 >> 1) % n);
  1727. X }
  1728. X
  1729. Xlstlen(list)
  1730. Xint *list;
  1731. X {
  1732. X    int i;
  1733. X
  1734. X    for (i = 0; list[i] != -1; i++)
  1735. X      ;
  1736. X    return(i);
  1737. X }
  1738. X
  1739. X#ifdef SIGTSTP
  1740. X
  1741. Xrestart()
  1742. X {
  1743. X    setsig(TRUE);
  1744. X    rawmode(TRUE);
  1745. X    redraw(TRUE);
  1746. X    moveto(19, 0);
  1747. X    (void) printf("cmd:%d> ", cnt);
  1748. X    cleol();
  1749. X    (void) printf("%s", resgb);
  1750. X    (void) fflush(stdout);
  1751. X }
  1752. X
  1753. X#endif SIGTSTP
  1754. X
  1755. Xsetsig(on)
  1756. X {
  1757. X    (void) signal(SIGINT, on ? SIG_IGN : SIG_DFL);
  1758. X    (void) signal(SIGQUIT, on ? SIG_IGN : SIG_DFL);
  1759. X    (void) signal(SIGTERM, on ? SIG_IGN : SIG_DFL);
  1760. X#ifdef SIGTSTP
  1761. X    (void) signal(SIGTSTP, on ? SIG_IGN : SIG_DFL);
  1762. X    (void) signal(SIGCONT, on ? restart : SIG_DFL);
  1763. X#endif
  1764. X }
  1765. X
  1766. Xstop()
  1767. X {
  1768. X    setsig(FALSE);
  1769. X    rawmode(FALSE);
  1770. X#ifdef SIGTSTP
  1771. X    (void) signal(SIGCONT, restart);
  1772. X    kill(getpid(), SIGTSTP);
  1773. X#else
  1774. X    (void) system("eval exec ${SHELL-/bin/sh}");
  1775. X#endif SIGTSTP
  1776. X }
  1777. X
  1778. Xgetcx()
  1779. X {
  1780. X    char ch;
  1781. X
  1782. X#ifdef SIGTSTP
  1783. X    (void) signal(SIGTSTP, stop);
  1784. X#else
  1785. X    for (;;) {
  1786. X#endif SIGTSTP
  1787. X    (void) read(0, &ch, 1);
  1788. X#ifdef SIGTSTP
  1789. X    (void) signal(SIGTSTP, SIG_IGN);
  1790. X#else
  1791. X        if (ch != '\032')
  1792. X            break;
  1793. X        stop();
  1794. X    }
  1795. X#endif SIGTSTP
  1796. X    return(ch);
  1797. X }
  1798. X
  1799. Xrawmode(on)
  1800. X {
  1801. X    struct sgttyb s;
  1802. X    static struct sgttyb saveterm;
  1803. X    static int saved = FALSE;
  1804. X
  1805. X    if (on)
  1806. X     {
  1807. X#ifdef TCGETA
  1808. X         (void) ioctl(0, TCGETA, &s);
  1809. X#else
  1810. X    (void) ioctl(0, TIOCGETP, &s);
  1811. X#endif TCGETA
  1812. X    if (saved == FALSE)
  1813. X     {
  1814. X        saveterm = s;
  1815. X        saved = TRUE;
  1816. X     }
  1817. X#ifdef TCGETA
  1818. X#ifndef TERMINFO
  1819. X         ospeed = s.c_cflag & CBAUD;
  1820. X#endif  TERMINFO
  1821. X         s.c_lflag &= ~(ECHO|ICANON);
  1822. X         s.c_oflag &= ~TAB3;
  1823. X         s.c_cc[VMIN] = 1;
  1824. X         s.c_cc[VTIME] = 1;
  1825. X#else
  1826. X    ospeed = s.sg_ospeed;
  1827. X    s.sg_flags |= CBREAK;
  1828. X    s.sg_flags &= ~(ECHO|XTABS);
  1829. X#endif TCGETA
  1830. X     }
  1831. X    else
  1832. X      s = saveterm;
  1833. X#ifdef TCGETA
  1834. X    (void) ioctl(0, TCSETAW, &s);
  1835. X#else
  1836. X    (void) ioctl(0, TIOCSETN, &s);
  1837. X#endif
  1838. X }
  1839. X
  1840. Xgetterm()
  1841. X {
  1842. X    char termbuf[1024];
  1843. X    char *sp;
  1844. X    static char sbuf[150];
  1845. X    char *tgetstr();
  1846. X
  1847. X    tgetent(termbuf, getenv("TERM"));
  1848. X    sp = sbuf;
  1849. X
  1850. X    PC = *(tgetstr("pc", &sp));
  1851. X    *UP = *(tgetstr("pc", &sp));
  1852. X    UP[1] = 0;
  1853. X    if (!tgetflag("bs"))
  1854. X        *BC = *(sc_bs = tgetstr("bc", &sp));
  1855. X    else {
  1856. X        *BC = '\b';
  1857. X        sc_bs = BC;
  1858. X    }
  1859. X    BC[1] = 0;
  1860. X    sc_init = tgetstr("ti", &sp);
  1861. X    sc_deinit = tgetstr("te", &sp);
  1862. X    sc_cleol = tgetstr("ce", &sp);
  1863. X    sc_clear = tgetstr("cl", &sp);
  1864. X    sc_move = tgetstr("cm", &sp);
  1865. X    sc_s_in = tgetstr("so", &sp);
  1866. X    sc_s_out = tgetstr("se", &sp);
  1867. X }
  1868. X
  1869. Xxputc(c)
  1870. Xregister c;
  1871. X {
  1872. X    (void) putchar(c);
  1873. X }
  1874. X
  1875. Xinit()
  1876. X {
  1877. X    tputs(sc_init, 24, xputc);
  1878. X }
  1879. X
  1880. Xdeinit()
  1881. X {
  1882. X    tputs(sc_deinit, 24, xputc);
  1883. X }
  1884. X
  1885. Xclear()
  1886. X {
  1887. X    tputs(sc_clear, 24, xputc);
  1888. X }
  1889. X
  1890. Xcleol()
  1891. X {
  1892. X    tputs(sc_cleol, 1, xputc);
  1893. X }
  1894. X
  1895. Xstandout()
  1896. X {
  1897. X    tputs(sc_s_in, 1, xputc);
  1898. X }
  1899. X
  1900. Xstandend()
  1901. X {
  1902. X    tputs(sc_s_out, 1, xputc);
  1903. X }
  1904. X
  1905. Xmoveto(y, x)
  1906. X {
  1907. X    char *tgoto();
  1908. X
  1909. X    tputs(tgoto(sc_move, x, y), 1, xputc);
  1910. X }
  1911. X
  1912. Xput(dest, item)
  1913. Xint *dest;
  1914. X {
  1915. X    if (item == -1)
  1916. X      return;
  1917. X    while (*dest != -1)
  1918. X      dest++;
  1919. X    *dest++ = item;
  1920. X    *dest = -1;
  1921. X }
  1922. X
  1923. Xget(source)
  1924. Xint *source;
  1925. X {
  1926. X    int i;
  1927. X
  1928. X    for (i = 0; *source != -1; i++, source++)
  1929. X      ;
  1930. X    if (i)
  1931. X     {
  1932. X    i = *--source;
  1933. X    *source = -1;
  1934. X    return(i);
  1935. X     }
  1936. X    return(-1);
  1937. X }
  1938. X
  1939. Xpeek(source)
  1940. Xint *source;
  1941. X {
  1942. X    int i;
  1943. X
  1944. X    for (i = 0; source[i] != -1; i++)
  1945. X      ;
  1946. X    return(i ? source[i - 1] : -1);
  1947. X }
  1948. END_OF_solx.c
  1949. if test 16202 -ne `wc -c <solx.c`; then
  1950.     echo shar: \"solx.c\" unpacked with wrong size!
  1951. fi
  1952. # end of overwriting check
  1953. fi
  1954. echo shar: End of shell archive.
  1955. exit 0
  1956.  
  1957.  
  1958.