home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / Games / UnixGames / accordian / Source / accrdn.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-01-28  |  26.3 KB  |  1,240 lines

  1. #! /bin/sh
  2. # This is a shell archive.  Remove anything before this line, then unpack
  3. # it by saving it into a file and typing "sh file".  To overwrite existing
  4. # files, type "sh file -c".  You can also feed this as standard input via
  5. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  6. # will see the following message at the end:
  7. #        "End of archive 1 (of 1)."
  8. # Contents:  README MANIFEST accordian.c accordian.man cards.c cards.h
  9. #   help.c makefile
  10. # Wrapped by billr@saab on Sun Nov 29 18:05:07 1992
  11. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  12. if test -f 'README' -a "${1}" != "-c" ; then 
  13.   echo shar: Will not clobber existing file \"'README'\"
  14. else
  15. echo shar: Extracting \"'README'\" \(1686 characters\)
  16. sed "s/^X//" >'README' <<'END_OF_FILE'
  17. X        --------- ACCORDIAN SOLITAIRE ---------
  18. X
  19. XThis is the card game of Accordian Solitaire.  A deck of cards is
  20. Xdealt to the playing table (either a card at a time, or the whole
  21. Xdeck at once), and the goal is to move stacks of cards around
  22. Xuntil a single stack of cards is left on the table.
  23. X
  24. XStacks of cards can only move 1 or 3 spaces up the line of cards,
  25. Xonto other stacks whose top card is of the same suit or rank as
  26. Xthe current stack's top card.
  27. X
  28. XIf you end up with a single stack, you win the game!
  29. X
  30. XThe book of card games I got this out of (but have since lost) said
  31. Xof this game something like the following:
  32. X
  33. X    The response to this game after we published that it was basically
  34. X    impossible to win was about half a dozen letters, typically saying
  35. X    the following: `I have play Accordian every night for the last
  36. X    25 years, and have won no fewer than 3 times.'
  37. X
  38. XGiven the chance of winning the game, I felt it wise to write the program
  39. Xso I wouldn't tire out my hands reshuffling the deck after each defeat.
  40. X
  41. X
  42. XTo compile and run, edit "Makefile", and change file path, and compiler
  43. Xdefinitions to suit your machine.  I have included the compiler setups
  44. Xfor BSD-ish and SysV-ish machines.  I presume that it will compile under
  45. Xany other system that has an implementation of the "curses" package.
  46. X
  47. XI have successfully compiled and run the program under SunOS 4.1.1 (BSD-ish)
  48. Xon a Sun Sparc 1+, and under IRIX 4.0.5 (SysV-ish) on an SGI Crimson.
  49. X
  50. X
  51. XPlease send me any enhancements or modifications done to the program,
  52. Xso I can keep my copy up-to-date with any updated versions out there.
  53. X
  54. X
  55. XThis program is public domain.
  56. X
  57. X-Eric Lechner (ericl@xilinx.com)  19 November 1992
  58. END_OF_FILE
  59. if test 1686 -ne `wc -c <'README'`; then
  60.     echo shar: \"'README'\" unpacked with wrong size!
  61. fi
  62. # end of 'README'
  63. fi
  64. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  65.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  66. else
  67. echo shar: Extracting \"'MANIFEST'\" \(362 characters\)
  68. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  69. X   File Name        Archive #    Description
  70. X-----------------------------------------------------------
  71. X MANIFEST                   1    This shipping list
  72. X README                     1    
  73. X accordian.c                1    
  74. X accordian.man              1    
  75. X cards.c                    1    
  76. X cards.h                    1    
  77. X help.c                     1    
  78. X makefile                   1    
  79. END_OF_FILE
  80. if test 362 -ne `wc -c <'MANIFEST'`; then
  81.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  82. fi
  83. # end of 'MANIFEST'
  84. fi
  85. if test -f 'accordian.c' -a "${1}" != "-c" ; then 
  86.   echo shar: Will not clobber existing file \"'accordian.c'\"
  87. else
  88. echo shar: Extracting \"'accordian.c'\" \(13179 characters\)
  89. sed "s/^X//" >'accordian.c' <<'END_OF_FILE'
  90. X/*
  91. X * accordian - the solitaire card game
  92. X *
  93. X * Author: Eric Lechner (ericl@xilinx.com)
  94. X * Originally written: Summer 1990
  95. X * Minor enhancements: March 1991 and November 1992
  96. X */
  97. X
  98. X#include <stdio.h>
  99. X#include <stdlib.h>
  100. X#include <pwd.h>
  101. X#include <time.h>
  102. X#include <curses.h>
  103. X#include <signal.h>
  104. X#include "cards.h"
  105. X
  106. X#define BADCARD        -1
  107. X#define NOTINDECK    -2
  108. X#define STUCK        -3
  109. X
  110. X#define MOVE1    1
  111. X#define MOVE3    2
  112. X
  113. X#define WIN        1
  114. X#define MOREMOVES    2
  115. X#define LOSE        3
  116. X
  117. X#define BUFFERLENGTH    256
  118. X
  119. Xint quit();
  120. X
  121. Xstruct save {
  122. X    int position;
  123. X    int num_spaces;
  124. X};
  125. X
  126. Xint save_nextcard, save_lastpile;
  127. Xint _face = 0, _suit = 0;
  128. Xint _msg[5];
  129. Xstruct card deck[52];
  130. Xstruct card save_deck[52];
  131. Xchar buffer[256];
  132. Xstruct save undo[52], save[52];
  133. Xint nummoves, save_moves;
  134. X
  135. X/*
  136. X * main -- the main program loop
  137. X */
  138. Xmain(argc,argv)
  139. Xint argc;
  140. Xchar *argv[];
  141. X{
  142. X    int lastpile;    /* last exposed "pile" position in the deck */
  143. X    int nextcard;    /* next "free" card in the deck */
  144. X    int place;    /* place of card to move in the deck*/
  145. X    int playing;
  146. X    int lastlast, thislast;    /* last displayed card */
  147. X    int i, ch, tmp, num;
  148. X    int title;
  149. X    FILE *fp, *pfp;
  150. X    char *pager;
  151. X
  152. X    if (argc > 1) {
  153. X    pager = getenv("PAGER");
  154. X    if (pager == NULL || *pager == '\0') pager = DEFAULT_PAGER;
  155. X
  156. X    pfp = popen(pager, "w");
  157. X    if (pfp == NULL) pfp = stdout;
  158. X
  159. X    i = 0;
  160. X    while (helplist[i] != 0)
  161. X        fprintf(pfp, "%s\n",helplist[i++]);
  162. X
  163. X    fp = fopen(ACCORDIAN_WINFILE, "r");
  164. X    if (fp != NULL) {
  165. X        fprintf(pfp, "\nAccordian winners:\n");
  166. X        while ((ch = fgetc(fp)) != EOF) fputc(ch, pfp);
  167. X        fclose(fp);
  168. X    }
  169. X    if (pfp != stdout) pclose(pfp);
  170. X    exit(-1);
  171. X    }
  172. X
  173. X    SRANDOM(getpid());
  174. X
  175. X    signal(SIGINT,quit);
  176. X
  177. X    /* yap, if curses window couldn't be formed */
  178. X    /* note: most curses implementations quit for you here */
  179. X    if (initscr() == NULL) {
  180. X    fprintf(stderr,"Couldn't initialize the screen.\n");
  181. X    exit(-1);
  182. X    }
  183. X
  184. X    savetty();
  185. X
  186. XStartOfGame:
  187. X    title = FALSE;
  188. X
  189. X    for (i=0; i<5; i++) _msg[i] = 0;
  190. X
  191. X    for (i=0; i<52; i++) {
  192. X    undo[i].position = 0;
  193. X    undo[i].num_spaces = 0;
  194. X    }
  195. X    nummoves = 0;
  196. X
  197. X    newdeck();
  198. X    shuffle();
  199. X
  200. X    lastpile = 0;
  201. X    nextcard = 1;
  202. X
  203. X    savedeck(lastpile,nextcard);
  204. X
  205. X    clear();
  206. X    cbreak();
  207. X    noecho();
  208. X
  209. X    playing = TRUE;
  210. X
  211. X    lastlast = -1;
  212. X    while (playing) {
  213. X    thislast = lastpile;
  214. X    if (lastlast != thislast) display(lastlast+1,lastpile);
  215. X    if (!title) {
  216. X        move(2,23);
  217. X        printw("Accordian Solitaire - by Eric Lechner");
  218. X        title = TRUE;
  219. X    }
  220. X    lastlast = thislast;
  221. X    move(8,50);
  222. X    if (lastpile == 51 || nextcard == 52)
  223. X        printw("All cards have been dealt.");
  224. X    else
  225. X        printw("Cards left : %d",52 - nextcard);
  226. X    clrtoeol();
  227. X    move(11,50);
  228. X    printw("Your move : ");
  229. X    move(11,62);
  230. X    clrtoeol();
  231. X    refresh();
  232. X    ch = getch();
  233. X    printch(ch);
  234. X    switch (ch) {
  235. X        case 'D' :        /* deal the whole deck */
  236. X        if (nextcard < 52) {
  237. X            lastpile += 52 - nextcard;
  238. X            nextcard = 52;
  239. X            clearmsg();
  240. X        } else {
  241. X            putmsg("Out of cards.");
  242. X        }
  243. X        break;
  244. X        case 'd' :        /* deal another card */
  245. X        if (nextcard < 52) {
  246. X            nextcard++;
  247. X            lastpile++;
  248. X            clearmsg();
  249. X        } else {
  250. X            putmsg("Out of cards.");
  251. X        }
  252. X        break;
  253. X        case 0x12 :        /* redraw screen if a ^R or ^L */
  254. X        case 0x1c:
  255. X        clear();
  256. X        display(0,lastpile);
  257. X        title = FALSE;
  258. X        for (i=0; i<5; i++) _msg[i] = 0;
  259. X        break;
  260. X        case 'x' :
  261. X        case 'X' :
  262. X        playing = FALSE;
  263. X        break;
  264. X#ifdef DEBUG
  265. X        case 'l' :    /* kluge to test save_win() routine */
  266. X        save_win();
  267. X        break;
  268. X#endif
  269. X        case ' ' :
  270. X        clearmsg();
  271. X        break;
  272. X        case '?' :
  273. X        help();
  274. X        clear();
  275. X        display(0,lastpile);
  276. X        title = FALSE;
  277. X        for (i=0; i<5; i++) _msg[i] = 0;
  278. X        break;
  279. X        case 'r' :
  280. X        case 'R' :
  281. X        restoredeck(&lastpile,&nextcard);
  282. X        display(1,lastpile);
  283. X        if (lastpile < 51) undisplay(lastpile+1,51);
  284. X        putmsg("Deck restored.");
  285. X        break;
  286. X        case 's' :
  287. X        case 'S' :
  288. X        savedeck(lastpile,nextcard);
  289. X        putmsg("Deck saved.");
  290. X        break;
  291. X        case 'f' :
  292. X        case 'F' :
  293. X        find_move(lastpile);
  294. X        break;
  295. X        case 'u' :
  296. X        case 'U' : /* undo a move here */
  297. X        clearmsg();
  298. X        if (--nummoves < 0) {
  299. X            nummoves = 0;
  300. X            putmsg("No moves to undo!");
  301. X        } else {
  302. X            for (i=51; i>undo[nummoves].position; i--) {
  303. X                swap(i,i-1);
  304. X            }
  305. X            swap(i,i - undo[nummoves].num_spaces);
  306. X            lastpile++;
  307. X            display( undo[nummoves].position - undo[nummoves].num_spaces, lastpile);
  308. X        }
  309. X        break;
  310. X        case 'a' :
  311. X        case 'A' :
  312. X        case '1' :
  313. X        case '2' :
  314. X        case '3' :
  315. X        case '4' :
  316. X        case '5' :
  317. X        case '6' :
  318. X        case '7' :
  319. X        case '8' :
  320. X        case '9' :
  321. X        case 'j' :
  322. X        case 'J' :
  323. X        case 'q' :
  324. X        case 'Q' :
  325. X        case 'k' :
  326. X        case 'K' :
  327. X        place = get_card(ch,lastpile);
  328. X        switch (place) {
  329. X            case BADCARD :
  330. X            /* print "bad key" error message */
  331. X            putmsg("Hit '?' for help.");
  332. X            break;
  333. X            case NOTINDECK :
  334. X            /* print "not in deck" error message */
  335. X            sprintf(buffer,"Couldn't find the %s of %s.",
  336. X                cardnames[_face], suitnames[_suit]);
  337. X            putmsg(buffer);
  338. X            break;
  339. X            default:
  340. X            /* choose move for card, if any */
  341. X            switch (check(place)) {
  342. X                case MOVE1 :
  343. X                tmp = '1';
  344. X                break;
  345. X                case MOVE3 :
  346. X                tmp = '3';
  347. X                break;
  348. X                case (MOVE3 | MOVE1) :
  349. X                putmsg("Move 1 or 3 spaces");
  350. X                move(11,62);
  351. X                clrtoeol();
  352. X                refresh();
  353. X                tmp = getch();
  354. X                break;
  355. X                default :
  356. X                tmp = STUCK;
  357. X                break;
  358. X            }
  359. X            switch (tmp) {
  360. X                case '0' :
  361. X                clearmsg();
  362. X                break;
  363. X                case '1' :
  364. X                case '3' :
  365. X                num = tmp - '0';
  366. X                if (place < num) {
  367. X                    sprintf(buffer,"Can't swap up %d.",num);
  368. X                    putmsg(buffer);
  369. X                    break;
  370. X                } else clearmsg();
  371. X                undo[nummoves].num_spaces = num;
  372. X                undo[nummoves].position = place;
  373. X                nummoves++;
  374. X                swap(place,place-num);
  375. X                for(i=place; i<51; i++)
  376. X                    swap(i,i+1);
  377. X                lastpile--;
  378. X                display(place - num,lastpile);
  379. X                undisplay(lastpile + 1,lastpile + 1);
  380. X                switch(checkwin(lastpile,nextcard)) {
  381. X                    case WIN :
  382. X                    putmsg("You win! Congratulations!");
  383. X                    playing = FALSE;
  384. X                    save_win();
  385. X                    break;
  386. X                    case LOSE :
  387. X                        putmsg("No more moves. You lose!");
  388. X                        playing = FALSE;
  389. X                        break;
  390. X                    default :
  391. X                    break;
  392. X                }
  393. X                break;
  394. X                case STUCK :
  395. X                sprintf(buffer,"The %s of %s cannot move!",
  396. X                    cardnames[_face], suitnames[_suit]);
  397. X                putmsg(buffer);
  398. X                break;
  399. X                default :
  400. X                putmsg("Hit '?' for help.");
  401. X                break;
  402. X            }
  403. X        }
  404. X        break;
  405. X        default :
  406. X        putmsg("Hit '?' for help.");
  407. X        break;
  408. X    }
  409. X    }
  410. X    move(20,50);
  411. X    printw("Play again? [y/n] ");
  412. XGetAnotherCh:
  413. X    move(20,68);
  414. X    refresh();
  415. X    ch = getch();
  416. X    switch (ch) {
  417. X    case 'y' :
  418. X    case 'Y' :
  419. X        goto StartOfGame;
  420. X    case 'n' :
  421. X    case 'N' :
  422. X    case 'x' :
  423. X    case 'X' :
  424. X    case 'q' :
  425. X    case 'Q' :
  426. X        break;
  427. X    default:
  428. X        goto GetAnotherCh;
  429. X    }
  430. X    move(20,0);
  431. X    refresh();
  432. X    resetty();
  433. X    endwin();
  434. X}
  435. X
  436. X/*
  437. X * display -- print the deck onto the screen from position "start" to "end"
  438. X */
  439. Xdisplay(start,end)
  440. Xint start, end;
  441. X{
  442. X    int i, hilite = NORMAL;
  443. X
  444. X    for (i=start; i<=end; i++) {
  445. X    move((i%13) + 5, (int) (i/13) * 10 + 10);
  446. X    if (deck[i].face != 9) {
  447. X        printw(" ");
  448. X    }
  449. X    switch (deck[i].suit) {
  450. X        case CLUB :
  451. X        case SPADE :
  452. X        hilite = NORMAL;
  453. X        break;
  454. X        case HEART :
  455. X        case DIAMOND :
  456. X        standout();
  457. X        hilite = REVERSE;
  458. X        break;
  459. X    }
  460. X    printw("%s%s",cards[deck[i].face],suits[deck[i].suit]);
  461. X    if (hilite == REVERSE) {
  462. X        standend();
  463. X        hilite = NORMAL;
  464. X    }
  465. X    if (!(i % 13) && i > 0) {
  466. X        arrow(1,(int) i / 13);
  467. X    }
  468. X    }
  469. X}
  470. X
  471. X/*
  472. X * undisplay -- clear display from "place1" to "place2"
  473. X *              (useful for clearing off the end card)
  474. X */
  475. Xundisplay(place1,place2)
  476. Xint place1, place2;
  477. X{
  478. X    int i;
  479. X
  480. X    for (i = place1; i <= place2; i++) {
  481. X    move((i%13) + 5, (int) (i/13) * 10 + 10);
  482. X    standend();
  483. X    printw("   ");
  484. X    standend();
  485. X    if (!(i%13) && i > 0)
  486. X        arrow(0,(int) i/13);
  487. X    }
  488. X}
  489. X
  490. X/*
  491. X * arrow -- draw an arrow from one column to the preceding one
  492. X */
  493. Xarrow(on,row)
  494. Xint on,row;
  495. X{
  496. X    int i;
  497. X    move(5, row * 10 + 6);
  498. X    printw("%s",on ? "---" : "   ");
  499. X    for(i=1;i<12;i++) {
  500. X    move(5 + i, row * 10 + 6);
  501. X    printw("%s",on ? "|" : " ");
  502. X    }
  503. X    move(17,row * 10 + 4);
  504. X    printw("%s",on ? "<--" : "   ");
  505. X}
  506. X
  507. X/*
  508. X * get_card -- get a card as input from the user, face value, and suit.
  509. X */
  510. Xget_card(ch,lastpile)
  511. Xint ch, lastpile;
  512. X{
  513. X    int card, suit, i;
  514. X
  515. X    /* get the card */
  516. X    switch (ch) {
  517. X    case 'a' :
  518. X    case 'A' :
  519. X        card = 0;
  520. X        break;
  521. X    case '2' :
  522. X    case '3' :
  523. X    case '4' :
  524. X    case '5' :
  525. X    case '6' :
  526. X    case '7' :
  527. X    case '8' :
  528. X    case '9' :
  529. X        card = ch - '1';
  530. X        break;
  531. X    case '1' :
  532. X        if (getch() == '0') {
  533. X        card = 9;
  534. X        printch('0');
  535. X        } else
  536. X        return(BADCARD);
  537. X        break;
  538. X    case 'j' :
  539. X    case 'J' :
  540. X        card = 10;
  541. X        break;
  542. X    case 'q' :
  543. X    case 'Q' :
  544. X        card = 11;
  545. X        break;
  546. X    case 'k' :
  547. X    case 'K' :
  548. X        card = 12;
  549. X        break;
  550. X    default :
  551. X        return (BADCARD);
  552. X    }
  553. X    _face = card;
  554. X
  555. X    /* now get the suit */
  556. X    switch(getch()) {
  557. X    case 's' :
  558. X    case 'S' :
  559. X        suit = SPADE;
  560. X        break;
  561. X    case 'h' :
  562. X    case 'H' :
  563. X        suit = HEART;
  564. X        break;
  565. X    case 'c' :
  566. X    case 'C' :
  567. X        suit = CLUB;
  568. X        break;
  569. X    case 'd' :
  570. X    case 'D' :
  571. X        suit = DIAMOND;
  572. X        break;
  573. X    default :
  574. X        return (BADCARD);
  575. X    }
  576. X    _suit = suit;
  577. X
  578. X    /* now we've got the card.  find it in the deck */
  579. X    i = 0;
  580. X    do {
  581. X    if (card == deck[i].face && suit == deck[i].suit)
  582. X        return(i);
  583. X    } while (++i <= lastpile);
  584. X    return(NOTINDECK);
  585. X}
  586. X
  587. X/*
  588. X * check -- return if the card in postion "place" can move up the deck
  589. X */
  590. Xcheck(place)
  591. Xint place;
  592. X{
  593. X    int tmp = 0;
  594. X
  595. X    if (place < 1)
  596. X    return(tmp);
  597. X
  598. X    if ((deck[place-1].face == deck[place].face) ||
  599. X    (deck[place-1].suit == deck[place].suit)) {
  600. X    tmp |= MOVE1;
  601. X    }
  602. X
  603. X    if (place < 3)
  604. X    return(tmp);
  605. X
  606. X    if ((deck[place-3].face == deck[place].face) ||
  607. X    (deck[place-3].suit == deck[place].suit)) {
  608. X    tmp |= MOVE3;
  609. X    }
  610. X    return(tmp);
  611. X}
  612. X
  613. X/*
  614. X * putmsg -- print a message to the message buffer space
  615. X */
  616. Xputmsg(buffer)
  617. Xchar *buffer;
  618. X{
  619. X    int line = 0, pos, space, length;
  620. X    char *text[5];
  621. X    char tmpbuffer[BUFFERLENGTH];
  622. X    char *msgbuffer;
  623. X
  624. X    msgbuffer = tmpbuffer;
  625. X
  626. X    strcpy(msgbuffer,buffer);
  627. X
  628. X    while (line < 5) {
  629. X    length = strlen(msgbuffer);
  630. X    if (length >= 30) {
  631. X        text[line] = msgbuffer;
  632. X
  633. X        space = -1;
  634. X        for (pos=0; pos<30; pos++) 
  635. X        if (msgbuffer[pos] == ' ')
  636. X            space = pos;
  637. X
  638. X        if (space != -1)
  639. X        msgbuffer[space] = '\0';
  640. X        else
  641. X        space = 30;
  642. X
  643. X        msgbuffer += space + 1;
  644. X    } else if (length != 0) {
  645. X        text[line] = msgbuffer;
  646. X        msgbuffer += length;
  647. X    } else text[line] = 0;
  648. X    line++;
  649. X    }
  650. X
  651. X    for (line=0; line<5; line++) {
  652. X    if (_msg[line] || text[line] != 0)
  653. X        move(14+line,50);
  654. X
  655. X    if (_msg[line]) clrtoeol();
  656. X
  657. X    if (text[line] != 0) {
  658. X        printw("%s",text[line]);
  659. X        _msg[line] = TRUE;
  660. X    }
  661. X    }
  662. X}
  663. X
  664. X/*
  665. X * clearmsg -- clear the message buffer space
  666. X */
  667. Xclearmsg()
  668. X{
  669. X    int i;
  670. X
  671. X    for (i=0; i<5; i++) {
  672. X    if (_msg[i]) {
  673. X        move(14+i,50);
  674. X        clrtoeol();
  675. X        _msg[i] = FALSE;
  676. X    }
  677. X    }
  678. X}
  679. X
  680. X/*
  681. X * checkwin -- determine if the user has finished the game
  682. X */
  683. Xcheckwin(lastpile,nextcard)
  684. Xint lastpile, nextcard;
  685. X{
  686. X    int i;
  687. X
  688. X    if (nextcard != 52)
  689. X    return(MOREMOVES);
  690. X
  691. X    if (lastpile == 0)
  692. X    return(WIN);
  693. X
  694. X    for (i=0; i<=lastpile; i++)
  695. X    if (check(i) != 0)
  696. X        return(MOREMOVES);
  697. X
  698. X    return(LOSE);
  699. X}
  700. X
  701. X/*
  702. X * find_move -- a "cheater" function, to find first available move
  703. X */
  704. Xfind_move(lastpile)
  705. X{
  706. X    int i;
  707. X    for (i=0; i<=lastpile; i++) {
  708. X    if (check(i) != 0) {
  709. X        sprintf(buffer,"The %s of %s can move.",
  710. X        cardnames[deck[i].face],suitnames[deck[i].suit]);
  711. X        putmsg(buffer);
  712. X        return;
  713. X    }
  714. X    }
  715. X    putmsg("Try dealing more cards.");
  716. X}
  717. X
  718. X/*
  719. X * quit -- the nice control-C handler
  720. X */
  721. Xquit()
  722. X{
  723. X    move(21,0);
  724. X    refresh();
  725. X    resetty();
  726. X    endwin();
  727. X
  728. X    exit(0);
  729. X}
  730. X
  731. X/*
  732. X * savedeck -- save the deck into the "save" deck
  733. X */
  734. Xsavedeck(lastpile,nextcard)
  735. Xint lastpile, nextcard;
  736. X{
  737. X    int i;
  738. X
  739. X    for (i=0; i<52; i++) {
  740. X    save_deck[i].face = deck[i].face;
  741. X    save_deck[i].suit = deck[i].suit;
  742. X    save[i].num_spaces = undo[i].num_spaces;
  743. X    save[i].position = undo[i].position;
  744. X    }
  745. X    save_lastpile = lastpile;
  746. X    save_nextcard = nextcard;
  747. X    save_moves = nummoves;
  748. X}
  749. X
  750. X/*
  751. X * restoredeck -- restore the deck from the previously saved deck
  752. X */
  753. Xrestoredeck(lastpile,nextcard)
  754. Xint *lastpile, *nextcard;
  755. X{
  756. X    int i;
  757. X
  758. X    for (i=0; i<52; i++) {
  759. X    deck[i].face = save_deck[i].face;
  760. X    deck[i].suit = save_deck[i].suit;
  761. X    undo[i].position = save[i].position;
  762. X    undo[i].num_spaces = save[i].num_spaces;
  763. X    }
  764. X    *lastpile = save_lastpile;
  765. X    *nextcard = save_nextcard;
  766. X    nummoves = save_moves;
  767. X}
  768. X
  769. X/*
  770. X * printch -- print a character to the screen, filtering out
  771. X *            all non-alphanumeric characters
  772. X */
  773. Xprintch(ch)
  774. Xint ch;
  775. X{
  776. X    if ((ch >= 'a' && ch <= 'z') ||
  777. X    (ch >= 'A' && ch <= 'Z') || 
  778. X    (ch >= '0' && ch <= '9')) {
  779. X    printw("%c",ch);
  780. X    refresh();
  781. X    }
  782. X}
  783. X
  784. X/*
  785. X * save_win -- save this win to the "win" file, for historical purposes
  786. X */
  787. Xsave_win()
  788. X{
  789. X    time_t utime;
  790. X    struct passwd *pw;
  791. X    char *name;
  792. X    FILE *fp;
  793. X
  794. X    fp = fopen(ACCORDIAN_WINFILE,"a+");
  795. X    if (!fp) return;
  796. X
  797. X    time(&utime);
  798. X    pw = getpwuid(getuid());
  799. X    if (!pw)
  800. X    name = "Someone with no name";
  801. X    else
  802. X    name = pw->pw_name;
  803. X
  804. X    fprintf(fp,"%s won on %s",name,ctime(&utime));
  805. X
  806. X    fclose(fp);
  807. X}
  808. X
  809. END_OF_FILE
  810. if test 13179 -ne `wc -c <'accordian.c'`; then
  811.     echo shar: \"'accordian.c'\" unpacked with wrong size!
  812. fi
  813. # end of 'accordian.c'
  814. fi
  815. if test -f 'accordian.man' -a "${1}" != "-c" ; then 
  816.   echo shar: Will not clobber existing file \"'accordian.man'\"
  817. else
  818. echo shar: Extracting \"'accordian.man'\" \(1844 characters\)
  819. sed "s/^X//" >'accordian.man' <<'END_OF_FILE'
  820. X.TH ACCORDIAN 6 "16 November 1992"
  821. X.SH NAME
  822. Xaccordian
  823. X\- the ``Accordian'' solitaire card game
  824. X.SH SYNOPSIS
  825. X.B accordian
  826. X.SH DESCRIPTION
  827. XThe deck of cards is dealt either a card at a time, or the
  828. Xentire deck at once, depending on your playing style.  After
  829. Xcards are dealt, each card, and the stack underneath it, can
  830. Xbe moved either 1 or 3 spaces, onto another stack where that
  831. Xhas the same rank or suit for the topmost card in the stack.
  832. X.PP
  833. XThe goal of the game is to move all the cards into a single
  834. Xstack, containing all the cards.
  835. X.SH COMMANDS
  836. X.RS
  837. XSelect cards by typing their face value and suit.  The
  838. Xcards are 2 to 9, J, Q, K, and A.  The suits are H, S, D, and C.
  839. XIf the card selected has only one choice for its move, it moves
  840. Xautomatically.  You will be prompted for your move, if you have
  841. Xa choice between moving the card 1 or 3 spaces.
  842. X.IP `d'
  843. XDeal a single card from the deck.
  844. X.IP `D'
  845. XDeal the remainder of the deck.
  846. X.IP `f'
  847. XFind the first card that is still able to move.
  848. X.IP `s'
  849. XSave the current deck into memory, so it can be restored later.
  850. XThis is the only way to `redo' moves you have undone.
  851. X.IP `r'
  852. XRestore the most recently saved copy of the deck.
  853. X.IP `u'
  854. XUndo the last single move.  `Undo' will save all the previous moves
  855. Xthat you have played, except for saving and restoring the deck.
  856. X.IP `x'
  857. XExit from Accordian.
  858. X.IP `^R'
  859. XRedraw the screen
  860. X.IP `?'
  861. XPrint a screen of instructions and help.
  862. X.RE
  863. X.SH OPTIONS
  864. X.RS
  865. XIf any command line options are specified,
  866. X.B accordian
  867. Xwill print the same help as found by typing `?' while playing the game.
  868. X.RE
  869. X.SH HISTORY
  870. XAccordian was originally written during Summer 1990.  Minor enhancements
  871. Xwere made in March 1991, and November 1992.
  872. X.SH BUGS
  873. XThe game is almost impossible to win.  This is a bug in the
  874. Xgame, not the implementation.  :-)
  875. X.SH AUTHOR
  876. XEric Lechner, ericl@xilinx.com
  877. END_OF_FILE
  878. if test 1844 -ne `wc -c <'accordian.man'`; then
  879.     echo shar: \"'accordian.man'\" unpacked with wrong size!
  880. fi
  881. # end of 'accordian.man'
  882. fi
  883. if test -f 'cards.c' -a "${1}" != "-c" ; then 
  884.   echo shar: Will not clobber existing file \"'cards.c'\"
  885. else
  886. echo shar: Extracting \"'cards.c'\" \(958 characters\)
  887. sed "s/^X//" >'cards.c' <<'END_OF_FILE'
  888. X/*
  889. X * cards.c - generic card utilities
  890. X */
  891. X
  892. X#include "cards.h"
  893. X
  894. Xchar *cards[] = {
  895. X        "A",
  896. X        "2",
  897. X        "3",
  898. X        "4",
  899. X        "5",
  900. X        "6",
  901. X        "7",
  902. X        "8",
  903. X        "9",
  904. X        "10",
  905. X        "J",
  906. X        "Q",
  907. X        "K"
  908. X    };
  909. X
  910. Xchar *cardnames[] = {
  911. X        "Ace",
  912. X        "Two",
  913. X        "Three",
  914. X        "Four",
  915. X        "Five",
  916. X        "Six",
  917. X        "Seven",
  918. X        "Eight",
  919. X        "Nine",
  920. X        "Ten",
  921. X        "Jack",
  922. X        "Queen",
  923. X        "King"
  924. X    };
  925. X
  926. Xchar *suits[] = {
  927. X        "S",
  928. X        "H",
  929. X        "C",
  930. X        "D"
  931. X    };
  932. X
  933. Xchar *suitnames[] = {
  934. X        "Spades",
  935. X        "Hearts",
  936. X        "Clubs",
  937. X        "Diamonds"
  938. X    };
  939. X
  940. Xshuffle()
  941. X{
  942. X    int i;
  943. X    for (i=0; i<52; i++) {
  944. X        swap(i,RANDOM() % 52);
  945. X    }
  946. X}
  947. X
  948. Xswap(card1,card2)
  949. Xint card1, card2;
  950. X{
  951. X    int face, suit;
  952. X
  953. X    face = deck[card1].face;
  954. X    deck[card1].face = deck[card2].face;
  955. X    deck[card2].face = face;
  956. X
  957. X    suit = deck[card1].suit;
  958. X    deck[card1].suit = deck[card2].suit;
  959. X    deck[card2].suit = suit;
  960. X}
  961. X
  962. Xnewdeck()
  963. X{
  964. X    int face;
  965. X    int suit;
  966. X
  967. X    for (face = 0; face < 13; face++) {
  968. X        for (suit=0; suit<4; suit++) {
  969. X            deck[suit*13+face].face = face;
  970. X            deck[suit*13+face].suit = suit;
  971. X        }
  972. X    }
  973. X}
  974. END_OF_FILE
  975. if test 958 -ne `wc -c <'cards.c'`; then
  976.     echo shar: \"'cards.c'\" unpacked with wrong size!
  977. fi
  978. # end of 'cards.c'
  979. fi
  980. if test -f 'cards.h' -a "${1}" != "-c" ; then 
  981.   echo shar: Will not clobber existing file \"'cards.h'\"
  982. else
  983. echo shar: Extracting \"'cards.h'\" \(634 characters\)
  984. sed "s/^X//" >'cards.h' <<'END_OF_FILE'
  985. X/*
  986. X * cards.h - the include library with all the definitions for card things
  987. X */
  988. X
  989. X#define REVERSE    1    /* the suit should be displayed in reverse */
  990. X#define NORMAL    0
  991. X
  992. X#define SPADE    0    /* the types of cards */
  993. X#define HEART    1    /* this should ALWAYS match the suits[] array */
  994. X#define CLUB    2
  995. X#define DIAMOND    3
  996. X
  997. X#ifndef TRUE
  998. X#define TRUE 1
  999. X#endif
  1000. X#ifndef FALSE
  1001. X#define FALSE 0
  1002. X#endif
  1003. X
  1004. Xstruct card {
  1005. X    int face;
  1006. X    int suit;
  1007. X};
  1008. X
  1009. Xextern char *cards[];
  1010. Xextern char *cardnames[];
  1011. Xextern char *suits[];
  1012. Xextern char *suitnames[];
  1013. Xextern char *helplist[];
  1014. Xextern struct card deck[52];
  1015. X
  1016. Xextern newdeck();
  1017. Xextern shuffle();
  1018. Xextern swap();
  1019. Xextern help();
  1020. END_OF_FILE
  1021. if test 634 -ne `wc -c <'cards.h'`; then
  1022.     echo shar: \"'cards.h'\" unpacked with wrong size!
  1023. fi
  1024. # end of 'cards.h'
  1025. fi
  1026. if test -f 'help.c' -a "${1}" != "-c" ; then 
  1027.   echo shar: Will not clobber existing file \"'help.c'\"
  1028. else
  1029. echo shar: Extracting \"'help.c'\" \(1621 characters\)
  1030. sed "s/^X//" >'help.c' <<'END_OF_FILE'
  1031. X
  1032. X/*
  1033. X * the accordian help stuff
  1034. X */
  1035. X
  1036. X#include <stdio.h>
  1037. X#include <curses.h>
  1038. X#include "cards.h"
  1039. X
  1040. X#define HELPHEIGHT 22
  1041. X
  1042. Xchar *helplist[] = {
  1043. X        "          Welcome to Accordian Solitaire!",
  1044. X        "",
  1045. X        "The goal of the game is to deal all cards from the",
  1046. X        "deck, and stack them into a single pile of cards.",
  1047. X        "Cards can move onto other cards that are one or",
  1048. X        "three cards up in the deck.  Cards can only stack",
  1049. X        "onto other cards of the same suit or rank.",
  1050. X        "",
  1051. X        "Select cards by typing their face value and suit.",
  1052. X        "The card moves automatically if it has only one move.",
  1053. X        "You must choose the move if there are multiple moves.",
  1054. X        "",
  1055. X        "         Keys :",
  1056. X        "           `d' : Deal a card from the deck",
  1057. X        "           `D' : Deal the whole deck",
  1058. X        "           `f' : Find a card that can move",
  1059. X        "           `s' : Save a copy of the deck",
  1060. X        "           `u' : Undo the last move",
  1061. X        "           `r' : Restore the saved deck",
  1062. X        "           `x' : Exit from Accordian",
  1063. X        "          `^R' : Redraw the screen",
  1064. X    0 };
  1065. X
  1066. Xhelp()
  1067. X{
  1068. X    int c2, ch, done, start;
  1069. X
  1070. X    clear();
  1071. X
  1072. X    c2 = start = 0;
  1073. X    done = FALSE;
  1074. X
  1075. X    while (!done) {
  1076. XHelp:        for (c2 = start; c2 < start + HELPHEIGHT; c2++) {
  1077. X            if (helplist[c2] == 0) {
  1078. X                done = TRUE;
  1079. X                break;
  1080. X            }
  1081. X            move(1 + (c2 % HELPHEIGHT),13);
  1082. X            printw("%s",helplist[c2]);
  1083. X        }
  1084. X
  1085. X        move(23,26);
  1086. X        printw("     - hit any key -       ");
  1087. X        move(23,48);
  1088. X    
  1089. X        refresh();
  1090. X        ch = getch();
  1091. X        switch (ch) {
  1092. X            case 0x12 :
  1093. X            case 0x0c :
  1094. X                clear();
  1095. X                c2 = start;
  1096. X                goto Help;
  1097. X                break;
  1098. X            case 'x' :
  1099. X            case 'X' :
  1100. X            case 'q' :
  1101. X            case 'Q' :
  1102. X                done = TRUE;
  1103. X                break;
  1104. X        }
  1105. X        start = c2;
  1106. X    }
  1107. X}
  1108. X
  1109. END_OF_FILE
  1110. if test 1621 -ne `wc -c <'help.c'`; then
  1111.     echo shar: \"'help.c'\" unpacked with wrong size!
  1112. fi
  1113. # end of 'help.c'
  1114. fi
  1115. if test -f 'makefile' -a "${1}" != "-c" ; then 
  1116.   echo shar: Will not clobber existing file \"'makefile'\"
  1117. else
  1118. echo shar: Extracting \"'makefile'\" \(1767 characters\)
  1119. sed "s/^X//" >'makefile' <<'END_OF_FILE'
  1120. X#
  1121. X# makefile for accordian
  1122. X#
  1123. X
  1124. X# The high score file:
  1125. XWINFILE = /home/baggins/ericl/lib/accordian.wins
  1126. X
  1127. X# Where the program will live
  1128. XDESTDIR = /home/baggins/ericl/bin
  1129. X
  1130. X# Where the manpage will live
  1131. XMANDIR = /home/baggins/ericl/man
  1132. X
  1133. X
  1134. X# Which random number generator your system uses
  1135. X# these worked under SunOS (BSD-ish)
  1136. XRANDOM = random
  1137. XSRANDOM = srandom
  1138. X# these worked under IRIX (SysV-ish)
  1139. X#RANDOM = lrand48
  1140. X#SRANDOM = srand48
  1141. X
  1142. X# where the default pager lives
  1143. X# bsd-ish systems use;
  1144. XPAGER = /usr/ucb/more
  1145. X# irix uses:
  1146. X#PAGER = /usr/bsd/more
  1147. X# most SysV machines use:
  1148. X#PAGER = /usr/bin/more
  1149. X
  1150. X
  1151. X# compiler options
  1152. XCC = cc
  1153. X
  1154. X# these worked under SunOS
  1155. XLOCAL_CFLAGS = -g
  1156. XLOCAL_LFLAGS = -g
  1157. XLLIBS = -lcurses -ltermcap
  1158. X
  1159. X# these worked under SYS_V (SGI IRIX)
  1160. X# (note: IRIX uses "-cckr" to make the compiler like K+R C.
  1161. X# Your machine may need something different to specify this.)
  1162. X#LOCAL_CFLAGS = -g -cckr
  1163. X#LOCAL_LFLAGS = -g
  1164. X#LLIBS = -lcurses
  1165. X
  1166. X
  1167. XCFLAGS = $(LOCAL_CFLAGS) -DRANDOM=$(RANDOM) -DSRANDOM=$(SRANDOM) \
  1168. X    -DACCORDIAN_WINFILE=\"$(WINFILE)\" -DDEFAULT_PAGER=\"$(PAGER)\"
  1169. XLFLAGS = $(LOCAL_LFLAGS)
  1170. X
  1171. X
  1172. XOBJS =    accordian.o \
  1173. X    cards.o \
  1174. X    help.o
  1175. X
  1176. Xaccordian: $(OBJS)
  1177. X    $(CC) $(LFLAGS) $(OBJS) -o $@ $(LLIBS)
  1178. X
  1179. X##  Creating manpages.
  1180. X.SUFFIXES:    .6 .man
  1181. X.man.6:
  1182. X    @rm -f $@
  1183. X    nroff -man $< > $@
  1184. X    chmod 444 $@
  1185. X
  1186. Xinstall: accordian accordian.6
  1187. X    cp accordian $(DESTDIR)
  1188. X    chmod 711 $(DESTDIR)/accordian
  1189. X    cp accordian.6 $(MANDIR)/accordian.6
  1190. X    chmod 644 $(MANDIR)/accordian.6
  1191. X
  1192. X$(OBJS) : cards.h makefile
  1193. X
  1194. Xclobber:
  1195. X    make clean
  1196. X    @ rm -f accordian accordian.6 accordian.sh
  1197. Xclean:
  1198. X    @ rm -f $(OBJS)
  1199. X
  1200. X#
  1201. X# all the stuff that gets packed into the archive file
  1202. X#
  1203. XSHARSTUFF = \
  1204. X    README \
  1205. X    makefile \
  1206. X    accordian.c \
  1207. X    help.c \
  1208. X    cards.c \
  1209. X    cards.h \
  1210. X    accordian.man
  1211. X
  1212. Xshar:
  1213. X    shar $(SHARSTUFF) > accordian.sh
  1214. END_OF_FILE
  1215. if test 1767 -ne `wc -c <'makefile'`; then
  1216.     echo shar: \"'makefile'\" unpacked with wrong size!
  1217. fi
  1218. # end of 'makefile'
  1219. fi
  1220. echo shar: End of archive 1 \(of 1\).
  1221. cp /dev/null ark1isdone
  1222. MISSING=""
  1223. for I in 1 ; do
  1224.     if test ! -f ark${I}isdone ; then
  1225.     MISSING="${MISSING} ${I}"
  1226.     fi
  1227. done
  1228. if test "${MISSING}" = "" ; then
  1229.     echo You have the archive.
  1230.     rm -f ark[1-9]isdone
  1231. else
  1232.     echo You still need to unpack the following archives:
  1233.     echo "        " ${MISSING}
  1234. fi
  1235. ##  End of shell archive.
  1236. exit 0
  1237.  
  1238.  
  1239.  unoryoryoS)  syoryoryoS)  syoryoryoS)  syoryoryoS)  syory
  1240.