|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)canfield.c 5.10 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: /*
31: * The canfield program
32: *
33: * Authors:
34: * Originally written: Steve Levine
35: * Converted to use curses and debugged: Steve Feldman
36: * Card counting: Kirk McKusick and Mikey Olson
37: * User interface cleanups: Eric Allman and Kirk McKusick
38: * Betting by Kirk McKusick
39: */
40:
41: #include <sys/types.h>
42: #include <sys/signal.h>
43: #include <curses.h>
44: #include <ctype.h>
45: #include "pathnames.h"
46:
47: #define decksize 52
48: #define originrow 0
49: #define origincol 0
50: #define basecol 1
51: #define boxcol 42
52: #define tboxrow 2
53: #define bboxrow 17
54: #define movecol 43
55: #define moverow 16
56: #define msgcol 43
57: #define msgrow 15
58: #define titlecol 30
59: #define titlerow 0
60: #define sidecol 1
61: #define ottlrow 6
62: #define foundcol 11
63: #define foundrow 3
64: #define stockcol 2
65: #define stockrow 8
66: #define fttlcol 10
67: #define fttlrow 1
68: #define taloncol 2
69: #define talonrow 13
70: #define tabrow 8
71: #define ctoprow 21
72: #define cbotrow 23
73: #define cinitcol 14
74: #define cheightcol 1
75: #define cwidthcol 4
76: #define handstatrow 21
77: #define handstatcol 7
78: #define talonstatrow 22
79: #define talonstatcol 7
80: #define stockstatrow 23
81: #define stockstatcol 7
82: #define Ace 1
83: #define Jack 11
84: #define Queen 12
85: #define King 13
86: #define atabcol 11
87: #define btabcol 18
88: #define ctabcol 25
89: #define dtabcol 32
90:
91: #define spades 's'
92: #define clubs 'c'
93: #define hearts 'h'
94: #define diamonds 'd'
95: #define black 'b'
96: #define red 'r'
97:
98: #define stk 1
99: #define tal 2
100: #define tab 3
101: #define INCRHAND(row, col) {\
102: row -= cheightcol;\
103: if (row < ctoprow) {\
104: row = cbotrow;\
105: col += cwidthcol;\
106: }\
107: }
108: #define DECRHAND(row, col) {\
109: row += cheightcol;\
110: if (row > cbotrow) {\
111: row = ctoprow;\
112: col -= cwidthcol;\
113: }\
114: }
115:
116:
117: struct cardtype {
118: char suit;
119: char color;
120: bool visible;
121: bool paid;
122: int rank;
123: struct cardtype *next;
124: };
125:
126: #define NIL ((struct cardtype *) -1)
127:
128: struct cardtype *deck[decksize];
129: struct cardtype cards[decksize];
130: struct cardtype *bottom[4], *found[4], *tableau[4];
131: struct cardtype *talon, *hand, *stock, *basecard;
132: int length[4];
133: int cardsoff, base, cinhand, taloncnt, stockcnt, timesthru;
134: char suitmap[4] = {spades, clubs, hearts, diamonds};
135: char colormap[4] = {black, black, red, red};
136: char pilemap[4] = {atabcol, btabcol, ctabcol, dtabcol};
137: char srcpile, destpile;
138: int mtforigin, tempbase;
139: int coldcol, cnewcol, coldrow, cnewrow;
140: bool errmsg, done;
141: bool mtfdone, Cflag = FALSE;
142: #define INSTRUCTIONBOX 1
143: #define BETTINGBOX 2
144: #define NOBOX 3
145: int status = INSTRUCTIONBOX;
146: int uid;
147:
148: /*
149: * Basic betting costs
150: */
151: #define costofhand 13
152: #define costofinspection 13
153: #define costofgame 26
154: #define costofrunthroughhand 5
155: #define costofinformation 1
156: #define secondsperdollar 60
157: #define maxtimecharge 3
158: #define valuepercardup 5
159: /*
160: * Variables associated with betting
161: */
162: struct betinfo {
163: long hand; /* cost of dealing hand */
164: long inspection; /* cost of inspecting hand */
165: long game; /* cost of buying game */
166: long runs; /* cost of running through hands */
167: long information; /* cost of information */
168: long thinktime; /* cost of thinking time */
169: long wins; /* total winnings */
170: long worth; /* net worth after costs */
171: };
172: struct betinfo this, game, total;
173: bool startedgame = FALSE, infullgame = FALSE;
174: time_t acctstart;
175: int dbfd = -1;
176:
177: /*
178: * The following procedures print the board onto the screen using the
179: * addressible cursor. The end of these procedures will also be
180: * separated from the rest of the program.
181: *
182: * procedure to set the move command box
183: */
184: movebox()
185: {
186: switch (status) {
187: case BETTINGBOX:
188: printtopbettingbox();
189: break;
190: case NOBOX:
191: clearabovemovebox();
192: break;
193: case INSTRUCTIONBOX:
194: printtopinstructions();
195: break;
196: }
197: move(moverow, boxcol);
198: printw("| |");
199: move(msgrow, boxcol);
200: printw("| |");
201: switch (status) {
202: case BETTINGBOX:
203: printbottombettingbox();
204: break;
205: case NOBOX:
206: clearbelowmovebox();
207: break;
208: case INSTRUCTIONBOX:
209: printbottominstructions();
210: break;
211: }
212: refresh();
213: }
214:
215: /*
216: * print directions above move box
217: */
218: printtopinstructions()
219: {
220: move(tboxrow, boxcol);
221: printw("*----------------------------------*");
222: move(tboxrow + 1, boxcol);
223: printw("| MOVES |");
224: move(tboxrow + 2, boxcol);
225: printw("|s# = stock to tableau |");
226: move(tboxrow + 3, boxcol);
227: printw("|sf = stock to foundation |");
228: move(tboxrow + 4, boxcol);
229: printw("|t# = talon to tableau |");
230: move(tboxrow + 5, boxcol);
231: printw("|tf = talon to foundation |");
232: move(tboxrow + 6, boxcol);
233: printw("|## = tableau to tableau |");
234: move(tboxrow + 7, boxcol);
235: printw("|#f = tableau to foundation |");
236: move(tboxrow + 8, boxcol);
237: printw("|ht = hand to talon |");
238: move(tboxrow + 9, boxcol);
239: printw("|c = toggle card counting |");
240: move(tboxrow + 10, boxcol);
241: printw("|b = present betting information |");
242: move(tboxrow + 11, boxcol);
243: printw("|q = quit to end the game |");
244: move(tboxrow + 12, boxcol);
245: printw("|==================================|");
246: }
247:
248: /*
249: * Print the betting box.
250: */
251: printtopbettingbox()
252: {
253:
254: move(tboxrow, boxcol);
255: printw("*----------------------------------*");
256: move(tboxrow + 1, boxcol);
257: printw("|Costs Hand Game Total |");
258: move(tboxrow + 2, boxcol);
259: printw("| Hands |");
260: move(tboxrow + 3, boxcol);
261: printw("| Inspections |");
262: move(tboxrow + 4, boxcol);
263: printw("| Games |");
264: move(tboxrow + 5, boxcol);
265: printw("| Runs |");
266: move(tboxrow + 6, boxcol);
267: printw("| Information |");
268: move(tboxrow + 7, boxcol);
269: printw("| Think time |");
270: move(tboxrow + 8, boxcol);
271: printw("|Total Costs |");
272: move(tboxrow + 9, boxcol);
273: printw("|Winnings |");
274: move(tboxrow + 10, boxcol);
275: printw("|Net Worth |");
276: move(tboxrow + 11, boxcol);
277: printw("|Return |");
278: move(tboxrow + 12, boxcol);
279: printw("|==================================|");
280: }
281:
282: /*
283: * clear info above move box
284: */
285: clearabovemovebox()
286: {
287: int i;
288:
289: for (i = 0; i <= 11; i++) {
290: move(tboxrow + i, boxcol);
291: printw(" ");
292: }
293: move(tboxrow + 12, boxcol);
294: printw("*----------------------------------*");
295: }
296:
297: /*
298: * print instructions below move box
299: */
300: printbottominstructions()
301: {
302: move(bboxrow, boxcol);
303: printw("|Replace # with the number of the |");
304: move(bboxrow + 1, boxcol);
305: printw("|tableau you want. |");
306: move(bboxrow + 2, boxcol);
307: printw("*----------------------------------*");
308: }
309:
310: /*
311: * print betting information below move box
312: */
313: printbottombettingbox()
314: {
315: move(bboxrow, boxcol);
316: printw("|x = toggle information box |");
317: move(bboxrow + 1, boxcol);
318: printw("|i = list playing instructions |");
319: move(bboxrow + 2, boxcol);
320: printw("*----------------------------------*");
321: }
322:
323: /*
324: * clear info below move box
325: */
326: clearbelowmovebox()
327: {
328: int i;
329:
330: move(bboxrow, boxcol);
331: printw("*----------------------------------*");
332: for (i = 1; i <= 2; i++) {
333: move(bboxrow + i, boxcol);
334: printw(" ");
335: }
336: }
337:
338: /*
339: * procedure to put the board on the screen using addressable cursor
340: */
341: makeboard()
342: {
343: clear();
344: refresh();
345: move(titlerow, titlecol);
346: printw("=-> CANFIELD <-=");
347: move(fttlrow, fttlcol);
348: printw("foundation");
349: move(foundrow - 1, fttlcol);
350: printw("=---= =---= =---= =---=");
351: move(foundrow, fttlcol);
352: printw("| | | | | | | |");
353: move(foundrow + 1, fttlcol);
354: printw("=---= =---= =---= =---=");
355: move(ottlrow, sidecol);
356: printw("stock tableau");
357: move(stockrow - 1, sidecol);
358: printw("=---=");
359: move(stockrow, sidecol);
360: printw("| |");
361: move(stockrow + 1, sidecol);
362: printw("=---=");
363: move(talonrow - 2, sidecol);
364: printw("talon");
365: move(talonrow - 1, sidecol);
366: printw("=---=");
367: move(talonrow, sidecol);
368: printw("| |");
369: move(talonrow + 1, sidecol);
370: printw("=---=");
371: move(tabrow - 1, atabcol);
372: printw("-1- -2- -3- -4-");
373: movebox();
374: }
375:
376: /*
377: * clean up the board for another game
378: */
379: cleanupboard()
380: {
381: int cnt, row, col;
382: struct cardtype *ptr;
383:
384: if (Cflag) {
385: clearstat();
386: for(ptr = stock, row = stockrow;
387: ptr != NIL;
388: ptr = ptr->next, row++) {
389: move(row, sidecol);
390: printw(" ");
391: }
392: move(row, sidecol);
393: printw(" ");
394: move(stockrow + 1, sidecol);
395: printw("=---=");
396: move(talonrow - 2, sidecol);
397: printw("talon");
398: move(talonrow - 1, sidecol);
399: printw("=---=");
400: move(talonrow + 1, sidecol);
401: printw("=---=");
402: }
403: move(stockrow, sidecol);
404: printw("| |");
405: move(talonrow, sidecol);
406: printw("| |");
407: move(foundrow, fttlcol);
408: printw("| | | | | | | |");
409: for (cnt = 0; cnt < 4; cnt++) {
410: switch(cnt) {
411: case 0:
412: col = atabcol;
413: break;
414: case 1:
415: col = btabcol;
416: break;
417: case 2:
418: col = ctabcol;
419: break;
420: case 3:
421: col = dtabcol;
422: break;
423: }
424: for(ptr = tableau[cnt], row = tabrow;
425: ptr != NIL;
426: ptr = ptr->next, row++)
427: removecard(col, row);
428: }
429: }
430:
431: /*
432: * procedure to create a deck of cards
433: */
434: initdeck(deck)
435: struct cardtype *deck[];
436: {
437: int i;
438: int scnt;
439: char s;
440: int r;
441:
442: i = 0;
443: for (scnt=0; scnt<4; scnt++) {
444: s = suitmap[scnt];
445: for (r=Ace; r<=King; r++) {
446: deck[i] = &cards[i];
447: cards[i].rank = r;
448: cards[i].suit = s;
449: cards[i].color = colormap[scnt];
450: cards[i].next = NIL;
451: i++;
452: }
453: }
454: }
455:
456: /*
457: * procedure to shuffle the deck
458: */
459: shuffle(deck)
460: struct cardtype *deck[];
461: {
462: int i,j;
463: struct cardtype *temp;
464:
465: for (i=0; i<decksize; i++) {
466: deck[i]->visible = FALSE;
467: deck[i]->paid = FALSE;
468: }
469: for (i = decksize-1; i>=0; i--) {
470: j = random() % decksize;
471: if (i != j) {
472: temp = deck[i];
473: deck[i] = deck[j];
474: deck[j] = temp;
475: }
476: }
477: }
478:
479: /*
480: * procedure to remove the card from the board
481: */
482: removecard(a, b)
483: {
484: move(b, a);
485: printw(" ");
486: }
487:
488: /*
489: * procedure to print the cards on the board
490: */
491: printrank(a, b, cp, inverse)
492: struct cardtype *cp;
493: bool inverse;
494: {
495: move(b, a);
496: if (cp->rank != 10)
497: addch(' ');
498: if (inverse)
499: standout();
500: switch (cp->rank) {
501: case 2: case 3: case 4: case 5: case 6: case 7:
502: case 8: case 9: case 10:
503: printw("%d", cp->rank);
504: break;
505: case Ace:
506: addch('A');
507: break;
508: case Jack:
509: addch('J');
510: break;
511: case Queen:
512: addch('Q');
513: break;
514: case King:
515: addch('K');
516: }
517: if (inverse)
518: standend();
519: }
520:
521: /*
522: * procedure to print out a card
523: */
524: printcard(a, b, cp)
525: int a,b;
526: struct cardtype *cp;
527: {
528: if (cp == NIL)
529: removecard(a, b);
530: else if (cp->visible == FALSE) {
531: move(b, a);
532: printw(" ? ");
533: } else {
534: bool inverse = (cp->suit == 'd' || cp->suit == 'h');
535:
536: printrank(a, b, cp, inverse);
537: if (inverse)
538: standout();
539: addch(cp->suit);
540: if (inverse)
541: standend();
542: }
543: }
544:
545: /*
546: * procedure to move the top card from one location to the top
547: * of another location. The pointers always point to the top
548: * of the piles.
549: */
550: transit(source, dest)
551: struct cardtype **source, **dest;
552: {
553: struct cardtype *temp;
554:
555: temp = *source;
556: *source = (*source)->next;
557: temp->next = *dest;
558: *dest = temp;
559: }
560:
561: /*
562: * Procedure to set the cards on the foundation base when available.
563: * Note that it is only called on a foundation pile at the beginning of
564: * the game, so the pile will have exactly one card in it.
565: */
566: fndbase(cp, column, row)
567: struct cardtype **cp;
568: {
569: bool nomore;
570:
571: if (*cp != NIL)
572: do {
573: if ((*cp)->rank == basecard->rank) {
574: base++;
575: printcard(pilemap[base], foundrow, *cp);
576: if (*cp == tableau[0])
577: length[0] = length[0] - 1;
578: if (*cp == tableau[1])
579: length[1] = length[1] - 1;
580: if (*cp == tableau[2])
581: length[2] = length[2] - 1;
582: if (*cp == tableau[3])
583: length[3] = length[3] - 1;
584: transit(cp, &found[base]);
585: if (cp == &talon)
586: usedtalon();
587: if (cp == &stock)
588: usedstock();
589: if (*cp != NIL) {
590: printcard(column, row, *cp);
591: nomore = FALSE;
592: } else {
593: removecard(column, row);
594: nomore = TRUE;
595: }
596: cardsoff++;
597: if (infullgame) {
598: this.wins += valuepercardup;
599: game.wins += valuepercardup;
600: total.wins += valuepercardup;
601: }
602: } else
603: nomore = TRUE;
604: } while (nomore == FALSE);
605: }
606:
607: /*
608: * procedure to initialize the things necessary for the game
609: */
610: initgame()
611: {
612: register i;
613:
614: for (i=0; i<18; i++) {
615: deck[i]->visible = TRUE;
616: deck[i]->paid = TRUE;
617: }
618: stockcnt = 13;
619: stock = deck[12];
620: for (i=12; i>=1; i--)
621: deck[i]->next = deck[i - 1];
622: deck[0]->next = NIL;
623: found[0] = deck[13];
624: deck[13]->next = NIL;
625: for (i=1; i<4; i++)
626: found[i] = NIL;
627: basecard = found[0];
628: for (i=14; i<18; i++) {
629: tableau[i - 14] = deck[i];
630: deck[i]->next = NIL;
631: }
632: for (i=0; i<4; i++) {
633: bottom[i] = tableau[i];
634: length[i] = tabrow;
635: }
636: hand = deck[18];
637: for (i=18; i<decksize-1; i++)
638: deck[i]->next = deck[i + 1];
639: deck[decksize-1]->next = NIL;
640: talon = NIL;
641: base = 0;
642: cinhand = 34;
643: taloncnt = 0;
644: timesthru = 0;
645: cardsoff = 1;
646: coldrow = ctoprow;
647: coldcol = cinitcol;
648: cnewrow = ctoprow;
649: cnewcol = cinitcol + cwidthcol;
650: }
651:
652: /*
653: * procedure to print the beginning cards and to start each game
654: */
655: startgame()
656: {
657: register int j;
658:
659: shuffle(deck);
660: initgame();
661: this.hand = costofhand;
662: game.hand += costofhand;
663: total.hand += costofhand;
664: this.inspection = 0;
665: this.game = 0;
666: this.runs = 0;
667: this.information = 0;
668: this.wins = 0;
669: this.thinktime = 0;
670: infullgame = FALSE;
671: startedgame = FALSE;
672: printcard(foundcol, foundrow, found[0]);
673: printcard(stockcol, stockrow, stock);
674: printcard(atabcol, tabrow, tableau[0]);
675: printcard(btabcol, tabrow, tableau[1]);
676: printcard(ctabcol, tabrow, tableau[2]);
677: printcard(dtabcol, tabrow, tableau[3]);
678: printcard(taloncol, talonrow, talon);
679: move(foundrow - 2, basecol);
680: printw("Base");
681: move(foundrow - 1, basecol);
682: printw("Rank");
683: printrank(basecol, foundrow, found[0], 0);
684: for (j=0; j<=3; j++)
685: fndbase(&tableau[j], pilemap[j], tabrow);
686: fndbase(&stock, stockcol, stockrow);
687: showstat(); /* show card counting info to cheaters */
688: movetotalon();
689: updatebettinginfo();
690: }
691:
692: /*
693: * procedure to clear the message printed from an error
694: */
695: clearmsg()
696: {
697: int i;
698:
699: if (errmsg == TRUE) {
700: errmsg = FALSE;
701: move(msgrow, msgcol);
702: for (i=0; i<25; i++)
703: addch(' ');
704: refresh();
705: }
706: }
707:
708: /*
709: * procedure to print an error message if the move is not listed
710: */
711: dumberror()
712: {
713: errmsg = TRUE;
714: move(msgrow, msgcol);
715: printw("Not a proper move ");
716: }
717:
718: /*
719: * procedure to print an error message if the move is not possible
720: */
721: destinerror()
722: {
723: errmsg = TRUE;
724: move(msgrow, msgcol);
725: printw("Error: Can't move there");
726: }
727:
728: /*
729: * function to see if the source has cards in it
730: */
731: bool
732: notempty(cp)
733: struct cardtype *cp;
734: {
735: if (cp == NIL) {
736: errmsg = TRUE;
737: move(msgrow, msgcol);
738: printw("Error: no cards to move");
739: return (FALSE);
740: } else
741: return (TRUE);
742: }
743:
744: /*
745: * function to see if the rank of one card is less than another
746: */
747: bool
748: ranklower(cp1, cp2)
749: struct cardtype *cp1, *cp2;
750: {
751: if (cp2->rank == Ace)
752: if (cp1->rank == King)
753: return (TRUE);
754: else
755: return (FALSE);
756: else if (cp1->rank + 1 == cp2->rank)
757: return (TRUE);
758: else
759: return (FALSE);
760: }
761:
762: /*
763: * function to check the cardcolor for moving to a tableau
764: */
765: bool
766: diffcolor(cp1, cp2)
767: struct cardtype *cp1, *cp2;
768: {
769: if (cp1->color == cp2->color)
770: return (FALSE);
771: else
772: return (TRUE);
773: }
774:
775: /*
776: * function to see if the card can move to the tableau
777: */
778: bool
779: tabok(cp, des)
780: struct cardtype *cp;
781: {
782: if ((cp == stock) && (tableau[des] == NIL))
783: return (TRUE);
784: else if (tableau[des] == NIL)
785: if (stock == NIL &&
786: cp != bottom[0] && cp != bottom[1] &&
787: cp != bottom[2] && cp != bottom[3])
788: return (TRUE);
789: else
790: return (FALSE);
791: else if (ranklower(cp, tableau[des]) && diffcolor(cp, tableau[des]))
792: return (TRUE);
793: else
794: return (FALSE);
795: }
796:
797: /*
798: * procedure to turn the cards onto the talon from the deck
799: */
800: movetotalon()
801: {
802: int i, fin;
803:
804: if (cinhand <= 3 && cinhand > 0) {
805: move(msgrow, msgcol);
806: printw("Hand is now empty ");
807: }
808: if (cinhand >= 3)
809: fin = 3;
810: else if (cinhand > 0)
811: fin = cinhand;
812: else if (talon != NIL) {
813: timesthru++;
814: errmsg = TRUE;
815: move(msgrow, msgcol);
816: if (timesthru != 4) {
817: printw("Talon is now the new hand");
818: this.runs += costofrunthroughhand;
819: game.runs += costofrunthroughhand;
820: total.runs += costofrunthroughhand;
821: while (talon != NIL) {
822: transit(&talon, &hand);
823: cinhand++;
824: }
825: if (cinhand >= 3)
826: fin = 3;
827: else
828: fin = cinhand;
829: taloncnt = 0;
830: coldrow = ctoprow;
831: coldcol = cinitcol;
832: cnewrow = ctoprow;
833: cnewcol = cinitcol + cwidthcol;
834: clearstat();
835: showstat();
836: } else {
837: fin = 0;
838: done = TRUE;
839: printw("I believe you have lost");
840: refresh();
841: sleep(5);
842: }
843: } else {
844: errmsg = TRUE;
845: move(msgrow, msgcol);
846: printw("Talon and hand are empty");
847: fin = 0;
848: }
849: for (i=0; i<fin; i++) {
850: transit(&hand, &talon);
851: INCRHAND(cnewrow, cnewcol);
852: INCRHAND(coldrow, coldcol);
853: removecard(cnewcol, cnewrow);
854: if (i == fin - 1)
855: talon->visible = TRUE;
856: if (Cflag) {
857: if (talon->paid == FALSE && talon->visible == TRUE) {
858: this.information += costofinformation;
859: game.information += costofinformation;
860: total.information += costofinformation;
861: talon->paid = TRUE;
862: }
863: printcard(coldcol, coldrow, talon);
864: }
865: }
866: if (fin != 0) {
867: printcard(taloncol, talonrow, talon);
868: cinhand -= fin;
869: taloncnt += fin;
870: if (Cflag) {
871: move(handstatrow, handstatcol);
872: printw("%3d", cinhand);
873: move(talonstatrow, talonstatcol);
874: printw("%3d", taloncnt);
875: }
876: fndbase(&talon, taloncol, talonrow);
877: }
878: }
879:
880:
881: /*
882: * procedure to print card counting info on screen
883: */
884: showstat()
885: {
886: int row, col;
887: register struct cardtype *ptr;
888:
889: if (!Cflag)
890: return;
891: move(talonstatrow, talonstatcol - 7);
892: printw("Talon: %3d", taloncnt);
893: move(handstatrow, handstatcol - 7);
894: printw("Hand: %3d", cinhand);
895: move(stockstatrow, stockstatcol - 7);
896: printw("Stock: %3d", stockcnt);
897: for ( row = coldrow, col = coldcol, ptr = talon;
898: ptr != NIL;
899: ptr = ptr->next ) {
900: if (ptr->paid == FALSE && ptr->visible == TRUE) {
901: ptr->paid = TRUE;
902: this.information += costofinformation;
903: game.information += costofinformation;
904: total.information += costofinformation;
905: }
906: printcard(col, row, ptr);
907: DECRHAND(row, col);
908: }
909: for ( row = cnewrow, col = cnewcol, ptr = hand;
910: ptr != NIL;
911: ptr = ptr->next ) {
912: if (ptr->paid == FALSE && ptr->visible == TRUE) {
913: ptr->paid = TRUE;
914: this.information += costofinformation;
915: game.information += costofinformation;
916: total.information += costofinformation;
917: }
918: INCRHAND(row, col);
919: printcard(col, row, ptr);
920: }
921: }
922:
923: /*
924: * procedure to clear card counting info from screen
925: */
926: clearstat()
927: {
928: int row;
929:
930: move(talonstatrow, talonstatcol - 7);
931: printw(" ");
932: move(handstatrow, handstatcol - 7);
933: printw(" ");
934: move(stockstatrow, stockstatcol - 7);
935: printw(" ");
936: for ( row = ctoprow ; row <= cbotrow ; row++ ) {
937: move(row, cinitcol);
938: printw("%56s", " ");
939: }
940: }
941:
942: /*
943: * procedure to update card counting base
944: */
945: usedtalon()
946: {
947: removecard(coldcol, coldrow);
948: DECRHAND(coldrow, coldcol);
949: if (talon != NIL && (talon->visible == FALSE)) {
950: talon->visible = TRUE;
951: if (Cflag) {
952: this.information += costofinformation;
953: game.information += costofinformation;
954: total.information += costofinformation;
955: talon->paid = TRUE;
956: printcard(coldcol, coldrow, talon);
957: }
958: }
959: taloncnt--;
960: if (Cflag) {
961: move(talonstatrow, talonstatcol);
962: printw("%3d", taloncnt);
963: }
964: }
965:
966: /*
967: * procedure to update stock card counting base
968: */
969: usedstock()
970: {
971: stockcnt--;
972: if (Cflag) {
973: move(stockstatrow, stockstatcol);
974: printw("%3d", stockcnt);
975: }
976: }
977:
978: /*
979: * let 'em know how they lost!
980: */
981: showcards()
982: {
983: register struct cardtype *ptr;
984: int row;
985:
986: if (!Cflag || cardsoff == 52)
987: return;
988: for (ptr = talon; ptr != NIL; ptr = ptr->next) {
989: ptr->visible = TRUE;
990: ptr->paid = TRUE;
991: }
992: for (ptr = hand; ptr != NIL; ptr = ptr->next) {
993: ptr->visible = TRUE;
994: ptr->paid = TRUE;
995: }
996: showstat();
997: move(stockrow + 1, sidecol);
998: printw(" ");
999: move(talonrow - 2, sidecol);
1000: printw(" ");
1001: move(talonrow - 1, sidecol);
1002: printw(" ");
1003: move(talonrow, sidecol);
1004: printw(" ");
1005: move(talonrow + 1, sidecol);
1006: printw(" ");
1007: for (ptr = stock, row = stockrow; ptr != NIL; ptr = ptr->next, row++) {
1008: move(row, stockcol - 1);
1009: printw("| |");
1010: printcard(stockcol, row, ptr);
1011: }
1012: if (stock == NIL) {
1013: move(row, stockcol - 1);
1014: printw("| |");
1015: row++;
1016: }
1017: move(handstatrow, handstatcol - 7);
1018: printw(" ");
1019: move(row, stockcol - 1);
1020: printw("=---=");
1021: if ( cardsoff == 52 )
1022: getcmd(moverow, movecol, "Hit return to exit");
1023: }
1024:
1025: /*
1026: * procedure to update the betting values
1027: */
1028: updatebettinginfo()
1029: {
1030: long thiscosts, gamecosts, totalcosts;
1031: double thisreturn, gamereturn, totalreturn;
1032: time_t now;
1033: register long dollars;
1034:
1035: time(&now);
1036: dollars = (now - acctstart) / secondsperdollar;
1037: if (dollars > 0) {
1038: acctstart += dollars * secondsperdollar;
1039: if (dollars > maxtimecharge)
1040: dollars = maxtimecharge;
1041: this.thinktime += dollars;
1042: game.thinktime += dollars;
1043: total.thinktime += dollars;
1044: }
1045: thiscosts = this.hand + this.inspection + this.game +
1046: this.runs + this.information + this.thinktime;
1047: gamecosts = game.hand + game.inspection + game.game +
1048: game.runs + game.information + game.thinktime;
1049: totalcosts = total.hand + total.inspection + total.game +
1050: total.runs + total.information + total.thinktime;
1051: this.worth = this.wins - thiscosts;
1052: game.worth = game.wins - gamecosts;
1053: total.worth = total.wins - totalcosts;
1054: thisreturn = ((double)this.wins / (double)thiscosts - 1.0) * 100.0;
1055: gamereturn = ((double)game.wins / (double)gamecosts - 1.0) * 100.0;
1056: totalreturn = ((double)total.wins / (double)totalcosts - 1.0) * 100.0;
1057: if (status != BETTINGBOX)
1058: return;
1059: move(tboxrow + 2, boxcol + 13);
1060: printw("%4d%8d%9d", this.hand, game.hand, total.hand);
1061: move(tboxrow + 3, boxcol + 13);
1062: printw("%4d%8d%9d", this.inspection, game.inspection, total.inspection);
1063: move(tboxrow + 4, boxcol + 13);
1064: printw("%4d%8d%9d", this.game, game.game, total.game);
1065: move(tboxrow + 5, boxcol + 13);
1066: printw("%4d%8d%9d", this.runs, game.runs, total.runs);
1067: move(tboxrow + 6, boxcol + 13);
1068: printw("%4d%8d%9d", this.information, game.information,
1069: total.information);
1070: move(tboxrow + 7, boxcol + 13);
1071: printw("%4d%8d%9d", this.thinktime, game.thinktime, total.thinktime);
1072: move(tboxrow + 8, boxcol + 13);
1073: printw("%4d%8d%9d", thiscosts, gamecosts, totalcosts);
1074: move(tboxrow + 9, boxcol + 13);
1075: printw("%4d%8d%9d", this.wins, game.wins, total.wins);
1076: move(tboxrow + 10, boxcol + 13);
1077: printw("%4d%8d%9d", this.worth, game.worth, total.worth);
1078: move(tboxrow + 11, boxcol + 13);
1079: printw("%4.0f%%%7.1f%%%8.1f%%", thisreturn, gamereturn, totalreturn);
1080: }
1081:
1082: /*
1083: * procedure to move a card from the stock or talon to the tableau
1084: */
1085: simpletableau(cp, des)
1086: struct cardtype **cp;
1087: {
1088: int origin;
1089:
1090: if (notempty(*cp)) {
1091: if (tabok(*cp, des)) {
1092: if (*cp == stock)
1093: origin = stk;
1094: else
1095: origin = tal;
1096: if (tableau[des] == NIL)
1097: bottom[des] = *cp;
1098: transit(cp, &tableau[des]);
1099: length[des]++;
1100: printcard(pilemap[des], length[des], tableau[des]);
1101: timesthru = 0;
1102: if (origin == stk) {
1103: usedstock();
1104: printcard(stockcol, stockrow, stock);
1105: } else {
1106: usedtalon();
1107: printcard(taloncol, talonrow, talon);
1108: }
1109: } else
1110: destinerror();
1111: }
1112: }
1113:
1114: /*
1115: * print the tableau
1116: */
1117: tabprint(sour, des)
1118: {
1119: int dlength, slength, i;
1120: struct cardtype *tempcard;
1121:
1122: for (i=tabrow; i<=length[sour]; i++)
1123: removecard(pilemap[sour], i);
1124: dlength = length[des] + 1;
1125: slength = length[sour];
1126: if (slength == tabrow)
1127: printcard(pilemap[des], dlength, tableau[sour]);
1128: else
1129: while (slength != tabrow - 1) {
1130: tempcard = tableau[sour];
1131: for (i=1; i<=slength-tabrow; i++)
1132: tempcard = tempcard->next;
1133: printcard(pilemap[des], dlength, tempcard);
1134: slength--;
1135: dlength++;
1136: }
1137: }
1138:
1139: /*
1140: * procedure to move from the tableau to the tableau
1141: */
1142: tabtotab(sour, des)
1143: register int sour, des;
1144: {
1145: struct cardtype *temp;
1146:
1147: if (notempty(tableau[sour])) {
1148: if (tabok(bottom[sour], des)) {
1149: tabprint(sour, des);
1150: temp = bottom[sour];
1151: bottom[sour] = NIL;
1152: if (bottom[des] == NIL)
1153: bottom[des] = temp;
1154: temp->next = tableau[des];
1155: tableau[des] = tableau[sour];
1156: tableau[sour] = NIL;
1157: length[des] = length[des] + (length[sour] - (tabrow - 1));
1158: length[sour] = tabrow - 1;
1159: timesthru = 0;
1160: } else
1161: destinerror();
1162: }
1163: }
1164:
1165: /*
1166: * functions to see if the card can go onto the foundation
1167: */
1168: bool
1169: rankhigher(cp, let)
1170: struct cardtype *cp;
1171: {
1172: if (found[let]->rank == King)
1173: if (cp->rank == Ace)
1174: return(TRUE);
1175: else
1176: return(FALSE);
1177: else if (cp->rank - 1 == found[let]->rank)
1178: return(TRUE);
1179: else
1180: return(FALSE);
1181: }
1182:
1183: /*
1184: * function to determine if two cards are the same suit
1185: */
1186: samesuit(cp, let)
1187: struct cardtype *cp;
1188: {
1189: if (cp->suit == found[let]->suit)
1190: return (TRUE);
1191: else
1192: return (FALSE);
1193: }
1194:
1195: /*
1196: * procedure to move a card to the correct foundation pile
1197: */
1198: movetofound(cp, source)
1199: struct cardtype **cp;
1200: {
1201: tempbase = 0;
1202: mtfdone = FALSE;
1203: if (notempty(*cp)) {
1204: do {
1205: if (found[tempbase] != NIL)
1206: if (rankhigher(*cp, tempbase)
1207: && samesuit(*cp, tempbase)) {
1208: if (*cp == stock)
1209: mtforigin = stk;
1210: else if (*cp == talon)
1211: mtforigin = tal;
1212: else
1213: mtforigin = tab;
1214: transit(cp, &found[tempbase]);
1215: printcard(pilemap[tempbase],
1216: foundrow, found[tempbase]);
1217: timesthru = 0;
1218: if (mtforigin == stk) {
1219: usedstock();
1220: printcard(stockcol, stockrow, stock);
1221: } else if (mtforigin == tal) {
1222: usedtalon();
1223: printcard(taloncol, talonrow, talon);
1224: } else {
1225: removecard(pilemap[source], length[source]);
1226: length[source]--;
1227: }
1228: cardsoff++;
1229: if (infullgame) {
1230: this.wins += valuepercardup;
1231: game.wins += valuepercardup;
1232: total.wins += valuepercardup;
1233: }
1234: mtfdone = TRUE;
1235: } else
1236: tempbase++;
1237: else
1238: tempbase++;
1239: } while ((tempbase != 4) && !mtfdone);
1240: if (!mtfdone)
1241: destinerror();
1242: }
1243: }
1244:
1245: /*
1246: * procedure to get a command
1247: */
1248: getcmd(row, col, cp)
1249: int row, col;
1250: char *cp;
1251: {
1252: char cmd[2], ch;
1253: int i;
1254:
1255: i = 0;
1256: move(row, col);
1257: printw("%-24s", cp);
1258: col += 1 + strlen(cp);
1259: move(row, col);
1260: refresh();
1261: do {
1262: ch = getch() & 0177;
1263: if (ch >= 'A' && ch <= 'Z')
1264: ch += ('a' - 'A');
1265: if (ch == '\f') {
1266: wrefresh(curscr);
1267: refresh();
1268: } else if (i >= 2 && ch != _tty.sg_erase && ch != _tty.sg_kill) {
1269: if (ch != '\n' && ch != '\r' && ch != ' ')
1270: write(1, "\007", 1);
1271: } else if (ch == _tty.sg_erase && i > 0) {
1272: printw("\b \b");
1273: refresh();
1274: i--;
1275: } else if (ch == _tty.sg_kill && i > 0) {
1276: while (i > 0) {
1277: printw("\b \b");
1278: i--;
1279: }
1280: refresh();
1281: } else if (ch == '\032') { /* Control-Z */
1282: suspend();
1283: move(row, col + i);
1284: refresh();
1285: } else if (isprint(ch)) {
1286: cmd[i++] = ch;
1287: addch(ch);
1288: refresh();
1289: }
1290: } while (ch != '\n' && ch != '\r' && ch != ' ');
1291: srcpile = cmd[0];
1292: destpile = cmd[1];
1293: }
1294:
1295: /*
1296: * Suspend the game (shell escape if no process control on system)
1297: */
1298: suspend()
1299: {
1300: #ifndef SIGTSTP
1301: char *sh;
1302: #endif
1303:
1304: updatebettinginfo();
1305: move(21, 0);
1306: refresh();
1307: if (dbfd != -1) {
1308: lseek(dbfd, uid * sizeof(struct betinfo), 0);
1309: write(dbfd, (char *)&total, sizeof(total));
1310: }
1311: kill(getpid(), SIGTSTP);
1312: raw();
1313: noecho();
1314: }
1315:
1316: /*
1317: * procedure to evaluate and make the specific moves
1318: */
1319: movecard()
1320: {
1321: int source, dest;
1322: char osrcpile, odestpile;
1323:
1324: done = FALSE;
1325: errmsg = FALSE;
1326: do {
1327: if (talon == NIL && hand != NIL)
1328: movetotalon();
1329: if (cardsoff == 52) {
1330: refresh();
1331: srcpile = 'q';
1332: } else if (!startedgame) {
1333: move(msgrow, msgcol);
1334: errmsg = TRUE;
1335: switch (34 - taloncnt - cinhand) {
1336: default:
1337: errmsg = FALSE;
1338: break;
1339: case 1:
1340: printw("One card used from talon ");
1341: break;
1342: case 2:
1343: printw("Two cards used from talon ");
1344: break;
1345: case 3:
1346: printw(">3< cards used from talon ");
1347: break;
1348: }
1349: getcmd(moverow, movecol, "Move:");
1350: } else
1351: getcmd(moverow, movecol, "Move:");
1352: clearmsg();
1353: if (srcpile >= '1' && srcpile <= '4')
1354: source = (int) (srcpile - '1');
1355: if (destpile >= '1' && destpile <= '4')
1356: dest = (int) (destpile - '1');
1357: if (!startedgame &&
1358: (srcpile == 't' || srcpile == 's' || srcpile == 'h' ||
1359: srcpile == '1' || srcpile == '2' || srcpile == '3' ||
1360: srcpile == '4')) {
1361: startedgame = TRUE;
1362: osrcpile = srcpile;
1363: odestpile = destpile;
1364: if (status != BETTINGBOX)
1365: srcpile = 'y';
1366: else do {
1367: getcmd(moverow, movecol, "Inspect game?");
1368: } while (srcpile != 'y' && srcpile != 'n');
1369: if (srcpile == 'n') {
1370: srcpile = 'q';
1371: } else {
1372: this.inspection += costofinspection;
1373: game.inspection += costofinspection;
1374: total.inspection += costofinspection;
1375: srcpile = osrcpile;
1376: destpile = odestpile;
1377: }
1378: }
1379: switch (srcpile) {
1380: case 't':
1381: if (destpile == 'f' || destpile == 'F')
1382: movetofound(&talon, source);
1383: else if (destpile >= '1' && destpile <= '4')
1384: simpletableau(&talon, dest);
1385: else
1386: dumberror();
1387: break;
1388: case 's':
1389: if (destpile == 'f' || destpile == 'F')
1390: movetofound(&stock, source);
1391: else if (destpile >= '1' && destpile <= '4')
1392: simpletableau(&stock, dest);
1393: else dumberror();
1394: break;
1395: case 'h':
1396: if (destpile != 't' && destpile != 'T') {
1397: dumberror();
1398: break;
1399: }
1400: if (infullgame) {
1401: movetotalon();
1402: break;
1403: }
1404: if (status == BETTINGBOX) {
1405: do {
1406: getcmd(moverow, movecol,
1407: "Buy game?");
1408: } while (srcpile != 'y' &&
1409: srcpile != 'n');
1410: if (srcpile == 'n') {
1411: showcards();
1412: done = TRUE;
1413: break;
1414: }
1415: }
1416: infullgame = TRUE;
1417: this.wins += valuepercardup * cardsoff;
1418: game.wins += valuepercardup * cardsoff;
1419: total.wins += valuepercardup * cardsoff;
1420: this.game += costofgame;
1421: game.game += costofgame;
1422: total.game += costofgame;
1423: movetotalon();
1424: break;
1425: case 'q':
1426: showcards();
1427: done = TRUE;
1428: break;
1429: case 'b':
1430: printtopbettingbox();
1431: printbottombettingbox();
1432: status = BETTINGBOX;
1433: break;
1434: case 'x':
1435: clearabovemovebox();
1436: clearbelowmovebox();
1437: status = NOBOX;
1438: break;
1439: case 'i':
1440: printtopinstructions();
1441: printbottominstructions();
1442: status = INSTRUCTIONBOX;
1443: break;
1444: case 'c':
1445: Cflag = !Cflag;
1446: if (Cflag)
1447: showstat();
1448: else
1449: clearstat();
1450: break;
1451: case '1': case '2': case '3': case '4':
1452: if (destpile == 'f' || destpile == 'F')
1453: movetofound(&tableau[source], source);
1454: else if (destpile >= '1' && destpile <= '4')
1455: tabtotab(source, dest);
1456: else dumberror();
1457: break;
1458: default:
1459: dumberror();
1460: }
1461: fndbase(&stock, stockcol, stockrow);
1462: fndbase(&talon, taloncol, talonrow);
1463: updatebettinginfo();
1464: } while (!done);
1465: }
1466:
1467: char *basicinstructions[] = {
1468: "Here are brief instuctions to the game of Canfield:\n\n",
1469: " If you have never played solitaire before, it is recom-\n",
1470: "mended that you consult a solitaire instruction book. In\n",
1471: "Canfield, tableau cards may be built on each other downward\n",
1472: "in alternate colors. An entire pile must be moved as a unit\n",
1473: "in building. Top cards of the piles are available to be able\n",
1474: "to be played on foundations, but never into empty spaces.\n\n",
1475: " Spaces must be filled from the stock. The top card of\n",
1476: "the stock also is available to be played on foundations or\n",
1477: "built on tableau piles. After the stock is exhausted, ta-\n",
1478: "bleau spaces may be filled from the talon and the player may\n",
1479: "keep them open until he wishes to use them.\n\n",
1480: " Cards are dealt from the hand to the talon by threes\n",
1481: "and this repeats until there are no more cards in the hand\n",
1482: "or the player quits. To have cards dealt onto the talon the\n",
1483: "player types 'ht' for his move. Foundation base cards are\n",
1484: "also automatically moved to the foundation when they become\n",
1485: "available.\n\n",
1486: "push any key when you are finished: ",
1487: 0 };
1488:
1489: char *bettinginstructions[] = {
1490: " The rules for betting are somewhat less strict than\n",
1491: "those used in the official version of the game. The initial\n",
1492: "deal costs $13. You may quit at this point or inspect the\n",
1493: "game. Inspection costs $13 and allows you to make as many\n",
1494: "moves as is possible without moving any cards from your hand\n",
1495: "to the talon. (the initial deal places three cards on the\n",
1496: "talon; if all these cards are used, three more are made\n",
1497: "available) Finally, if the game seems interesting, you must\n",
1498: "pay the final installment of $26. At this point you are\n",
1499: "credited at the rate of $5 for each card on the foundation;\n",
1500: "as the game progresses you are credited with $5 for each\n",
1501: "card that is moved to the foundation. Each run through the\n",
1502: "hand after the first costs $5. The card counting feature\n",
1503: "costs $1 for each unknown card that is identified. If the\n",
1504: "information is toggled on, you are only charged for cards\n",
1505: "that became visible since it was last turned on. Thus the\n",
1506: "maximum cost of information is $34. Playing time is charged\n",
1507: "at a rate of $1 per minute.\n\n",
1508: "push any key when you are finished: ",
1509: 0 };
1510:
1511: /*
1512: * procedure to printout instructions
1513: */
1514: instruct()
1515: {
1516: register char **cp;
1517:
1518: move(originrow, origincol);
1519: printw("This is the game of solitaire called Canfield. Do\n");
1520: printw("you want instructions for the game?");
1521: do {
1522: getcmd(originrow + 3, origincol, "y or n?");
1523: } while (srcpile != 'y' && srcpile != 'n');
1524: if (srcpile == 'n')
1525: return;
1526: clear();
1527: for (cp = basicinstructions; *cp != 0; cp++)
1528: printw(*cp);
1529: refresh();
1530: getch();
1531: clear();
1532: move(originrow, origincol);
1533: printw("Do you want instructions for betting?");
1534: do {
1535: getcmd(originrow + 2, origincol, "y or n?");
1536: } while (srcpile != 'y' && srcpile != 'n');
1537: if (srcpile == 'n')
1538: return;
1539: clear();
1540: for (cp = bettinginstructions; *cp != 0; cp++)
1541: printw(*cp);
1542: refresh();
1543: getch();
1544: }
1545:
1546: /*
1547: * procedure to initialize the game
1548: */
1549: initall()
1550: {
1551: int i;
1552:
1553: srandom(getpid());
1554: time(&acctstart);
1555: initdeck(deck);
1556: uid = getuid();
1557: if (uid < 0)
1558: uid = 0;
1559: dbfd = open(_PATH_SCORE, 2);
1560: if (dbfd < 0)
1561: return;
1562: i = lseek(dbfd, uid * sizeof(struct betinfo), 0);
1563: if (i < 0) {
1564: close(dbfd);
1565: dbfd = -1;
1566: return;
1567: }
1568: i = read(dbfd, (char *)&total, sizeof(total));
1569: if (i < 0) {
1570: close(dbfd);
1571: dbfd = -1;
1572: return;
1573: }
1574: }
1575:
1576: /*
1577: * procedure to end the game
1578: */
1579: bool
1580: finish()
1581: {
1582: int row, col;
1583:
1584: if (cardsoff == 52) {
1585: getcmd(moverow, movecol, "Hit return to exit");
1586: clear();
1587: refresh();
1588: move(originrow, origincol);
1589: printw("CONGRATULATIONS!\n");
1590: printw("You won the game. That is a feat to be proud of.\n");
1591: row = originrow + 5;
1592: col = origincol;
1593: } else {
1594: move(msgrow, msgcol);
1595: printw("You got %d card", cardsoff);
1596: if (cardsoff > 1)
1597: printw("s");
1598: printw(" off ");
1599: move(msgrow, msgcol);
1600: row = moverow;
1601: col = movecol;
1602: }
1603: do {
1604: getcmd(row, col, "Play again (y or n)?");
1605: } while (srcpile != 'y' && srcpile != 'n');
1606: errmsg = TRUE;
1607: clearmsg();
1608: if (srcpile == 'y')
1609: return (FALSE);
1610: else
1611: return (TRUE);
1612: }
1613:
1614: /*
1615: * Field an interrupt.
1616: */
1617: askquit()
1618: {
1619: move(msgrow, msgcol);
1620: printw("Really wish to quit? ");
1621: do {
1622: getcmd(moverow, movecol, "y or n?");
1623: } while (srcpile != 'y' && srcpile != 'n');
1624: clearmsg();
1625: if (srcpile == 'y')
1626: cleanup();
1627: signal(SIGINT, askquit);
1628: }
1629:
1630: /*
1631: * procedure to clean up and exit
1632: */
1633: cleanup()
1634: {
1635:
1636: total.thinktime += 1;
1637: status = NOBOX;
1638: updatebettinginfo();
1639: if (dbfd != -1) {
1640: lseek(dbfd, uid * sizeof(struct betinfo), 0);
1641: write(dbfd, (char *)&total, sizeof(total));
1642: close(dbfd);
1643: }
1644: clear();
1645: move(22,0);
1646: refresh();
1647: endwin();
1648: exit(0);
1649: /* NOTREACHED */
1650: }
1651:
1652: /*
1653: * Can you tell that this used to be a Pascal program?
1654: */
1655: main(argc, argv)
1656: int argc;
1657: char *argv[];
1658: {
1659: #ifdef MAXLOAD
1660: double vec[3];
1661:
1662: loadav(vec);
1663: if (vec[2] >= MAXLOAD) {
1664: puts("The system load is too high. Try again later.");
1665: exit(0);
1666: }
1667: #endif
1668: signal(SIGINT, askquit);
1669: signal(SIGHUP, cleanup);
1670: signal(SIGTERM, cleanup);
1671: initscr();
1672: raw();
1673: noecho();
1674: initall();
1675: instruct();
1676: makeboard();
1677: for (;;) {
1678: startgame();
1679: movecard();
1680: if (finish())
1681: break;
1682: if (cardsoff == 52)
1683: makeboard();
1684: else
1685: cleanupboard();
1686: }
1687: cleanup();
1688: /* NOTREACHED */
1689: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.