home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 305_01 / poker.c < prev    next >
Text File  |  1990-02-14  |  45KB  |  1,771 lines

  1. /*
  2. TITLE:        POKER.C;
  3. DATE:        5/15/88;
  4. DESCRIPTION:    "Five-card draw poker.";
  5. VERSION:    1.01;
  6. KEYWORDS:    poker, cards;
  7. FILENAME:    POKER.C;
  8. WARNINGS:    "Requires IBM or compatible.";
  9. SEE-ALSO:    CARDS.DOC, BLACKJACK.C;
  10. SYSTEM:        MS-DOS;
  11. COMPILERS:    Aztec;
  12. AUTHORS:    Dan Schechter;
  13.  */
  14.  
  15. /*
  16. This program is copyright 1988, 1989 by Dan Schechter.
  17. You may copy and distribute it only on a not-for-profit basis.
  18. I provide this source code mainly for informational purposes but 
  19. you may modify it providing that you give attribution to the original author
  20. and document your modifications and distribute the modified version
  21. only on a not-for-profit basis. Since it writes directly to screen
  22. memory you must compile using large model. (I know how to get around
  23. that now, but I am no longer updating this program.)
  24.  */
  25.  
  26. /* BUGS: -->
  27.         Problem in betq():
  28.         if only two players remain in at start of final bets,
  29.         and if the first folds (an unnatural, but legal thing to do),
  30.         the second will bet before the program declares that only
  31.         one player remains in.
  32.         This does not materially affect the game.
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <color.h>
  37. #include <time.h>
  38.  
  39. char *version = "\
  40. POKER version 1.01 5/15/88 from KITTENSOFT.\n\
  41. Copyright (c) 1987, 1988 by Dan Schechter\n\n";
  42.  
  43. int main(void);
  44. int betq(int q);
  45. int al_st_fl(int *dis,int lhand[][2],int special[][2],int *suit);
  46. void kaydscrd(int who);
  47. void pladscrd(void);
  48. void evaluate(int who);
  49. void setvnull(char lhand[][2],int values[]);
  50. void setvpair(char lhand[][2],int values[]);
  51. void setvtwo(char lhand[][2],int values[]);
  52. void setvthre(char lhand[][2],int values[]);
  53. void setvstra(char lhand[][2],int values[]);
  54. void setvfull(char lhand[][2],int values[]);
  55. void setvfour(char lhand[][2],int values[]);
  56. int makebet(int highbet,int mytotal,int v[],int q,int who);
  57. int getbet(int q,int *line,int pot,int bet);
  58. int al_flushq(int who);
  59. int al_stq(int who);
  60. void prompt(char *s1,char *s2,char *s3);
  61. void setcolor(int c);
  62. void shuffle(void);
  63. void deldeck(int n);
  64. int rando(void);
  65. int comp(char *a,char *b);
  66. int compf(char *a,char *b);
  67. int valcmp(char *aa,char *bb);
  68. int myatoi(char *s);
  69. char *itoa(int n,char *s);
  70. int getreply(char *s);
  71. void selectcolor(void);
  72. int get2reply(char *s,int);
  73. int tpr(int c);
  74. int final_display(void);
  75. int rotate(void);
  76. void snaphand(int index);
  77. void writecard(int v,int h,int card);
  78. void colorchar(int v,int h,int suit,int c);
  79. void scr_color(int v,int h,int c,int q);
  80. void help(int q);
  81. void sethelp(void);
  82. void instructions(void);
  83. void intro(char *str);
  84. int mygetch(void);
  85. int inkey(void);
  86. void sendcurs(int v,int h);
  87. void showtime(void);
  88.  
  89. #define COL2 45
  90. #define COL1 5
  91. #define CARDLINE(x) (1+6*x)
  92. #define BETLINE 1
  93.  
  94. #define CLEARSCREEN scr_clear()
  95. #define ERAEOL scr_eol()
  96. #define sendcurs scr_curs
  97.  
  98. char *txt[53]={
  99.     "2S",    /* 0 */
  100.     "2H",    /* 1 */
  101.     "2C",    /* 2 */
  102.     "2D",    /* 3 */
  103.     "3S",    /* 4 */
  104.     "3H",    /* 5 */
  105.     "3C",    /* 6 */
  106.     "3D",    /* 7 */
  107.     "4S",    /* 8 */
  108.     "4H",    /* 9 */
  109.     "4C",    /* 10 */
  110.     "4D",    /* 11 */
  111.     "5S",    /* 12 */
  112.     "5H",    /* 13 */
  113.     "5C",    /* 14 */
  114.     "5D",    /* 15 */
  115.     "6S",    /* 16 */
  116.     "6H",    /* 17 */
  117.     "6C",    /* 18 */
  118.     "6D",    /* 19 */
  119.     "7S",    /* 20 */
  120.     "7H",    /* 21 */
  121.     "7C",    /* 22 */
  122.     "7D",    /* 23 */
  123.     "8S",    /* 24 */
  124.     "8H",    /* 25 */
  125.     "8C",    /* 26 */
  126.     "8D",    /* 27 */
  127.     "9S",    /* 28 */
  128.     "9H",    /* 29 */
  129.     "9C",    /* 30 */
  130.     "9D",    /* 31 */
  131.     "TS",    /* 32 */
  132.     "TH",    /* 33 */
  133.     "TC",    /* 34 */
  134.     "TD",    /* 35 */
  135.     "JS",    /* 36 */
  136.     "JH",    /* 37 */
  137.     "JC",    /* 38 */
  138.     "JD",    /* 39 */
  139.     "QS",    /* 40 */
  140.     "QH",    /* 41 */
  141.     "QC",    /* 42 */
  142.     "QD",    /* 43 */
  143.     "KS",    /* 44 */
  144.     "KH",    /* 45 */
  145.     "KC",    /* 46 */
  146.     "KD",    /* 47 */
  147.     "AS",    /* 48 */
  148.     "AH",    /* 49 */
  149.     "AC",    /* 50 */
  150.     "AD",    /* 51 */
  151.     "  "
  152. };
  153. char *money;
  154. char *computer = "Tchekalinsky" ;
  155. char *_names_[13] = {
  156.     " ",
  157.     "Goneril",
  158.     "Kent",
  159.     "Dmitry",
  160.     "Hermann",
  161.     "Cisco",
  162.     "Grushenka",
  163.     "Nastasya",
  164.     "Lady MacBeth",
  165.     "Billy Budd",
  166.     "Clytemnestra",
  167.     "Gaspar",
  168.     "Freya"
  169. };
  170. char *intro_strings[13] = {
  171.     " ",
  172.     "Princess Goneril.",
  173.     "The Earl of Kent.",
  174.     "Dmitry Fyodorovich Karamazov.",
  175.     "My old chum, Hermann the German.",
  176.     "Cisco, the singing hobo.",
  177.     "The beautiful Grushenka.",
  178.     "The madwoman, Nastasya Filipovna Barashkov.",
  179.     "Lady MacBeth.",
  180.     "Billy Budd, sailor.",
  181.     "Clytemnestra, queen of Argos.",
  182.     "Gaspar Ruiz.",
  183.     "Freya, of the Seven Isles."
  184. };
  185. char *currency[8] = {
  186.     "lira",
  187.     "pesos",
  188.     "rubles",
  189.     "drachmas",
  190.     "rupees",
  191.     "yen",
  192.     "c\242rdobas",
  193.     "toothpicks"
  194. };
  195. char *shmaddr;
  196. int color;
  197. int revid_atr=116;
  198. int norm_atr=112;
  199. int helpcolor;            /* color for help screens */ 
  200.  
  201. struct _hand_ {
  202.     int cards[5];
  203.     int values[7];
  204.     int discards[6];
  205.     int balance;        /* plus or minus for amount of winnings or losings */
  206.     int bluff;        /* bluff factor for computer hands */
  207.     int in;            /* true if hand has not folded */
  208.     char *name;
  209.     char *description;
  210.     int color;        /* color for screen messages */
  211. };
  212. int pot=0;
  213. int deck[52];
  214. int player;            /* hand[player] is player's hand */
  215. extern int _attrib;
  216. struct _hand_ hand[5];
  217. unsigned char sidescreen[4000];
  218.  
  219. char cat[45] = {
  220.     0x20, 0x20, 0x20, 0x20, 0x2f, 0x5c, 0x5f, 0x2f, 0x5c, '\n',
  221.     0x20, 0x20, 0x20, 0x28, 0xfe, 0x20, 0xd2, 0x20, 0xfe, 0x29, '\n',
  222.     0xf0, 0xf0, 0xf0, 0xf0, 0x20, 0xc4, 0xca, 0xc4, 0x20, 0xf0, 
  223.           0xf0, 0xf0, 0xf0, '\n',
  224.     0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x22, 0x22, '\n', 0x00
  225. };
  226.  
  227. int main()
  228. {
  229.     int r,i,j,dis[8],line,dcount;
  230.     char s[25],paws=0;
  231.     
  232.     for (dis[0]=r=0,i=1;i<5;i++,r=0){
  233.         dis[i]=rando()%12+1;
  234.         for (j=i-1;j>0;j--) if (dis[j]==dis[i]) r=1;
  235.         if (r) i--;
  236.     }
  237.     for (i=0;i<5;i++) {
  238.         hand[i].name=_names_[dis[i]];
  239.         hand[i].description=intro_strings[dis[i]];
  240.         hand[i].balance=0;
  241.     }
  242.     helpcolor =    2;
  243.     hand[0].color= 15;     /* display colors for color monitors. */
  244.     hand[1].color= 10;
  245.     hand[2].color= 11;
  246.     hand[3].color= 12;
  247.     hand[4].color= 14;
  248.     intro(s);
  249.     if (color=='c') setcolor(helpcolor);
  250.     else {
  251.         norm_atr=helpcolor=7;
  252.         revid_atr=112;
  253.     }
  254.     myprintf("\
  255. Good %s friend. My name is %s. Welcome to Petersburg.\n\
  256. Allow me to introduce your table-mates:\n\n",s,computer);
  257.     _attrib |= 8;
  258.     for (i=1;i<5;i++)
  259.         myprintf("\t\t  %s\n",hand[i].description);
  260.     _attrib ^= 8;
  261.     player=0;
  262.     myprintf("\n\
  263. The game is five-card draw poker.\n\
  264. There is no minimum to open, and there are no wild cards.\n\n\
  265. Would you like to play for:\n\n\
  266. \t1..... Italian lira.    \t5..... Indian rupees.\n\
  267. \t2..... Argentine pesos. \t6..... Japanese yen.\n\
  268. \t3..... Russian rubles.  \t7..... Nicaraguan c\242rdobas.\n\
  269. \t4..... Greek drachmas.  \t8..... Toothpicks.\n\n\
  270. \t\t? ");
  271.  
  272.     r=get2reply("12345678",1);
  273.     money=currency[r-49];
  274.     myputchar('\n');
  275.     goto shuf;
  276. st:    CLEARSCREEN;
  277. shuf:    shuffle();
  278.     dcount=0;
  279.     CLEARSCREEN;
  280.     for (i=0;i<5;i++)
  281.         for (j=0;j<5;j++)        /* deal cards */
  282.             hand[j].cards[i]=deck[dcount++];
  283. fdis:    for (i=0;i<5;i++) {
  284.         qsort(hand[i].cards,5,sizeof(int),comp);     /* sort hands */
  285.         evaluate(i);
  286.     }
  287.     for (i=0;i<5;i++) {
  288.         hand[i].in=1;            /* new hand: everyone is in. */
  289.         hand[i].balance-=10;        /* ante */
  290.         hand[i].bluff=rando()%100;    /* bluff factor
  291.                            meaningless for player's hand */
  292.         for (j=0;j<6;j++) hand[i].discards[j]=0;
  293.     }
  294.     pot+=50;
  295.     
  296.     line=CARDLINE(2);
  297.     sendcurs(line,COL1+10);   
  298.     r=betq(1);    /* opening bets. 
  299.                 On return, all opening bets have been
  300.                 made. pot and balances have been adjusted.
  301.                 some players may have folded */
  302.     setcolor(hand[player].color);
  303.     myprintf("\nPress space bar... ");
  304.     prompt("End of first round betting.","Press space bar.","");
  305.     paws=1;
  306.     get2reply(" ",2); 
  307.     myputchar('\n');
  308.     if (r==0) goto st;    /* no openers */
  309.     if (r==1) goto drop;    /* all but one folded */
  310.     
  311.     for (i=0;i<5;i++) {
  312.         if ((i==player)&&(hand[player].in)) {
  313.             if (paws==0){
  314.                 setcolor(hand[player].color);
  315.                 myprintf("\nPress space bar... ");
  316.                 prompt("Press space bar to continue.","","");
  317.                 get2reply(" ",3);
  318.                 myputchar('\n');
  319.                 paws=1;
  320.             }
  321.             for (j=0;j<4000;j++) sidescreen[j]=shmaddr[j];
  322.             scr_loc(&r,&j);
  323.             pladscrd();
  324.             scr_curs(r,j);
  325.             for (j=0;j<4000;j++) shmaddr[j]=sidescreen[j];
  326.             
  327.         }
  328.         else if (hand[i].in) {
  329.             kaydscrd(i);    /* computer discards */  
  330.             setcolor(hand[i].color);
  331.             myprintf("\n\t-*> %s ",hand[i].name);
  332.             switch (j=hand[i].discards[0]) {
  333.                 case 0: myprintf("stands pat."); break;
  334.                 case 1: myprintf("discards 1 card."); break;
  335.                 default: myprintf("discards %d cards.",j);
  336.             }
  337.             ERAEOL;
  338.             paws=0;
  339.         }
  340.     }
  341.     if (paws==0){
  342.         setcolor(hand[player].color);
  343.         myprintf("\nPress space bar... ");
  344.         prompt("Press space bar to continue.","","");
  345.         ERAEOL;
  346.         if (hand[player].in) 
  347.             for (i=0;i<hand[player].discards[0];i++)
  348.             writecard(2,COL1+(4-hand[player].discards[i+1])*6,52);
  349.         get2reply(" ",4);
  350.         myputchar('\n');
  351.     }
  352.     for (i=0;i<5;i++){        /* fill out hands after discarding */
  353.         if (hand[i].in==0) continue;
  354.         for (j=1;j <= hand[i].discards[0];j++)
  355.             hand[i].cards[ hand[i].discards[j] ] = deck[dcount++];
  356.     }
  357.     for (i=0;i<5;i++){
  358.         qsort(hand[i].cards,5,sizeof(int),comp);
  359.         for(j=0;j<7;j++) hand[i].values[j]=0;
  360.         if (hand[i].in) evaluate(i);
  361.     }
  362.     r=betq(2);        /* Final bets. */
  363.     setcolor(hand[player].color);
  364.     myprintf("\nPress space bar... ");
  365.     prompt("Press space bar to continue.","","");
  366.     get2reply(" ",5);
  367.  
  368. drop:    r=final_display();
  369.     if (r=='n') exit(0);
  370.     goto st;
  371. }
  372. /* ------------------------------------ BETQ */
  373. int betq(q)
  374. int q;
  375. {
  376.     int qq,r,i,j,line=7,whosebet,bet[6];
  377.     int call;    /* Consecutive calls. When call==4 betting is done. */
  378.     static numberin,opener;
  379.     
  380.     CLEARSCREEN;
  381.     for (i=0;i<6;i++) bet[i]=0;    /* bet[5] is largest amount bet 
  382.                     bet[n] is how much the n-th player
  383.                     has put in so far. */
  384.     sendcurs(line++,0);
  385.     setcolor(hand[player].color);
  386.     if (q==1) {
  387.         myprintf("Opening bets: Ante is 10 %s.\n",money);
  388.         opener=0;
  389.         numberin=5;
  390.     }
  391.     else myprintf("Final bets:\n");
  392.     
  393.     whosebet=opener;
  394.     for(call=(-1);;whosebet++){
  395.         whosebet %= 5;
  396.         if (q==1) {
  397.         if (bet[5]==0) qq='o';
  398.         else qq='t';
  399.         }
  400.         if (q==2) {
  401.         if (bet[5]==0) qq='y';
  402.         else qq= 'e';
  403.         }
  404.         if (hand[whosebet].in == 0) continue;
  405.         
  406.         if (whosebet!=player) {
  407.         r=makebet(bet[5],bet[whosebet],hand[whosebet].values,qq,whosebet);
  408.         setcolor(hand[whosebet].color);
  409.         myprintf("\n\t--> %s ",hand[whosebet].name);
  410.         switch(r){
  411.             case ('p'|1024): myprintf("passes."); break;
  412.             case ('f'|1024): myprintf("folds."); break;
  413.             case ('c'|1024): myprintf("calls."); break;
  414.             default: 
  415.                 if (bet[5]==0) {
  416.                     if (q==1) myprintf("opens with %d %s.",r,money);
  417.                     else myprintf("bets %d %s.",r,money);
  418.                 }
  419.                 else myprintf("raises %d %s.",r,money);
  420.         }
  421.         line++;
  422.         }
  423.         else r=getbet(qq,&line,pot,bet[5]-bet[player]);
  424.         
  425.         switch (r) {
  426.         case ('p'|1024): 
  427.             call++; 
  428.             break;
  429.         case ('f'|1024): 
  430.             numberin--;
  431.             hand[whosebet].in=0;
  432.             break;
  433.         case ('c'|1024): 
  434.             call++;
  435.             j= bet[5]-bet[whosebet];
  436.             hand[whosebet].balance -= j;
  437.             pot += j;
  438.             bet[whosebet]=bet[5];
  439.             break;
  440.         default:
  441.             call=0;
  442.             if (bet[5]==0) opener=whosebet;
  443.             j= bet[5]-bet[whosebet]+r;
  444.             hand[whosebet].balance -= j;
  445.             pot+=j;
  446.             bet[whosebet] += j;
  447.             bet[5]=bet[whosebet];
  448.             break;
  449.         }
  450.         if ((bet[5]==0)&&((call+1)==numberin)) return(0);
  451.         if ((bet[5])&&(numberin==1)) return(1);
  452.         if ((call+1)==numberin) return(numberin);
  453.     }
  454. }
  455. /* ------------------------------------------- AL_ST_FLUSH */
  456. int al_st_fl(dis,lhand,special,suit)
  457. int *dis,lhand[][2],special[][2],*suit;
  458. {
  459.     int *wp,*wpp,cnt,i,j;
  460.  
  461.     /* WARNING --> THIS ROUTINE WILL <SPLIT THE PAIR> */
  462.     qsort(special[0],5,2*sizeof(int),compf); 
  463.  
  464.     *suit=0;
  465.     i=special[0][1];
  466.     j=special[4][1];
  467.     if ((i==special[1][1])&&(i==special[2][1])&&(i==special[3][1]))
  468.         *suit=i;
  469.     if ((j==special[1][1])&&(j==special[2][1])&&(j==special[3][1]))
  470.         *suit=j;
  471.  
  472.     if (*suit==0) return(0);
  473.     
  474. /* if it gets this far, there is an almost-flush in suit */
  475.     if (i!=*suit) wp=wpp=special[1];
  476.     else wp=wpp=special[0];
  477. /* wp and wpp now point to a 4-card flush partial hand */
  478. /* ----> NOW LOOK FOR AN ALMOST-STRAIGHT. NEED NOT BE CONTIGUOUS. */
  479.     qsort(wp,4,2*sizeof(int),comp);
  480.     for (wpp+=2,cnt=j=0;j<3;j++,wp+=2,wpp+=2){
  481.         i=(*wp-*wpp);
  482.         if (((i==0)||(i>2)) || 
  483.             ((i==2)&&(cnt))) { cnt=2; break; } 
  484.         if (i==2) cnt=1;
  485.     }
  486.     if (cnt==2){
  487.         if (special[0][1]!=*suit) wp=wpp=special[1];
  488.         else wp=wpp=special[0];
  489.         if (*(wp+8)==14) {
  490.             *(wp+8)=1;
  491.             qsort(wp,4,2*sizeof(int),comp);
  492.             for (wpp+=2,cnt=j=0;j<3;j++,wp+=2,wpp+=2){
  493.                 i=(*wp-*wpp);
  494.                 if (((i==0)||(i>2)) || 
  495.                     ((i==2)&&(cnt))) return(0); 
  496.                 if (i==2) cnt=1;
  497.             }
  498.         }
  499.     }
  500. /* if it gets this far there is a 4-flush/almost-straight */
  501.     for (i=0;i<5;i++){
  502.         if (lhand[i][1]!=*suit){
  503.             dis[0]=1;
  504.             dis[1]=i;
  505.             return(1);
  506.         }
  507.     }
  508.     myprintf(" ERROR in al_st_fl() ");
  509.     return(-1);
  510. }
  511.  
  512. /* -------------------------------------- KAYDSCRD */
  513. void kaydscrd(who)
  514. int who;
  515. {
  516.     int i,j,cts;
  517.     int lhand[5][2],special[5][2],suit;
  518.     
  519.     for (i=0;i<5;i++) {
  520.         lhand[i][0]=special[i][0]=txt[hand[who].cards[i]][0];
  521.         lhand[i][1]=special[i][1]=txt[hand[who].cards[i]][1];
  522.     }
  523.      
  524.     /* BLUFF */
  525.     if (hand[who].bluff==0){
  526.         hand[who].discards[0]=0;
  527.         return;
  528.     }
  529.     
  530.     /* NO DRAW ON STRAIGHTS, FLUSHES, FULL HOUSES, OR ST-FLUSHES */
  531.     if ((hand[who].values[0]==8)||(hand[who].values[0]==16)||(hand[who].values[0]==32)||(hand[who].values[0]==128)){
  532.         hand[who].discards[0]=0;
  533.         return;
  534.     }
  535.     /* FOUR OF A KIND */
  536.     /* Always draw 1. Meaningless, but conceals value from opponents. */
  537.     if (hand[who].values[0]==64) {
  538.         hand[who].discards[0]=1;
  539.         if (lhand[0][0]==lhand[1][0])
  540.             hand[who].discards[1]=4;
  541.         else 
  542.             hand[who].discards[1]=0;
  543.         return;
  544.     }
  545.     /* THREE OF A KIND */
  546.     if (hand[who].values[0]==4){
  547.         hand[who].discards[0]=2;               /* DRAW TWO CARDS */
  548.         if ((lhand[1][0]==lhand[2][0])&&(lhand[1][0]==lhand[3][0])){
  549.             hand[who].discards[1]=0;
  550.             hand[who].discards[2]=4;
  551.             return;
  552.         }
  553.         if (lhand[1][0]==lhand[0][0]){
  554.             hand[who].discards[1]=3;
  555.             hand[who].discards[2]=4;
  556.         }
  557.         else {
  558.             hand[who].discards[1]=0;
  559.             hand[who].discards[2]=1;
  560.         }
  561.         return;
  562.     }
  563.     /* TWO PAIR */
  564.     if (hand[who].values[0]==2){
  565.         hand[who].discards[0]=1;      /* DRAW ONE FOR THE ODD CARD */
  566.         if (lhand[0][0]!=lhand[1][0]){
  567.             hand[who].discards[1]=0;
  568.             return;
  569.         }
  570.         if (lhand[2][0]!=lhand[3][0]) hand[who].discards[1]=2;
  571.         else hand[who].discards[1]=4;
  572.         return;
  573.     }
  574.     /* CHECK FOR ALMOST STRAIGHT FLUSH */
  575.     /* WARNING --> THIS ROUTINE WILL <SPLIT THE PAIR> */
  576.     if (al_st_fl(hand[who].discards,lhand,special,&suit)) return;
  577.  
  578.     /* PAIR */
  579.     if (hand[who].values[0]==1){
  580.         hand[who].discards[0]=3;         /* DRAW THREE ON A PAIR */
  581.         for (i=0;lhand[i][0]!=lhand[i+1][0];i++);
  582.         if (i==0){
  583.             hand[who].discards[1]=2;
  584.             hand[who].discards[2]=3;
  585.             hand[who].discards[3]=4;
  586.             return;
  587.         }
  588.         if (i==1){
  589.             hand[who].discards[1]=0;
  590.             hand[who].discards[2]=3;
  591.             hand[who].discards[3]=4;
  592.             return;
  593.         }
  594.         if (i==2){
  595.             hand[who].discards[1]=0;
  596.             hand[who].discards[2]=1;
  597.             hand[who].discards[3]=4;
  598.             return;
  599.         }
  600.         hand[who].discards[1]=0;
  601.         hand[who].discards[2]=1;
  602.         hand[who].discards[3]=2;
  603.         return;
  604.     }
  605.     /* NULL HAND - THE ONLY REMAINING POSSIBILITY */
  606.     /* CHECK FOR ALMOST-FLUSH */
  607.     if (suit){
  608.         hand[who].discards[0]=1;
  609.         for (i=0;i<5;i++)
  610.             if (lhand[i][1]!=suit) hand[who].discards[1]=i;
  611.         return;
  612.     }
  613.     /* CHECK FOR ALMOST STRAIGHT */
  614.     hand[who].discards[1]='x';
  615.     if ((lhand[0][0]+1==lhand[1][0])&&(lhand[1][0]+1==lhand[2][0])&&
  616. (lhand[2][0]+1==lhand[3][0])) hand[who].discards[1]=4;
  617.     if ((lhand[1][0]+1==lhand[2][0])&&(lhand[2][0]+1==lhand[3][0])&&
  618. (lhand[3][0]+1==lhand[4][0])) hand[who].discards[1]=0;
  619.     if ((lhand[0][0]==2)&&(lhand[1][0]==3)&&(lhand[2][0]==4)&&
  620. (lhand[4][0]==14)) hand[who].discards[1]=3;
  621.     if (hand[who].discards[1]!='x'){
  622.         hand[who].discards[0]=1;
  623.         return;
  624.     }
  625.     /* BLUFF */
  626.     hand[who].discards[1]=0;
  627.     hand[who].discards[2]=1;
  628.     hand[who].discards[3]=2;
  629.     hand[who].discards[4]=3;
  630.  
  631.     switch (hand[who].bluff){
  632.         case 0: hand[who].discards[0]=0; return;
  633.         case 1: hand[who].discards[0]=1; return;
  634.         case 2: hand[who].discards[0]=2; return;
  635.         case 3: hand[who].discards[0]=3; return;
  636.         default: hand[who].discards[0]=4; return;
  637.     }
  638. }
  639.  
  640. /* ----------------------------- PLADSCRD */
  641.  
  642. void pladscrd()
  643. {
  644.     int line,r,i,j;
  645.     
  646.     if (hand[player].in==0) return;
  647.     
  648.     CLEARSCREEN;
  649.     setcolor(hand[player].color);
  650.     prompt("Discard.","Press ENTER when done.","");
  651.     line=7;
  652.     sendcurs(line,7);
  653.     myprintf("1     2     3     4     5\n\n\n\
  654. Discard. List cards by number. Press DEL to start over. "); 
  655.     line++;
  656.     do {
  657.         for (i=0;i<6;i++) hand[player].discards[i]=0;
  658.         for (i=0;;){
  659.             r=get2reply("12345\r\177",6);
  660.             if ((r==13)||(r==127)) break;
  661.             r-=49;
  662.             for (j=1;j<=i;j++) if(hand[player].discards[j]==r) continue;
  663.             hand[player].discards[++i]=r;
  664.             scr_color(line,COL1+2+6*(r),24,0);
  665.         }
  666.         sendcurs(line,0);
  667.         ERAEOL;
  668.         sendcurs(line+2,56);
  669.         ERAEOL;
  670.     } while (r==127);
  671.     hand[player].discards[0]=i;
  672.                 /* now player's discards are marked, 
  673.                    but not yet filled */
  674.     for (i=1;i<6;i++) hand[player].discards[i]= 4-hand[player].discards[i];
  675.     sendcurs(7,1);
  676.     ERAEOL;
  677.     myprintf("\n");
  678.     ERAEOL;
  679.     myprintf("\n\n");
  680.     ERAEOL;
  681. }
  682.  
  683. /* ----------------------------- EVALUATE */
  684.  
  685. void evaluate(who)
  686. int who;
  687. {
  688.     char lhand[5][2];
  689.     int i,j,a,b,c,d,e,aq,bq,cq,dq,eq;
  690.     int pair,twopair,three,straight,flush,full,four,stflush;
  691.     
  692.     pair= twopair= three= straight= flush=0;
  693.     full= four= stflush=0;
  694.     for (i=0;i<7;i++) hand[who].values[i]=0; 
  695.     
  696.     for (i=0;i<5;i++) {
  697.         lhand[i][0]=txt[hand[who].cards[i]][0];
  698.         lhand[i][1]=txt[hand[who].cards[i]][1];
  699.     }
  700.     for (i=0;i<5;i++){
  701.         switch (lhand[i][0]) {
  702.             case 'T': lhand[i][0]=10; break;
  703.             case 'J': lhand[i][0]=11; break;
  704.             case 'Q': lhand[i][0]=12; break;
  705.             case 'K': lhand[i][0]=13; break;
  706.             case 'A': lhand[i][0]=14; break;
  707.             default:  lhand[i][0]-=48;
  708.         }
  709.     }
  710.     /* LOOK FOR FLUSH */
  711.     if ((lhand[0][1]==lhand[1][1])&&(lhand[0][1]==lhand[2][1])&&
  712. (lhand[0][1]==lhand[3][1])&&(lhand[0][1]==lhand[4][1])) flush=1;
  713.     
  714.     /* LOOK FOR STRAIGHT */
  715.     if ((lhand[0][0]+4==lhand[4][0])&&(lhand[1][0]+3==lhand[4][0])&&
  716. (lhand[2][0]+2==lhand[4][0])&&(lhand[3][0]+1==lhand[4][0])) straight=1;
  717.     if ((lhand[0][0]==2)&&(lhand[1][0]==3)&&(lhand[2][0]==4)&&
  718. (lhand[3][0]==5)&&(lhand[4][0]==14)) straight=1;
  719.     
  720.     /* LOOK FOR STRAIGHT FLUSH */
  721.     if ((flush==1)&&(straight==1)) stflush=1;
  722.     
  723.     /* LOOK FOR FOUR-OF-A-KIND */
  724.     aq= bq= cq= dq= eq=0;
  725.     a=lhand[0][0];
  726.     b=lhand[1][0];
  727.     c=lhand[2][0];
  728.     d=lhand[3][0];
  729.     e=lhand[4][0];
  730.     if (((a==b)&&(a==c)&&(a==d))||((b==c)&&(b==d)&&(b==e))) four=1;
  731.     
  732.     /* LOOK FOR FULL HOUSE */
  733.     aq=1;
  734.     for (i=1;i<5;i++) if (lhand[i][0]!=lhand[i-1][0]) aq++;
  735.     if ((aq==2)&&(four==0)) full=1;
  736.  
  737.     /* LOOK FOR TWO PAIR AND THREE-OF-A-KIND */
  738.     if (aq==3){
  739.         bq=0;
  740.         for (i=0;i<5;i++){
  741.             cq=0;
  742.             for (j=0;j<5;j++){
  743.                 if (i==j) continue;
  744.                 if (lhand[i][0]==lhand[j][0]) cq++;
  745.             }
  746.             if (cq==0) bq++; /* bq SHOULD = # OF UNMATCHED CARDS */
  747.         }
  748.         if (bq==2) three=1;
  749.         if (bq==1) twopair=1;
  750.         if ((bq==0)||(bq>2)) {
  751.             myprintf("\nError in TWOPAIR/THREE routine.\n");
  752.             exit(1);
  753.         }
  754.     }
  755.     
  756.     /* LOOK FOR PAIR */
  757.     if (aq==4) pair=1;
  758.     
  759.     /* SET values[0] TO INDICATE TYPE OF HAND */
  760.     if (pair==1) hand[who].values[0]=1;
  761.     if (twopair==1) hand[who].values[0]=2;
  762.     if (three==1) hand[who].values[0]=4;
  763.     if (straight==1) hand[who].values[0]=8;
  764.     if (flush==1) hand[who].values[0]=16;
  765.     if (full==1) hand[who].values[0]=32;
  766.     if (four==1) hand[who].values[0]=64;
  767.     if (stflush==1) hand[who].values[0]=128;
  768.     
  769.     /* SEND OUT FOR THE REST OF values[] */
  770.     if (hand[who].values[0]==0) setvnull(lhand,hand[who].values);    
  771.     if (hand[who].values[0]==1) setvpair(lhand,hand[who].values);
  772.     if (hand[who].values[0]==2) setvtwo(lhand,hand[who].values);
  773.     if (hand[who].values[0]==4) setvthre(lhand,hand[who].values);
  774.     if (hand[who].values[0]==8) setvstra(lhand,hand[who].values);
  775.     if (hand[who].values[0]==16) setvnull(lhand,hand[who].values); /* FLUSH SAME AS NULL */
  776.     if (hand[who].values[0]==32) setvfull(lhand,hand[who].values);
  777.     if (hand[who].values[0]==64) setvfour(lhand,hand[who].values);
  778.     if (hand[who].values[0]==128) setvstra(lhand,hand[who].values); /* ST-FLUSH SAME AS STRAIGHT */
  779.  
  780.  
  781. }
  782. /* --------------------------- SETV */
  783. void setvnull(lhand,values)
  784. char lhand[][2];
  785. int values[];
  786. {
  787.     int i;
  788.     for (i=1;i<6;i++) values[i]=lhand[5-i][0];
  789. }
  790. void setvpair(lhand,values)
  791. char lhand[][2];
  792. int values[];
  793. {
  794.     int i,j;
  795.  
  796.     for (i=1;i<6;i++) values[i]=0;
  797.     for (i=0;i<4;i++) if (lhand[i][0]==lhand[i+1][0]) values[1]=lhand[i][0]; 
  798.     j=2;
  799.     if (lhand[4][0]!=lhand[3][0]) values[j++]=lhand[4][0];
  800.     for (i=3;i>0;i--) {
  801.         if ((lhand[i][0]!=lhand[i-1][0])&&(lhand[i][0]!=lhand[i+1][0])){
  802.             values[j++]=lhand[i][0];
  803.         }
  804.     }
  805.     if (lhand[0][0]!=lhand[1][0]) values[j++]=lhand[0][0];
  806. }
  807. void setvtwo(lhand,values)
  808. char lhand[][2];
  809. int values[];
  810. {
  811.     int i,j;
  812.     j=1;
  813.  
  814.     for (i=4;i>0;i--)
  815.         if (lhand[i][0]==lhand[i-1][0]) values[j++]=lhand[i][0];
  816.     if (lhand[4][0]!=lhand[3][0]) values[j++]=lhand[4][0];
  817.     for (i=3;i>0;i--) 
  818.         if ((lhand[i][0]!=lhand[i-1][0])&&(lhand[i][0]!=lhand[i+1][0]))
  819.             values[j++]=lhand[i][0];
  820.     if (lhand[0][0]!=lhand[1][0]) values[j++]=lhand[0][0];
  821.     while (j<6) (values[j++])=0;
  822. }
  823. void setvthre(lhand,values)
  824. char lhand[][2];
  825. int values[];
  826. {
  827.     int i,j;
  828.  
  829.     for (i=0;i<4;i++) if (lhand[i][0]==lhand[i+1][0]) values[1]=lhand[i][0];
  830.     j=2;
  831.     if (lhand[4][0]!=lhand[3][0]) values[j++]=lhand[4][0];
  832.     for (i=3;i>0;i--) 
  833.         if ((lhand[i][0]!=lhand[i-1][0])&&(lhand[i][0]!=lhand[i+1][0]))
  834.             values[j++]=lhand[i][0];
  835.     if (lhand[0][0]!=lhand[1][0]) values[j++]=lhand[0][0];
  836.     while (j<6) (values[j++])=0;
  837. }
  838. void setvstra(lhand,values)
  839. char lhand[][2];
  840. int values[];
  841. {
  842.     int i;
  843.     if ((lhand[0][0]==2)&&(lhand[4][0]==14)) values[1]=5;
  844.     else values[1]=lhand[4][0];
  845.     for (i=2;i<6;i++) values[i]=0;
  846. }
  847. void setvfull(lhand,values)
  848. char lhand[][2];
  849. int values[];
  850. {
  851.     int i;
  852.     for (i=3;i>0;i--) 
  853.         if ((lhand[i][0]==lhand[i+1][0])&&(lhand[i][0]==lhand[i-1][0])){
  854.             values[1]=lhand[i][0];
  855.             break;
  856.         }
  857.     if (i==1) values[2]=lhand[4][0];
  858.     else values[2]=lhand[0][0];
  859.     
  860.     values[3]= values[4]= values[5]=0;
  861. }
  862. void setvfour(lhand,values)
  863. char lhand[][2];
  864. int values[];
  865. {
  866.     int i;
  867.     values[1]=lhand[1][0];
  868.     if (lhand[1][0]!=lhand[0][0]) values[2]=lhand[0][0];
  869.     else values[2]=lhand[4][0];
  870.     for (i=3;i<6;i++) values[i]=0;
  871. }
  872.  
  873. /* ------------------------------------- MAKEBET */
  874. /* 
  875. v[6] is values for the computer's hand
  876. q is a character as follows:
  877.     q=='o' if player has passed the opener and it is the computer's
  878.         turn to offer an opener.
  879.     q=='y' if the computer has opened and now it is the computer's
  880.         turn to bet first at the final bet.
  881.     q=='t' if the player has made a bet and the computer must decide
  882.         whether to call, fold, or raise. (at the opening)
  883.     q=='e' same as above, but at the final betting.
  884. bet is the amount of the bet the player has made, which the computer is
  885.     being challanged upon to match.
  886. pot is the amount of the pot, not counting the pending bet.
  887. bluff is the bluff index.
  888.  
  889. This function returns an integer as follows:
  890.     ('p'|1024) if the computer is to pass. Legal only if q=='o' or q=='y'
  891.     ('f'|1024) for fold. 
  892.     ('c'|1024) is for call. 
  893.     Otherwise the amount of the bet between 1 and 50.                */
  894.  
  895.  
  896. int makebet(highbet,mytotal,v,q,who)
  897. int mytotal,highbet,who;
  898. int q,v[];
  899. {
  900.     int b2,bet,bluff;
  901.     
  902.     bet=highbet-mytotal;
  903.     bluff=hand[who].bluff;
  904.     if (q=='o'){               /* computer's turn to open */
  905.         if (bluff>97) return('p'|1024);
  906.         if (v[0]>=8) return(50);
  907.         if (bluff==0) return(50);
  908.         if ((v[0]>=2)|| ((v[0]==1)&&(v[2]>10)) ) return(25);
  909.         if (bluff<=2) return(25);
  910.         return(('p'|1024));
  911.     }
  912.     if (q=='y') {            /* Round 2 computer's turn to open. */
  913.         if (bluff>97) return('p'|1024);
  914.         if (bluff==0) return(50);
  915.         if (v[0]>=8)  return(50);
  916.         if (bluff<=2) return(25);
  917.         if ((v[0]>2)||((v[0]==2)&&(v[1]>=10))) return(25);
  918.         return('p'|1024);
  919.     }
  920.     if (q=='t'){             /* Round 1 normal bet. */
  921.         if ((bluff)&&(v[0]<=4)&&(mytotal>150)) return('c'|1024);
  922.         if (mytotal>250) return('c'|1024);
  923.         if (bluff==0) return(50);
  924.         if (v[0]>=8) return(50);
  925.         if (bluff<=2) {
  926.             if (mytotal>=25) return('c'|1024);
  927.             return(25);
  928.         }
  929.         if ((v[0]>2)||((v[0]==2)&&(v[1]>=10))) return(25);
  930.         if (v[0]==0){
  931.             if (al_flushq(who)) return('c'|1024);
  932.             if (al_stq(who)) return('c'|1024);
  933.             if (bet< ((bluff/25)+10)) return('c'|1024);
  934.             return('f'|1024);
  935.         }
  936.         return(('c'|1024));
  937.     }
  938.     if (q=='e'){           /* Round 2 normal bet. */
  939.             /* Set a reasonable limit: */
  940.         if ((bluff)&&(v[0]<=4)&&(mytotal>150)) return('c'|1024);
  941.         if (mytotal>250) return('c'|1024); 
  942.             /* Bluff: */
  943.         if (bluff==0) return(50);
  944.             /* Low bluff: */
  945.         if (bluff>97) return('c'|1024);
  946.             /* Bet real hands: */
  947.         if (v[0]>8) return(50);
  948.         if (v[0]==4) {
  949.             if (bluff%10==0) return(25);
  950.             return(50);
  951.         }
  952.         if (v[0]==4){
  953.             if (bluff%10) return(50);
  954.             return(25);
  955.         }
  956.         if (bluff<=2) return(25);
  957.             /* when to fold: */
  958.         if ((v[0]==0)||((v[0]==1)&&(v[1]<=10))) { /* worthless hand */
  959.             if (bet<(bluff%25)+5) return(('c'|1024));
  960.             if (bet<(pot/25)) return(('c'|1024));
  961.             return(('f'|1024));
  962.         }
  963.         return('c'|1024);
  964.     }
  965. }
  966. /* Note A -- The effect of the step referenced is that if the player opens
  967.    with a token bet, to try to grab the ante, and if the computer fails
  968.    to raise the bet, the player will not necessarily know that the computer
  969.    has a poor hand.                                                   */
  970.  
  971. int getbet(q,line,pot,bet)
  972. int q, *line, bet, pot;
  973. {
  974.     char buf[50];
  975.     int n,i;
  976.     
  977.     setcolor(hand[player].color);
  978.     myprintf("\n\nThere are now %d %s in the pot.",pot,money);
  979. inpu:    switch (q) {
  980.         case 'o': 
  981.             myprintf("\nEnter (P)ass or the amount of your opening bet: ");
  982.             prompt("Pass or bet.","","");
  983.             break;
  984.         case 'y':
  985.             myprintf("\nEnter (P)ass or the amount of your bet: ");
  986.             prompt("Pass or bet.","","");
  987.             break;
  988.         case 't':
  989.         case 'e':
  990.             myprintf("\nBet is %d. Enter (C)all, (F)old, or the amount of your raise: ",bet);
  991.             mysprintf(buf,"%d %s has been bet.",bet,money);
  992.             prompt(buf,"Call, fold, or raise.","");
  993.             break;
  994.         default: 
  995.             myprintf("\nError in getbet().");
  996.             exit(1);
  997.     }
  998.     for (i=0;;i++){
  999.         buf[i]=get2reply("\b\r\177fpc0123456789",q);
  1000.         if (buf[i]==8) {
  1001.             if (i==0) continue;
  1002.             i-=2;
  1003.             myprintf("\b \b");
  1004.             continue;
  1005.         }
  1006.         myputchar(tpr(buf[i]));
  1007.         if (buf[i]==13) { buf[i]=0; break; }
  1008.         if (buf[0]=='f') return(('f'|1024));
  1009.         if (buf[0]=='p'){
  1010.             if ((q=='o')||(q=='y')) return(('p'|1024));
  1011.             myprintf("\nLegal inputs are C, F, or a bet. "); 
  1012.             i=(-1);
  1013.             continue;
  1014.         }
  1015.         if (buf[0]=='c'){
  1016.             if ((q=='t')||(q=='e')) return(('c'|1024));
  1017.             myprintf("\nLegal inputs are P, F, or a bet. "); 
  1018.             i=(-1);
  1019.             continue;
  1020.         }
  1021.         if ((buf[i]==127)||(i>25)) {
  1022.             myprintf("\nDeleted. Start over: ");
  1023.             i=(-1);
  1024.             continue;
  1025.         }
  1026.         if ((buf[i]<'0')||(buf[i]>'9')) {
  1027.             myprintf("\b \b"); 
  1028.             i--;
  1029.             continue;
  1030.         }        
  1031.     }
  1032.     n=myatoi(buf);
  1033.     if (n>50){
  1034.         myprintf("\nLimit is 50 %s. Try again. ",money);
  1035.         goto inpu;
  1036.     }
  1037.     if (n==0){
  1038.         if (q=='o') return(('p'|1024));
  1039.         else return(('c'|1024));
  1040.     }
  1041.     return(n);
  1042. }
  1043.  
  1044. int al_flushq(who)
  1045. int who;
  1046. {
  1047.     int local[5],i;
  1048.     
  1049.     for (i=0;i<5;i++)
  1050.         local[i]=txt[ hand[who].cards[i] ][1];
  1051.     qsort(local,5,sizeof(int),comp);
  1052.     
  1053.     if ((local[0]==local[1])&&(local[1]==local[2])&&(local[2]==local[3]))
  1054.         return(1);
  1055.     if ((local[1]==local[2])&&(local[2]==local[3])&&(local[3]==local[4]))
  1056.         return(1);
  1057.     return(0);
  1058. }
  1059. int al_stq(who)
  1060. int who;
  1061. {
  1062.     int local[5],i;
  1063.     
  1064.     for (i=0;i<5;i++){
  1065.         local[i]= txt[ hand[who].cards[i] ][0];
  1066.         switch (local[i]) {
  1067.             case 'T': local[i]=10+48; break;
  1068.             case 'J': local[i]=11+48; break;
  1069.             case 'Q': local[i]=12+48; break;
  1070.             case 'K': local[i]=13+48; break;
  1071.             case 'A': local[i]=14+48; break;
  1072.         }
  1073.     }
  1074.     
  1075.     if ((local[0]+1==local[1])&&(local[1]+1==local[2])&&(local[2]+1==local[3]))
  1076.         return(1);
  1077.     if ((local[1]+1==local[2])&&(local[2]+1==local[3])&&(local[3]+1==local[4]))
  1078.         return(1);
  1079.     return(0);
  1080. }
  1081.  
  1082. char *pfh_777 = "Press \"?\" for help." ;
  1083. char *yc_777 = "     Your cards:" ;
  1084. char *folded_777 = "Folded" ;
  1085.  
  1086. void prompt(s1,s2,s3)
  1087. char *s1,*s2,*s3;
  1088. {
  1089.     int i,j;
  1090.     char *p[5];
  1091.     
  1092.     p[1]=s1;
  1093.     p[2]=s2;
  1094.     p[3]=s3;
  1095.     p[4]=pfh_777; 
  1096.  
  1097.     for (i=0;i<80;i++)
  1098.         for (j=0;j<7;j++)
  1099.             scr_color(j,i,' ',0);
  1100.  
  1101.     for (i=0;yc_777[i];i++) 
  1102.         scr_color(0,i,yc_777[i],0);
  1103.  
  1104.     if (hand[player].in){
  1105.         for (i=0,j=4;i<5;i++,j--)
  1106.             writecard(2,COL1+i*6,hand[player].cards[j]);
  1107.     }
  1108.     else {
  1109.         for (i=0,j=4;i<5;i++,j--)
  1110.             writecard(2,COL1+i*6,52);
  1111.         for (i=0;folded_777[i];i++) 
  1112.             scr_color(3,i+13,folded_777[i],0);
  1113.       }
  1114.     
  1115.     for(i=41;i<79;i++) scr_color(0,i,205,0);
  1116.     for(i=41;i<79;i++) scr_color(5,i,205,0);
  1117.     for(i=1;i<5;i++) scr_color(i,40,186,0);
  1118.     for(i=1;i<5;i++) scr_color(i,79,186,0);
  1119.     scr_color(0,40,201,0);
  1120.     scr_color(0,79,187,0);
  1121.     scr_color(5,40,200,0);
  1122.     scr_color(5,79,188,0);
  1123.     
  1124.     for (i=41;i<=42;i++) 
  1125.         for (j=1;j<=4;j++)
  1126.             scr_color(j,i,' ',0);
  1127.     for (j=1;j<=4;j++) {
  1128.         for (i=0;p[j][i];i++) 
  1129.             scr_color(j,i+43,p[j][i],0);
  1130.         i+=43;
  1131.         while (i<79)
  1132.             scr_color(j,i++,' ',0); 
  1133.     }
  1134. }
  1135. void setcolor(c)
  1136. int c;
  1137. {
  1138.     if (color=='c') _attrib=c;
  1139. }
  1140.  
  1141. /* -------------------------------- SHUFFLE */
  1142. void shuffle()
  1143. {
  1144.     int i,j,k,num,hold[52];
  1145.     
  1146.     for (i=0;i<52;i++) deck[i]=i;
  1147.     
  1148.     for (k=0;k<3;k++) {
  1149.         for (num=51,i=0;i<52;i++,num--){
  1150.             if (num==0) j=0;
  1151.             else j=rando()%num+1;
  1152.             hold[i]=deck[j];
  1153.             deldeck(j);
  1154.         }
  1155.         for (i=0;i<52;i++) deck[i]=hold[i];
  1156.     }
  1157.     j=rando()%45+3;
  1158.     for (i=0;i<52;i++,j++) {
  1159.         if (j==52) j=0;
  1160.         deck[i]=hold[j];
  1161.     }
  1162. }
  1163. void deldeck(n)
  1164. int n;
  1165. {
  1166.     while (n<51) {
  1167.         deck[n]=deck[n+1];
  1168.         n++;
  1169.     }
  1170. }
  1171. int rando()
  1172. {
  1173.     static long zi;
  1174.     static int mark=1;
  1175.     long time();
  1176.     
  1177.     if (mark) {
  1178.         mark=0;
  1179.         zi = time((long *)0);
  1180.         zi = zi & 16383;
  1181.     }
  1182.     zi*=23;
  1183.     zi+=17;
  1184.     zi%=32749;
  1185.     return((int)zi);
  1186. }
  1187. /* ------------------------------ COMP */
  1188. int comp(a,b)
  1189. char *a,*b;
  1190. {
  1191.     return(*(int *)a-*(int *)b);
  1192. }
  1193. int compf(a,b)
  1194. char *a,*b;
  1195. {
  1196.     a+=2;
  1197.     b+=2;
  1198.     return(*(int *)a-*(int *)b);
  1199. }
  1200. int valcmp(aa,bb)
  1201. char *aa,*bb;
  1202. {
  1203.     int i,*a,*b;
  1204.     
  1205.     a=(int *)aa;
  1206.     b=(int *)bb;
  1207.     for (i=0;i<6;i++){
  1208.         if (a[i]>b[i]) return(-1);
  1209.         if (b[i]>a[i]) return(1);
  1210.     }
  1211.     return(0);
  1212. }
  1213. int myatoi(s)
  1214. char *s;
  1215. {
  1216.     int n=0;
  1217.     
  1218.     while(*s==' ') s++;
  1219.     for(;;s++){
  1220.         if ((*s<'0')||(*s>'9')) return(n);
  1221.         n*=10;
  1222.         n+= *s-48;
  1223.     }
  1224. }
  1225.  
  1226. char *itoa(n,s)
  1227. int n;
  1228. char *s;
  1229. {
  1230.     s+=10;
  1231.     *s=0;
  1232.     for(;;){
  1233.         *(--s) = n%10+48;
  1234.         n/=10;
  1235.         if (n==0) return(s);
  1236.     }
  1237. }
  1238. int get2reply(s,q)
  1239. char *s;
  1240. int q;
  1241. {
  1242.     int i,c;
  1243.     
  1244.     for(;;){
  1245.         c=mygetch();
  1246.         if ((c=='?')||(c=='/')) { help(q); continue; }
  1247.         if ((c>='A')&&(c<='Z')) c+=32;
  1248.         for (i=0;s[i];i++) if (c==s[i]) return(c);
  1249.     }
  1250. }
  1251. int tpr(c)
  1252. int c;
  1253. {
  1254.  
  1255.     if ((c>='a')&&(c<='z')) c-=32;
  1256.     return(c);
  1257. }
  1258. int final_display()
  1259. {
  1260.     char *wp;
  1261.     int i,j,k,m,line,col,tie,helpflag=1;
  1262.     int order[5][7];
  1263.     
  1264.     for (i=0;i<5;i++) {
  1265.         hand[i].values[6]=i;
  1266.         for (j=0;j<7;j++) order[i][j]=(hand[i].values[j]);
  1267.         if (hand[i].in==0) 
  1268.             for (j=0;j<6;j++) hand[i].values[j]=order[i][j]=0;
  1269.     }
  1270.     qsort((char *) order, 5, 7*sizeof(int), valcmp);
  1271.     
  1272.     CLEARSCREEN;
  1273.     line=CARDLINE(0)-1;
  1274.     col=COL1;
  1275.     
  1276.     if (hand[order[1][6]].in == 0){  /* Only one hand in. No showdown. */
  1277.         setcolor(hand[ order[0][6] ].color);
  1278.         myprintf("Only one player remaining in.\n");
  1279.         if (order[0][6]!=player) 
  1280.             myprintf("%s takes", hand[ order[0][6] ].name ); 
  1281.         else myprintf("You take");
  1282.         myprintf(" the pot of %d %s.",pot,money); 
  1283.         helpflag=tie=0;
  1284.     }
  1285.     else for (i=0;i<5;i++){
  1286.         sendcurs(line,col);
  1287.         j=order[i][6];
  1288.         setcolor(hand[j].color);
  1289.         if (player==j) myprintf("Your cards:");
  1290.         else myprintf("%s\'s cards:", hand[j].name );
  1291.         
  1292.         line++;
  1293.         if (hand[j].in)
  1294.             for (m=0,k=4;m<5;m++,k--)
  1295.                 writecard(line,col+m*6,hand[j].cards[k]);
  1296.         else {
  1297.             for (m=0;m<5;m++)
  1298.                 writecard(line,col+m*6,52);
  1299.             sendcurs(line+1,col+8);
  1300.             myprintf("Folded");
  1301.         }
  1302.         line += 5;
  1303.         if (i==4) break;
  1304. /* problems here: */
  1305.         if (((valcmp((char *)order[i],(char *)order[i+1]))&&(col==COL1))||((i==3)&&(col==COL1))){
  1306.             sendcurs(line,5);
  1307.             if (i==0) myprintf("Take the pot");
  1308.             else myprintf("Split the pot");
  1309.             myprintf(" of %d %s.",pot,money); 
  1310.             line=CARDLINE(0)-1;
  1311.             col=COL2;
  1312.             tie=i;
  1313.         }
  1314.     }
  1315.     
  1316.     /* Settle the pot */
  1317.     for (i=0;i<=tie;i++)
  1318.         hand[order[i][6]].balance += pot/(tie+1);
  1319.     pot%= (tie+1);  /* Sets pot to zero but leaves the odd chips in. */
  1320.     
  1321.     /* Print out totals: */
  1322.     sendcurs(17,0);
  1323.     setcolor(hand[player].color);
  1324.     myprintf("Your balance is %d %s.\n",hand[player].balance,money);
  1325.     for (i=0;i<5;i++){
  1326.         if (i==player) continue;
  1327.         setcolor(hand[i].color);
  1328.         myprintf("%s\'s balance is %d %s.\n",hand[i].name,hand[i].balance,money);
  1329.     }
  1330.     setcolor(hand[player].color);
  1331.     rotate();
  1332.     player--;
  1333.     if (player==(-1)) player=4;
  1334.     setcolor(hand[player].color);
  1335.     myprintf("Would you like to play another hand? ");
  1336.     i=get2reply("yn",8+helpflag); 
  1337.     return (i);
  1338. }
  1339.  
  1340. rotate()
  1341. {
  1342.     struct _hand_ temp;
  1343.     int i;
  1344.     
  1345.     temp=hand[0];
  1346.     for(i=0;i<4;i++) hand[i]=hand[i+1];
  1347.     hand[4]=temp;
  1348. }
  1349.  
  1350. void writecard(v,h,card)
  1351. int v,h,card;
  1352. {
  1353.     int n,s;
  1354.     
  1355.     n=txt[card][0];
  1356.     s=txt[card][1];
  1357.     
  1358.     scr_color(v,h,218,0);
  1359.     scr_color(v,h+1,196,0);
  1360.     scr_color(v,h+2,196,0);
  1361.     scr_color(v,h+3,196,0);
  1362.     scr_color(v,h+4,191,0);
  1363.     scr_color(v+1,h,179,0);
  1364.     colorchar(v+1,h+1,s,' ');
  1365.     colorchar(v+1,h+2,s,' ');
  1366.     colorchar(v+1,h+3,s,' ');
  1367.     scr_color(v+1,h+4,179,0);
  1368.     scr_color(v+2,h,179,0);
  1369.     colorchar(v+2,h+1,s,' ');
  1370.     colorchar(v+2,h+2,s,' ');
  1371.     colorchar(v+2,h+3,s,' ');
  1372.     scr_color(v+2,h+4,179,0);
  1373.     scr_color(v+3,h,192,0);
  1374.     scr_color(v+3,h+1,196,0);
  1375.     scr_color(v+3,h+2,196,0);
  1376.     scr_color(v+3,h+3,196,0);
  1377.     scr_color(v+3,h+4,217,0);
  1378.     if (n=='T'){
  1379.         colorchar(v+1,h+1,s,'1');
  1380.         colorchar(v+1,h+2,s,'0');
  1381.     }
  1382.     else colorchar(v+1,h+2,s,n);  
  1383.     switch(s){
  1384.         case 'H': colorchar(v+2,h+2,s,3); break;
  1385.         case 'D': colorchar(v+2,h+2,s,4); break;
  1386.         case 'C': colorchar(v+2,h+2,s,5); break;
  1387.         case 'S': colorchar(v+2,h+2,s,6); break;
  1388.     }
  1389. }
  1390. void colorchar(v,h,suit,c)
  1391. int v,h,suit,c;
  1392. {
  1393.     switch (suit) {
  1394.         case 'H': 
  1395.         case 'D': scr_color(v,h,c,1); break;
  1396.         default:  scr_color(v,h,c,0);
  1397.     }
  1398. }
  1399. void scr_color(v,h,c,q)
  1400. int v,h,c,q;
  1401. {
  1402.     int off;
  1403.  
  1404.     off = 160*v+ 2*h;
  1405.     shmaddr[off]=c;
  1406.     switch(q){
  1407.         case 2:
  1408.             shmaddr[off+1]=helpcolor;
  1409.             break;
  1410.         case 1:
  1411.             shmaddr[off+1]=revid_atr;
  1412.             break;
  1413.         case 0:
  1414.             shmaddr[off+1]=norm_atr;
  1415.             break;
  1416.     }
  1417. }
  1418.  
  1419. void help(q)
  1420. int q;
  1421. {
  1422.     unsigned off;
  1423.     int i,h,v;
  1424.     static char *corent = "\
  1425. Use the BACKSPACE key to make corrections or the DEL key to start over.\n\
  1426. Press the ENTER (or RETURN) key to enter the amount you have indicated.";
  1427.     static char *yorn = "\
  1428. On returning to the game, answer \"Y\" to play another hand\n\
  1429. or \"N\" to exit from the program.\n";
  1430.     
  1431.     for (off=0;off<4000;off++) sidescreen[off]=shmaddr[off];
  1432.     
  1433.     scr_loc(&v,&h);
  1434.  
  1435.     CLEARSCREEN;
  1436.     setcolor(helpcolor);
  1437.     switch (q) {
  1438.         case 1:
  1439.     myprintf("Five-card draw poker is a gambling game.\n\
  1440. You must select which currency you wish to play for.\n");
  1441.     break;
  1442.         case 2:
  1443.     myprintf("The first round of betting has concluded.\n\
  1444. The program has paused to allow you to see how much each player has bet.\n");
  1445.     break;
  1446.         case 3:
  1447.     myprintf("\
  1448. At this point one or more players have discarded.\n\
  1449. The program has paused to let you see how many cards each has thrown out.\n\
  1450. Because discarding is done in rotation, there may be one or more\n\
  1451. players that have not yet discarded.\n\
  1452. They will do so after you.\n"); 
  1453.     break;
  1454.         case 4:
  1455.     myprintf("The program has paused to let you see how many cards have been\n");
  1456.     if (hand[player].in) {
  1457.         myprintf("\
  1458. thrown out by the players that came after you in the rotation order.\n\
  1459. \nWhen you continue, new cards will be dealt to you\n\
  1460. to replace any you have discarded.\n");
  1461.     }    
  1462.     else myprintf("thrown out by each player.\n");
  1463.     break;
  1464.         case 5:
  1465.     myprintf("Betting has concluded.\n\
  1466. The program has paused to let you see how much each player has bet.\n");
  1467.     break;
  1468.         case 6:
  1469.     myprintf("\
  1470. You may discard any number of cards.\n\
  1471. Or you may \"stand pat\" by discarding no cards.\n\n\
  1472. Using the numerals at the top of your keyboard, indicate the card(s)\n\
  1473. you wish to throw out.\n\
  1474. The leftmost card is \"1\", the rightmost card is \"5\"\n\n\
  1475. If you accidentally indicate a card you do not wish to discard,\n\
  1476. press the DEL key and start over.\n\n\
  1477. When you have correctly indicated ALL the cards you wish to throw out\n\
  1478. press the ENTER key. (May be marked \"RETURN\" on some keyboards.)\n");
  1479.     break;
  1480.         case 'o':
  1481.     myprintf("\
  1482. It is your turn to open the betting for this hand. Some poker rules require \n\
  1483. \"jacks or better\" to open. This version does not require any minimum hand to \n\
  1484. open. You may open on a bluff if you wish. Opening the betting merely means \n\
  1485. placing the first bet.\n\n\
  1486. If you do not wish to open, you may press P for PASS. You remain in the\n\
  1487. game and the next player has the chance to open. If no player opens, \n\
  1488. new hands are dealt and the game proceeds as with a new hand.\n\n\
  1489. To enter a bet, type the amount of your bet. The limit is 50 %s.\n\
  1490. An opening bet of zero is the same as PASS.\n\n\
  1491. %s",money,corent);
  1492.     break;
  1493.         case 'y':
  1494.     myprintf("\
  1495. This is the second (and final) round of betting. \n\
  1496. It is your turn to place the first bet.\n\n\
  1497. If you do not wish to bet, you may press P for PASS. You will remain in the \n\
  1498. game and the next player will have a chance to bet. If no player bets, the \n\
  1499. game proceeds directly to the \"showdown\" and the highest hand wins the pot.\n\n\
  1500. To enter a bet, type the amount of your bet. The limit is 50 %s.\n\
  1501. A bet of zero is the same as PASS.\n\n\
  1502. %s",money,corent);
  1503.     break;
  1504.         case 't':
  1505.         case 'e':
  1506.     myprintf("\
  1507. The %s round of betting is in progress.\n\
  1508. A bet has been placed by another player.\n\
  1509. You must either CALL the bet, FOLD your hand, or enter a raise.\n\
  1510. If you press C for CALL, it has the effect of matching the bet.\n\
  1511. You are putting that amount of money into the pot and you remain in the game.\n\
  1512. If you press F for FOLD, you are not putting any more money in the pot, but \n\
  1513. you forfeit whatever money you have already put in, and you are out of the \n\
  1514. game for the rest of this hand.\n\n\
  1515. If you raise (by entering a number from 1 to 50) you are putting that number \n\
  1516. of %s into the pot, PLUS the amount of the pending bet. \n\
  1517. Thus if there is a pending bet of 25 %s and you enter 25, you are\n\
  1518. actually putting 50 %s into the pot.\n\n\
  1519. To enter a raise, type the amount. The limit is 50 %s.\n\
  1520. A raise of zero is the same as CALL.\n\n\
  1521. %s", (q=='t') ? "opening" : "final" ,money,money,money,money,corent);
  1522.     break;
  1523.         case 9:
  1524.     myprintf("\
  1525. The winning hand is shown in the left column.\n\n\
  1526. The losing hands are shown in the right column, in descending order of\n\
  1527. strength.\n\n\
  1528. A player who has folded does not have to show his cards. Therefore you only\n\
  1529. see the cards of players who have remained in until the end.\n\n\
  1530. %s",yorn);
  1531.     break;
  1532.         case 8:
  1533.     myprintf("\
  1534. If every player but one has folded, rather than calling the bet of the one\n\
  1535. remaining player, that player wins the pot and does not have to show his\n\
  1536. cards. If you want to see the cards in the winning hand, you (or some other\n\
  1537. player) must call the bet.\n\n\
  1538. Thus, with only one player remaining in at the end of this hand, you are not\n\
  1539. shown any cards. Maddening, isn't it?\n\n\
  1540. %s",yorn);
  1541.     break;
  1542.         default:
  1543.     myprintf("\nError in help().\n");
  1544.     exit(1);
  1545.  
  1546.     }
  1547.     myprintf("\n\n\
  1548.      Now press \"H\" to see the order of poker hands.\n\
  1549.      Or press any other key to return to the game... ");
  1550.     
  1551.     for(;;){
  1552.         showtime();
  1553.         if ((i=inkey())!=-1) break;
  1554.     }
  1555.     if (tpr(i)=='H') instructions();
  1556.     
  1557.     for (off=0;off<4000;off++) shmaddr[off]=sidescreen[off];
  1558.     scr_curs(v,h);
  1559. }
  1560.  
  1561. void instructions()
  1562. {
  1563.     int r;
  1564.     
  1565.     CLEARSCREEN;
  1566.     myprintf("\
  1567. For complete rules of 5-card draw poker see Hoyle's Rules of Games.\n\
  1568. The order of poker hands is as follows:\n\n\
  1569. Straight-flush. (Any straight all in one suit.)\n\
  1570. Four-of-a-kind.\n\
  1571. Full house. (Three-of-a-kind plus a pair.)\n\
  1572. Flush. (Any 5 cards all of the same suit.)\n\
  1573. Straight. (5 cards all in numerical order, as 3,4,5,6,7 or 8,9,10,J,Q.)\n\
  1574. Three-of-a-kind.\n\
  1575. Two pair.\n\
  1576. Pair.\n\n\
  1577. For tie breaking higher cards beat lower cards and the ace is high,\n\
  1578. except that in a straight, an ace may be either high or low.\n\
  1579. There is no precidence of suits: All suits are equal.\n\
  1580. In a full house the 3-of-a-kind has higher precidence than the pair.\n\
  1581. In the event of a draw, the pot is split.\n\n\
  1582. Press any key... ");
  1583.     while ((r=inkey())==-1) showtime();
  1584. }
  1585. void intro(str)
  1586. char *str;
  1587. {
  1588.     char s[50],*abstoptr();
  1589.     int hour;
  1590.     struct tm t;
  1591.     
  1592.     CLEARSCREEN;
  1593.     myprintf("%s%s\
  1594. This program is shareware.\n\
  1595. You may make as many copies as you like.\n\
  1596. Please pass copies along to your friends.\n\
  1597. If you find it enjoyable please contribute $5 to help support the future\n\
  1598. of play-before-you-pay software.\n\n\
  1599. \tDan Schechter\n\
  1600. \tRoute 1 Box 19\n\
  1601. \tAmenia, North Dakota, 58004\n\n\
  1602. Man∙ thanks.\n\n\
  1603. Press any key to begin the game... ",version,cat);
  1604.     hour=mygetch();
  1605.     CLEARSCREEN;
  1606.     dostime(&t);
  1607.     hour=t.tm_hour;
  1608.     strcpy(str,"morning");
  1609.     if (hour>=12) strcpy(str,"afternoon");
  1610.     if (hour>=18) strcpy(str,"evening");
  1611.  
  1612.     if (( getmode() &15 ) ==7) color='m';
  1613.     else color='c';
  1614.  
  1615.     if (color=='m') shmaddr=abstoptr(0xb0000l);
  1616.     else shmaddr=abstoptr(0xb8000l);
  1617.     CLEARSCREEN;
  1618.     setcolor(helpcolor);
  1619.  
  1620. }
  1621. int mygetch()
  1622. {
  1623.     int c;
  1624.  
  1625.     do {
  1626.         while (scr_poll()==-1) rando();
  1627.         c=scr_getc();
  1628.         if ((c==3)||(c==-2)) exit(0);
  1629.         if (c==211) c=127;
  1630.         if (c==203) c=8;
  1631.     } while (c>127);
  1632.     return(c);
  1633. }
  1634. int inkey()
  1635. {
  1636.     int c;
  1637.     
  1638.     c=scr_poll();
  1639.     if (c==-1) return(-1);
  1640.     c=scr_getc();
  1641.     if (c>127) return(-1);
  1642.     if ((c==3)||(c==-2)) exit(0);
  1643.     return(c);
  1644.  
  1645. }
  1646.  
  1647. void showtime()
  1648. {
  1649.     struct tm t;
  1650.     char s[50];
  1651.     int i=0,hour;
  1652.     
  1653.     dostime(&t);
  1654.     hour=t.tm_hour;
  1655.     if (hour>=13) hour-=12;
  1656.     if (hour==0) hour=12;
  1657.     if (hour>=10) s[i++]='1';
  1658.     s[i++]=hour%10+48;
  1659.     s[i++]=':';
  1660.     s[i++]= t.tm_min/10+48;
  1661.     s[i++]= t.tm_min%10+48;
  1662.     s[i++]= ':';
  1663.     s[i++]= t.tm_sec/10+48;
  1664.     s[i++]= t.tm_sec%10+48;
  1665.     s[i]=0; 
  1666.  
  1667.     for(i=0;i<8;i++) scr_color(24,i+36,s[i],2); 
  1668.  
  1669.  
  1670. }
  1671. getmode()
  1672. {
  1673.     struct { unsigned ax,bx,cx,dx,si,di,ds,es; } regs;
  1674.     
  1675.     regs.bx=regs.cx=regs.dx=regs.si=regs.di=regs.ds=regs.es=0;
  1676.     regs.ax = 15<<8;
  1677.     sysint(0x10,®s,®s);
  1678.     
  1679.     return (regs.ax&255);
  1680. }
  1681. /* ------------------------------------------- FORMAT: 
  1682. I got carried away with wanting to minimize executable file size
  1683. So I sometimes use the following functions. */
  1684.  
  1685. static int (*fun)();
  1686. int myformat(f,ctrl,p)
  1687. int (*f)();
  1688. char *ctrl;
  1689. char *p;
  1690. {
  1691.     fun=f;
  1692.     
  1693.     while (*ctrl) {
  1694.         if ((*ctrl)=='%') {
  1695.             ctrl++;
  1696.             switch(*ctrl++){
  1697.                 case 's': 
  1698.                     _kstrput(p);
  1699.                     p += sizeof(char *);
  1700.                     break;
  1701.                 case 'd': 
  1702.                     _mydput(p);
  1703.                     p += sizeof(int);
  1704.                     break;
  1705.                 case 0:
  1706.                     return;
  1707.             }
  1708.             continue;
  1709.         }
  1710.         (*fun)(*(ctrl++));
  1711.     }
  1712. }
  1713. _kstrput(p)
  1714. char **p;
  1715. {
  1716.     int i=0;
  1717.     
  1718.     while ((*p)[i])
  1719.         (*fun) ((*p)[i++]);
  1720. }
  1721. _mydput(p)
  1722. char *p;
  1723. {
  1724.     int t,n,mask;
  1725.     
  1726.     n= *((int *)p);
  1727.     if (n<0){
  1728.         (*fun)('-');
  1729.         n = -n;
  1730.     }
  1731.     for(mask = 10000;mask!=1;mask/=10)
  1732.         if (mask<=n) break;
  1733.     for(;mask;mask/=10){
  1734.         t = n/mask;
  1735.         n -= t*mask;
  1736.         (*fun)(t+48);
  1737.     }
  1738. }
  1739. /* ------------------------------------------- PRINTF: */
  1740. myprintf(ctrl,parml)
  1741. char *ctrl;
  1742. unsigned parml;
  1743. {
  1744.     int myputchar();
  1745.     myformat(myputchar,ctrl,&parml);
  1746. }
  1747. int myputchar(c)
  1748. int c;
  1749. {
  1750.     if (c=='\t') myprintf("        ");
  1751.     else scr_putc(c);
  1752.     if (c=='\n') scr_putc('\r');
  1753. }
  1754. /* ------------------------------------------- SPRINTF: */
  1755. static char *qb;
  1756. mysprintf(s,ctrl,parml)
  1757. char *s,*ctrl;
  1758. unsigned parml;
  1759. {
  1760.     static int _ccp();
  1761.  
  1762.     qb = s;
  1763.     myformat(_ccp,ctrl,&parml);
  1764.     *qb = 0;
  1765. }
  1766. static _ccp(c)
  1767. {
  1768.     *qb++ = c;
  1769. }
  1770. /* ------------------------------------------- */
  1771.