home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume2 / sol2 < prev    next >
Internet Message Format  |  1987-08-05  |  44KB

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