billr@saab.CNA.TEK.COM (Bill Randle) (07/13/89)
Submitted-by: Metal Head <csx43%seq1.keele.ac.uk@nsfnet-relay.ac.uk> Posting-number: Volume 7, Issue 18 Archive-name: poker/Part01 [The author said he was losing net access shortly, so he may not be able to respond to bug reports. After I made a few minor fixes, it ran OK on my Sun 3/60, OS 3.5. -br] [[The game was written, and therefore works, under BSD4.2 (DYNIX). Due to differences in curses, it compiles, but does not work under System V release 2.0. The style of play may differ from what some people expect, but it is close to the most general versions I have played. The rules are included. The game is completely honest, but is quite tough to beat. The strategy can be easily modifyed, by examining the first lines of the file p_decide.c. All the useful information I could think of, relating to compiling, has been included in the README file.]] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 2)." # Contents: README MANIFEST makefile p_decide.c p_hand.c p_scr.c # p_strat.c poker.c # Wrapped by billr@saab on Wed Jul 12 10:54:32 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(974 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X This vesion of poker was written under early BSD 4.2 (DYNIX), X with a UCB universe. X It is not guaranteed to work when compiled in the att universe X (System V release 2) due to differences in curses. X X The file poker.h should be edited to define how the instructions X are to be displayed. /usr/ucb/more is used, but this can be altered, X and so must the path to the file poker_rules. X X The title screen (with the implementors address) is displayed X by the procedure title(), which is in p_scr.c X X Most bugs have been removed, any that exist are in the hand X recognition routines, and do not appear often. Anything that looks X suspicious is probably just a design feature that you do not agree X with, or is due to the compiler and universe used. X X I make this statement because I will soon loose my account, and X will not be able to help with queries. The code is however, fairly X well structured, so it should not be too hard to modify. END_OF_FILE if test 974 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(486 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X README 1 X input.c 2 X makefile 1 X p_deal.c 2 X p_decide.c 1 X p_hand.c 1 X p_scr.c 1 X p_strat.c 1 X poker.c 1 X poker.h 2 X poker_rules 2 END_OF_FILE if test 486 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(469 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' Xpoker: poker.o p_scr.o p_deal.o p_hand.o p_strat.o p_decide.o input.o X cc -o poker p_scr.o poker.o p_deal.o p_hand.o p_strat.o p_decide.o input.o -lcurses -ltermcap X# X# remove the -ltermcap from the above line, to compile in System V version 2 X# X Xpoker.o: poker.c poker.h X Xp_scr.o: p_scr.c poker.h X Xp_deal.o: p_deal.c poker.h X Xp_strat.o: p_strat.c poker.h X Xp_hand.o: p_hand.c poker.h X Xp_decide.o: p_decide.c poker.h X Xinput.o: input.c poker.h END_OF_FILE if test 469 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi if test -f 'p_decide.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'p_decide.c'\" else echo shar: Extracting \"'p_decide.c'\" \(7959 characters\) sed "s/^X//" >'p_decide.c' <<'END_OF_FILE' X#include "poker.h" X Xlong rand(); X Xstatic int percent[18] = {92,92,92,100,70,67,80,90,88,97, X 50,85,85,50,85,90,85,70}; X X/* Percent is an array of percentages, used in the decision making */ X/* routine */ X X X Xint decision_A(first_deal) X X{ X /* decide between hi pair or 4 flush */ X /* with a 70:30 bias to a pair */ X X if(!first_deal) X return 11; X X else X X return ((rand()%100 < 30) ? 10:11); X X}/* decision A */ X X X X Xint decision_B() X X{ X /* decide between using 3 card straight flush or 3 high cards */ X /* with a bias of 60:40 for 3 high cards */ X X X return ((rand()%100 < 40) ? 7:6); X X}/* decision B */ X X X X Xint decision_C() X X{ X /* decide whether to use 2 high cards or 3 card flush */ X /* there is a bias of 70:30 for 2 high cards */ X X X return ((rand()%100 < 30) ? 3:4); X X}/* decision C */ X X X X Xint decision_D() X X{ X /* decide between 3 card run and 1 high card */ X /* there is a bias of 70:30 for 1 high cards */ X X X return ((rand()%100 < 30) ? 2:1); X X}/* decision D */ X X X X Xint stay (Hv,last_act,deal,winnings) X int Hv,last_act,deal,winnings; X X{ X /*******************************************************/ X /* Do I stay ? */ X /* */ X /* Only if Hv (Handvalue) == 0 and */ X /*if last_act == 1 or 0 (i.e last was a stay, or */ X /*you go first). */ X /* */ X /* Which deal also determines staying, as on first deal*/ X /*there is room for improvement */ X /* */ X /*******************************************************/ X X X int result; X X result = 0; /* don't stay */ X X switch (deal) { X case 1 : /* first deal */ X if(Hv < 13 && Hv != 11 && Hv != 8) X /* i.e nothing in hand */ X { X if(last_act == 0) /* I go first */ X result = (rand()%100 < percent[0]); X X if(last_act == 1) /* opponent stayed */ X result = (rand()%100) < percent[1]; X X } X break; X X case 0 : /* second deal */ X if(Hv < 13 && Hv != 11 && Hv != 8) X /* i.e nothing in hand */ X { X if(last_act == 0) /* I go first */ X result = (rand()%100 < percent[2]); X X if(last_act == 1) /* opponent stayed */ X if(winnings >=0 ) X result = (rand()%100 < percent[3]); X X } X else /* some thing in hand */ X X if(Hv < 13) /* only consider if < 2 pair */ X { X if(last_act == 0) /* I go first */ X result = (rand()%100 < percent[4]); X X }; X break; X }/* switch */ X X X return result; X X} /* stay */ X X X Xint drop(deal,cards_taken,Hv,last_act,winnings,turn) X int deal,Hv; X int cards_taken,last_act; X int winnings,turn; X X{ X /**********************************************/ X /* Do i drop my cards ? */ X /* */ X /* Only consider if nothing in hand and last */ X /*action was increase. Number of cards taken */ X /*by opponent, if second deal, is important. */ X /* If presently losing money, then be more */ X /*cautious, and drop more often. */ X /* */ X /* Follow through with a bluff, so never */ X /* drop if have previously bet. */ X /* */ X /**********************************************/ X X int result; X X result = 0; /* do not drop */ X X if(last_act < 9) X /* If the last action was a raise, i.e. >= 9, then I must have*/ X /* previously bet, so it is important to carry the bet on */ X /* and not go back on a bluff. */ X /* Otherwise, I have added no money to the pot, and can */ X /* consider dropping. */ X X switch (deal) { X X case 1 : /* first deal */ X X if(Hv < 13 && Hv != 11 && Hv != 8) X /* i.e nothing in hand */ X { X if(last_act ==0) /* go first */ X if(winnings >= 0) X result = (rand()%100) < percent[5]; X else X result = (rand()%100) < percent[6]; X X if(last_act > 3) /* opponent bet */ X if(winnings < 0) X result = (rand()%100) < percent[7]; X else X result = (rand()%100) < percent[8]; X } X X break; X X case 0 : /* second deal */ X X if(Hv < 13 && Hv != 11 && Hv != 8) X /* i.e nothing in hand */ X X { X if(last_act == 0) /* go first */ X X if(cards_taken == 0) /* opponent took no cards */ X result = (rand()%100) < percent[9]; X else X if(winnings >=0 ) X result = (rand()%100) < percent[10]; X else X result = (rand()%100) < percent[11]; X X if(last_act > 3) X if(winnings <0) X result = (rand()%100) < percent[12]; X else X result = (rand()%100 < percent[13]); X } X X else /* have some thing */ X if(cards_taken == 0 && Hv <15 ) X result = (rand()%100 < percent[14]); X } X X return result; X X}/* drop */ X X X Xint calling(Hv,turn,first_deal,cards_taken) X int Hv,turn,cards_taken,first_deal; X X{ X /* calling is determined by hand value and pot */ X /* on turn 6 of the betting the only options will be */ X /* drop or call, so automatically call on 6 */ X X int action; X X X action =0; /* do not call */ X X if (turn == 6) X action = 1; X X else X { X if(Hv < 13 && Hv != 11 && Hv != 8) X /* i.e nothing in hand */ X X action = (rand()%100 < percent[15]); /* nearly always call */ X else X if(Hv < 13) /* less than 2 pair */ X if(!first_deal && cards_taken == 0) X action = (rand()%100 < percent[16]); /* likely to call */ X else X action = (rand()%100 < percent[17]); X } X X return action; X X}/* calling */ X X X Xint increase(Hv,first_deal,cards_taken) X int Hv,first_deal,cards_taken; X X X{ /* increase current bet by one of three amounts */ X /* Small , Medium , Large . */ X /* */ X /* returned amounts are :- */ X /* */ X /* 1 - 5 , corresponding to bets of */ X /* 5,10,15,20,25 respectively */ X /* */ X X int amount; X X X switch (Hv) { X X case 20 : case 19 : case 18 : case 17 : case 16 : /* all 5 cards */ X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()%3); /* 1,2 or 3 */ X else X amount = 4 + (rand()&01); /* 4 or 5 */ X X break; X X case 15 : case 14 : case 13 : /* more than a hi pair */ X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()%3); /* 1,2 or 3 */ X else X amount = 4 + (rand()&01); /* 4 or 5 */ X X break; X X case 8 : /* lo pair */ X if (first_deal) X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()&01); /* 1 or 2 */ X else X amount = 3; X } X else /* second_deal */ X { X if(cards_taken ==0 ) X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1; X else X amount = 2; X } X else /* some cards taken */ X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()&01); /* 1 or 2 */ X else X amount = 3; X } X } X X break; X X case 11 : /* hi pair */ X if (first_deal) X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()&01); /* 1 or 2 */ X else X amount = 3; X } X X else /* second_deal */ X { X if(cards_taken ==0 ) X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()&01); X else X amount = 3; X } X else /* some cards taken */ X { X if( rand()%100 < 75) /* 75% of the time */ X amount = 1 + (rand()%3); /* 1,2 or 3 */ X else X amount = 4 + (rand()&01); /* 4 or 5 */ X } X } X X break; X X default : /* nothing in hand */ X amount = 1 + (rand()%5); /* 1 to 5 */ X break; X }/* switch */ X X X return amount; X X}/* increase bet */ X X END_OF_FILE if test 7959 -ne `wc -c <'p_decide.c'`; then echo shar: \"'p_decide.c'\" unpacked with wrong size! fi # end of 'p_decide.c' fi if test -f 'p_hand.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'p_hand.c'\" else echo shar: Extracting \"'p_hand.c'\" \(6808 characters\) sed "s/^X//" >'p_hand.c' <<'END_OF_FILE' X#include "poker.h" X X/* p_hand.c what is in the hand */ X X X Xflush flusher(hand) X playing_card *hand; X X/* Identify the xistence of a (partial)flush, and record the cards involved */ X{ X flush result; X X int count1,count2,x_posn; X int suit_matrix[4][HAND_SIZE + 1]; X X/* suit_matrix holds the no. of cards in each suit */ X X result.flush_of = 0; X X /* clear suit_matrix */ X X for(count1=0;count1<4;count1++) X suit_matrix[count1][0] = 0; X X/* fill in suit_matrix */ X X for(count1=0;count1 < HAND_SIZE;count1++) X { X x_posn = hand[count1].suit_value; X X suit_matrix[x_posn][(++suit_matrix[x_posn][0])] = count1; X X } X X for(count1=0;count1<4;count1++) X X if((result.flush_of = suit_matrix[count1][0]) >= 3) X { X for(count2=1;count2 <= result.flush_of; count2++) X result.cards[count2 - 1] = suit_matrix[count1][count2]; X X break; X } X X return result; X X}/* flusher */ X X Xint high_straight(hand) X playing_card *hand; X X/* Identify the existence of a five card straight */ X{ X X int have,ace; X int total,mean,count; X X total=0; X ace=0; X X ace = (hand[0].face_value == 1); X X for(count=0;count<HAND_SIZE;count++) X total += hand[count].face_value; X X mean = total/HAND_SIZE; X X have=1; X X if(!(total == 47 && ace)) /* i.e not AKQJT */ X for (count=0;count<HAND_SIZE;count++) X if (hand[count].face_value > (mean + 2) || X hand[count].face_value < (mean - 2)) X X have =0; X X return have; X X}/* high straight */ X X X Xprile pairs(hand) X playing_card *hand; X X/* find any pairs, or groupings of pairs */ X{ X int count,card_count,res,card; X int check[13]; X prile result; X X X for(count=0;count<13;count++) X check[count] = 0; /* clear check */ X X res = 2; X result.no_of_cards = 0; X X check[hand[0].face_value - 1] = 2; X X for(count=1;count<HAND_SIZE;count++) X { X card = hand[count].face_value - 1; X if (check[card] >= 2) X { X res *= check[card]; X check[card] = res; X } X else X check[card] = 2; X } X X result.p_type = res; X if (res > 2) X { X card_count = 0; X for(count =0;count<HAND_SIZE;count++) X if(check[hand[count].face_value - 1] > 2) X result.cards[card_count++] = count; X } X X X return result; X}/* pairs */ X X X Xrun runs(in_hand,pair,posn) X playing_card *in_hand; X int pair; X int posn; X X/* Identify any partial runs, of length >= 3 */ X/* It uses a sliding window, of varying size, to isolate */ X/* any runs, then does specific checks at the end for open */ X/* runs, such as 34_67 */ X X{ X playing_card hand[HAND_SIZE]; X X int start,window,sum,mean; X int remove,compare,limit; X int straight,count; X int diff,begin; X X run result; X X X for(count=0;count<HAND_SIZE;count++) X /* move in_hand to hand */ X /* so as not to corrupt hand */ X X hand[count] = in_hand[count]; X X X start = 0; X window = 3; X X result.length = 0; X result.open_str = 0; X begin = 0; X X if (pair) /* if a pair is present */ X { X if(posn == 0) /* check if card is first in hand */ X /* then find a card to compare suits with */ X compare = 2; X else X compare = posn - 1; X X /* preserve any straight flushes */ X X if(hand[posn].suit == hand[compare].suit) X remove = posn + 1; X else X remove = posn; X X /* shift chosen card to right of hand */ X X for(count=remove+1;count < HAND_SIZE;count++) X swap((hand + count -1),(hand+count)); X } X X limit = HAND_SIZE - pair; /* 4 or 5 */ X /* limit is the number of cards, in the possibly altered hand */ X X do X { X sum =0; X for (count = start;count < (start + window);count++) X sum += hand[count].face_value; X X mean = sum/window; X X straight = 1; /* disprove that a straight is present */ X diff = window/2; X X for(count = start;(count < (start + window) && straight );count++) X X straight = !(hand[count].face_value < mean - diff || X hand[count].face_value > mean + diff); X /* i.e is there a run present */ X X X if (straight) X { X result.length = window++; X begin = start; X } X else X start++; X } X while(start + window <= limit); X X X if(result.length > 0) /* identify cards in run */ X X for (count = 0;count < result.length;count++) X result.card[count] = begin + count; X X X if(result.length == 3) /* look for open straight */ X { X if (begin > 0) X { X /* check card to left */ X X if(hand[(begin - 1)].face_value == hand[begin].face_value - 2) X { X result.card[ result.length++ ] = begin - 1; X result.open_str = 1; X } X if((begin + 2) < (limit - 1)) X /* check card to right if 3 run is in middle of hand */ X X if(hand[limit].face_value == hand[limit - 1].face_value + 2) X { X result.card[ result.length++ ] = limit; X result.open_str = 1; X } X X } X else X /* begin = 0 */ X if (hand[3].face_value == hand[2].face_value + 2) X { X result.card[result.length++ ] = 3; X result.open_str = 1; X } X } X X X if(hand[0].face_value == 1) /* handle any possible top straight */ X X { X X if(hand[limit].face_value == 13 && hand[limit-1].face_value == 12) X if (hand[limit-2].face_value == 11) X { X result.length = 4; X result.card[0] = 0; X result.card[1] = limit-2; X result.card[2] = limit-1; X result.card[3] = limit; X } X else X { X result.length = 3; X result.card[0] = 0; X result.card[1] = limit-1; X result.card[2] = limit; X } X else /* look for TJQA */ X { X if (hand[limit].face_value == 12 && hand[limit-1].face_value == 11) X if (hand[limit-2].face_value == 10) X { X result.length = 4; X result.card[0] = 0; X result.card[1] = limit-2; X result.card[2] = limit-1; X result.card[3] = limit; X result.open_str = 1; X } X } X } X X if(pair) X /* undo shifting of cards */ X /* by incrementing the positon of cards to the right of the */ X /* moved card */ X X for(count=0;count<result.length;count++) X result.card[count] += (count >= remove); X X X return result; X X }/* runs */ X X X X Xhigh high_cards(hand) X X playing_card *hand; X X/* find all the High cards, i.e. >= 10 */ X X{ X int count; X high result; X X result.number = 0; X X for(count=0;count<HAND_SIZE;count++) X if(hand[count].face_value >= 10 || hand[count].face_value == 1) X result.cards[result.number++] = count; X X if(result.number == 1) /* choose a 2nd card to keep,but don`t report */ X result.cards[1] = (hand[0].face_value == 1)?4:3; X X if(result.number == 0) X { X result.cards[0] = 3; X result.cards[1] = 4; /* keep top highest two cards */ X } X X return result; X X}/* high cards */ X END_OF_FILE if test 6808 -ne `wc -c <'p_hand.c'`; then echo shar: \"'p_hand.c'\" unpacked with wrong size! fi # end of 'p_hand.c' fi if test -f 'p_scr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'p_scr.c'\" else echo shar: Extracting \"'p_scr.c'\" \(11110 characters\) sed "s/^X//" >'p_scr.c' <<'END_OF_FILE' X#include "poker.h" X#include <curses.h> X#include <signal.h> X#define x_pos(card_num) (((card_num)%5) * 8 + 1) X#define y_pos(card_num) (((card_num)/5) * 18) X#define WHERE(a,b) ((a) + (5 * ((b) != 0))) X#define MES_Y 1 X#define MES_X 1 X X X X/* These functions will handle the display */ X XWINDOW *_card[10]; X X/* a window for each card */ X X Xreally() X X/* Do you really want to quit ? */ X X{ X int old_x, old_y; X char reply; X X getyx(stdscr,old_y,old_x); X move(23,0); X printw("Do you really want to quit ? "); X refresh(); X do X get_input(0,&reply); X while(reply != 'y' && reply != 'n'); X move(23,0); X printw(" "); X refresh(); X if(reply == 'y') X die(); X else X { X move(old_y,old_x); X refresh(); X redraw_screen(); X } X X} X X Xdie () X{ /* what to do if user interupts */ X /* and really wants to quit */ X X signal(SIGINT,SIG_IGN); X echo(); X nocrmode(); X mvcur(0,COLS-1,LINES-1,0); X endwin(); X exit(); X} X X Xinitialise_screen() X X/* init. screen and signals */ X{ X initscr(); X X /* initscr() has problems when compiled under att SysV */ X X if (ERR) X { X printf("Error in initialising curses\n"); X die(); X } X X nl(); X noecho(); X crmode(); X leaveok(stdscr,TRUE); X scrollok(stdscr,FALSE); X signal(SIGINT,really); X signal(SIGQUIT,really); X /* these signals have problems when compiled under att SysV */ X X}/* init */ X X Xtitle_screen() X{ X X char key_press; X X clear(); X move(10,0); X printw(" +----------------------------------------------------+\n"); X printw(" | Welcome to 5 Card Draw Poker |\n"); X printw(" | |\n"); X printw(" | This is the Final Year Project of Nic Smith. |\n"); X printw(" | Written for BSD 4.2 Unix |\n"); X printw(" | Please mail any comments or bugs to :- |\n"); X printw(" | csx43@uk.ac.kl.seq1 |\n"); X printw(" +----------------------------------------------------+\n"); X X move(22,0); X printw("---More---"); X refresh(); X do X get_input(0,&key_press); X while (key_press != ' '); X X} X X X Xredraw_screen() X X{ X wrefresh(curscr); X} X X Xinstruct() X X/* display instructions and rules. The position of the file used is */ X/* defined in poker.h as INSTRUCTIONS */ X{ X char *inst[100]; X char reply; X X X clear(); X move(1,0); X printw("Do you want instructions and rules ? [y/n] : "); X move(1,45); X refresh(); X do X get_input(0,&reply); X while(reply != 'y' && reply != 'n'); X printw("%c",reply); X refresh(); X if(reply == 'y') X { X sprintf(inst,INSTRUCTIONS); X clear(); X refresh(); X system(inst); X } X X} X X X Xdraw_screen() X X /* set up the screen for the game. */ X X{ X int count; X X X clear(); X refresh(); X X /* first, draw the ten windows for the cards */ X X for (count =0;count<10;count++) /* places for the two hands */ X { X _card[count]=subwin(stdscr,5,5,y_pos(count),x_pos(count)); X scrollok(_card[count],FALSE); X leaveok(_card[count],FALSE); X box(_card[count],'|','-'); X X wmove(_card[count],0,0); X waddch(_card[count],'+'); X X wmove(_card[count],4,0); X waddch(_card[count],'+'); X X wmove(_card[count],0,4); X waddch(_card[count],'+'); X X wmove(_card[count],4,4); X waddch(_card[count],'+'); X }; X X/* Then number the cards */ X X for (count =0;count< HAND_SIZE;count++) X { X move(5,(x_pos(count) + 2)); X printw("%d",count + 1); X X move(17,(x_pos(count) + 2)); X printw("%d",count + 1); X X refresh(); X } X X X/* Finally set up other screen messages, such as stake etc. */ X X move(3,49); X printw("Stake : "); X X move(7,13); X printw("Your cards."); X X move(12,55); X printw("Pot : "); X X move (15,13); X printw("My cards."); X X move(20,49); X printw("Stake : "); X X refresh(); X X} X X X Xshow_hand (hand,at_bottom) X X playing_card *hand; X int at_bottom; X X /* display the given hand at the top/bottom of sreen */ X /* at_bottom, refers to where on the screen, and is boolean */ X X{ X int count; X X for (count=0;count<HAND_SIZE;count++) { X X wmove(_card[WHERE(count,at_bottom)],1,1); X waddch(_card[WHERE(count,at_bottom)],hand[count].suit); X X wmove(_card[WHERE(count,at_bottom)],2,2); X waddch(_card[WHERE(count,at_bottom)],hand[count].face); X X wmove(_card[WHERE(count,at_bottom)],3,3); X waddch(_card[WHERE(count,at_bottom)],hand[count].suit); X }; X refresh(); X X}/*show_hand*/ X X X Xclear_my_hand () X X/* wipe out the cards that appeared in the computer's position */ X X{ X int count; X X for (count=0;count<HAND_SIZE;count++) { X X wmove(_card[HAND_SIZE + count],1,1); X waddch(_card[HAND_SIZE + count],' '); X X wmove(_card[HAND_SIZE + count],2,2); X waddch(_card[HAND_SIZE + count],' '); X X wmove(_card[HAND_SIZE + count],3,3); X waddch(_card[HAND_SIZE + count],' '); X X }; X refresh(); X X}/* clear_my_hand */ X X X Xvoid money(you,me,pot) X int you,me,pot; X X/* Display all the information about the current distribution of wealth */ X X{ X move(3,58); X printw("%6d",you); X move(12,61); X printw("%6d",pot); X move(20,58); X printw("%6d",me); X refresh(); X X}/*money */ X X X Xvoid show_winner(win) X int win; X X/* Declare the winner, after a hand is played */ X X{ X int pause; X X for(pause=0;pause<900000;pause++); X move(13,0); X if(win == -1) X printw("It is a draw, the pot stays. "); X else X printw("%s win. ",win?"I ":"You "); X X refresh(); X for(pause=0;pause<900000;pause++); X X}/* show_winner */ X X X Xvoid show_over_win(win) X int win; X X/* declare the over all winner, when all of a stake is lost, or no more */ X/* games are required */ X X{ X int pause; X X X clear_mid(); X move(9,0); X if(win == -1) X printw("It is a draw. "); X else X { X printw("%sthe over all winner of that game.", X win?"I am ":"You are "); X move(10,0); X if(win) X printw(" Now isn't that a pity!! "); X else X printw("Congratulations! But that was only ONE game."); X } X X refresh(); X X for(pause=0;pause<900000;pause++); X X}/* show_over_win */ X X X X Xvoid i_do(what) X int what; X X/* Computer declares its actions */ X X{ X int pause; X X move(13,0); X printw("I will "); X X switch (what) { X case 1 : printw("stay. "); X break; X case 2 : printw("drop my cards. "); X break; X case 3 : printw("call. "); X break; X case 4 : case 5 : case 6 : case 7 : case 8 : X printw("bet %2d. ",(5 * (what - 3))); X break; X default : printw("raise %2d. ",(5 * (what - 8))); X break; X } X X refresh(); X if(what == 1) X for(pause=0;pause<900000;pause++); X X}/* i_do */ X X X X Xint ano_yes_no(source) X int source; X X/* ask if another game is requred, and get a y/n answer */ X X{ X char reply; X X move(11,0); X printw("Do you want another go ? "); X move(11,25); X refresh(); X do X get_input(source,&reply); X while(reply != 'y' && reply != 'n'); X mvaddch(11,25,reply); X refresh(); X X return (reply == 'y'); X X}/* yes_no */ X X X X Xshow_inc(raising,source,amount) X int raising; X int source; X int *amount; X X/* get and display the user's bet increment */ X X{ X move (9,0); X printw("How much do you want to %s (1-5): ", X raising?"raise":"bet"); X refresh(); X get_increment(source,amount); X move(9,37); X printw("%2d",*amount); X refresh(); X X} X X X Xint choose_SDB(source,amount) X int source; X int *amount; X X/* ask the user if he wants to stay, drop or bet, and get the reply */ X X{ X char choice; X int response; X X move(13,0); X printw(" "); X refresh(); X move(9,0); X printw("Do you wish to Stay,Drop or Bet : "); X refresh(); X get_SDB(source,&choice); X move(9,34); X printw("%c",choice); X refresh(); X if(choice == 'b') X show_inc(0,source,amount); X switch (choice) { X case 's' : /* Staying */ X response = 1; X break; X case 'd' : /* dropping */ X response = 2; X break; X case 'b' : /* betting */ X response = (*amount/5) + 3;/* bet this */ X X }/*switch*/ X X return response; X X}/* choose SDB */ X X X X Xint choose_RCD(source,amount,turn) X int source; X int *amount; X int turn; X X/* ask user if he wants to raise, drop or call */ X X{ X char choice; X int response; X X move(9,0); X printw("%sDo you wish to %sDrop or Call : ", X (turn ==6)?" ":"",(turn ==6)?"":"Raise,"); X refresh(); X do X get_RCD(source,&choice); X while(turn == 6 && choice == 'r'); /* disallow raise on turn 6 */ X move(9,36); X printw("%c",choice); X refresh(); X if(choice == 'r') X show_inc(1,source,amount); X switch (choice) { X case 'c' : /* Staying */ X response = 3; X break; X case 'd' : /* dropping */ X response = 2; X break; X case 'r' : /* betting */ X response = (*amount/5) + 8; X X }/*switch*/ X X return response; X X}/* choose RCD */ X X X X Xclear_mid() X X{ X move(9,0); X printw(" "); X move(10,0); X printw(" "); X move(11,0); X printw(" "); X move(12,0); X printw(" "); X move(13,0); X printw(" "); X refresh(); X} X X X Xvoid inform_ante(pot) X int pot; X X{/* inform user that ante is required */ X X int pause; X X clear_mid(); X move (11,0); X printw("We ante%s. ",(pot > 10)?" again":""); X refresh(); X for(pause=0;pause < 900000;pause++); X clear_mid(); X X}/* inform ante */ X X X X/***********************************************/ X/* Following functions are for getting users */ X/* rejected cards. */ X/***********************************************/ X X Xask_which() X X X{ X X move(9,0); X printw("Which cards do you want to reject : "); X refresh(); X move(9,36); X refresh(); X X}/* ask which */ X X X Xdelete_line() X X/* delete the line of rejected cards */ X X{ X move(9,35); X printw(" "); X refresh(); X move(9,35); X refresh(); X X}/* delete line */ X X X Xshow_choice(choice,count) X char choice; X int count; X X/* Does computer choose to stay, drop, bet, raise or call ? */ X X{ X X int across; X X across = 35 + (count * 2); X X mvaddch(9,across,choice); X refresh(); X X}/* show choice */ X X X Xi_take(num) X int num; X X/* Computer declares how many cards it takes */ X X{ X int pause; X X move(11,0); X printw("I will take %d card%s ",num, X (num != 1)?"s.":"."); X refresh(); X for(pause = 0;pause < 900000;pause++); X move(11,0); X printw(" "); X refresh(); X X}/* i_take */ END_OF_FILE if test 11110 -ne `wc -c <'p_scr.c'`; then echo shar: \"'p_scr.c'\" unpacked with wrong size! fi # end of 'p_scr.c' fi if test -f 'p_strat.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'p_strat.c'\" else echo shar: Extracting \"'p_strat.c'\" \(13748 characters\) sed "s/^X//" >'p_strat.c' <<'END_OF_FILE' X#include "poker.h" X X/****************************************/ X/* p_strat.c strategies */ X/****************************************/ X/* */ X/* Hand value :- */ X/* */ X/* 20 : Royal Flush. */ X/* 19 : Straight Flush */ X/* 18 : 4 of a Kind */ X/* 17 : Full House */ X/* 16 : Flush */ X/* 15 : Straight */ X/* 14 : 3 of a Kind */ X/* 13 : 2 pair */ X/* 12 : 4 card straight flush */ X/* {11 : high pair */ X/* {10 : 4 card flush */ X/* 9 : 4 card straight */ X/* 8 : low pair */ X/* {7 : 3 card straight flush */ X/* {6 : 3 high card */ X/* 5 : inside straight` */ X/* {4 : 2 high cards */ X/* {3 : 3 card flush */ X/* */ X/* {2 : 3 card run */ X/* {1 : 1 high card */ X/* */ X/* a high card is >= 10 */ X/* */ X/****************************************/ X X/* These are the procedures that categorise the hand */ X Xflush flusher(); Xprile pairs(); Xrun runs(); Xhigh high_cards(); X X X Xprile priles; Xrun straight; Xflush flushes; Xhigh top_cards; Xdescribe res; X Xint hi_straight; X X X Xint strai_flush (stra,flus,length) X int *stra,*flus,length; X X/* If there is a run present, and a flush present, this decides whether */ X/* or not the same cards are involved in both, i.e. a straight flush */ X{ X int count; X int truth; X X X truth=1; X X for(count=0;count < length;count++) X if(stra[count] != flus[count]) X truth = 0; X X return truth; X X}/* strai_flush */ X X X X X Xvoid improve(keep,throw,numkept) X int *keep,*throw; X int numkept; X X/* given the cards used in a hand, locate those that need to be changed */ X X{ X int card_count,keep_count,throw_count; X int keeping; X X throw_count = 0; X for(card_count = 0;card_count < HAND_SIZE;card_count++) X { X keeping = 0; X for(keep_count = 0;keep_count < numkept;keep_count++) X if(keep[keep_count] == card_count) X keeping =1; X X if(!keeping) X throw[throw_count++] = card_count; X } X X X}/* improve */ X X X X Xint real_straight(hand) X X playing_card *hand; X X /* the straight algorithm is often wrong if there is a pair present */ X /* This one makes certain */ X X{ X int real; X int counter,ptr; X X real = 1; X counter =0; X ptr=straight.card[0] ; /* first card of straight */ X X X if(hand[ptr].face_value == 1 && X hand[HAND_SIZE - 1].face_value == 13) /* ace and king present */ X X ptr = straight.card[++counter]; /* look at next card */ X X do X { X if(hand[ptr].face_value >= hand[ptr+1].face_value) X real = 0; X X ptr++; X counter++; X } X while(counter < straight.length - 1); X X return real; X X X}/* real_straight */ X X X X Xvoid handle_prile(hand,deal) X X playing_card *hand; X int deal; X X/* This decides what to do with a hand, given that a pair is present */ X X{ X switch (priles.p_type) { X X /* Four of a kind */ X case 256 : res.hand_value = 18; X if(hand[priles.cards[0]].face_value < 10) X { X res.reject = 1; X improve(priles.cards,res.exchange,4); X } X else X res.reject = 0; X break; X X /* Full house */ X case 32 : case 64 : res.hand_value = 17; X res.reject = 0; X break; X X /* Three of a kind */ X case 16 : res.hand_value = 14; X res.reject = 2; X improve(priles.cards,res.exchange,3); X break; X X /* Two pair */ X case 8 : res.hand_value = 13; X res.reject = 1; X improve(priles.cards,res.exchange,4); X break; X X /* One pair */ X case 4 : if(flushes.flush_of == 4 && X X deal && /* only continue if first deal */ X X !straight.open_str && X straight.length == 4 && X real_straight(hand) ) X X /* is there also a 4 straight_flush ? */ X /* if so it is a better hand to improve */ X /* on first deal than any pair */ X X { X res.hand_value=12; X res.reject = 1; X improve(flushes.cards,res.exchange,4); X } X else /* no 4 sra_flush */ X { X if(hand[priles.cards[0]].face_value < 10 && X hand[priles.cards[0]].face_value > 1 ) X X {/* have a low pair but others are better if still */ X /* improving hand.*/ X X if(flushes.flush_of == 4 && deal) X { X res.hand_value = 10; X res.reject = 1; X improve(flushes.cards,res.exchange,4); X } X else X { X if(straight.length == 4 && X deal && X !straight.open_str && X real_straight(hand)) X X { X res.hand_value = 9; X res.reject = 1; X improve(straight.card,res.exchange,4); X } X else /* only a low pair */ X { X res.hand_value = 8; X res.reject = 3; X improve(priles.cards,res.exchange,2); X } X } X X X } X else /* hi pair */ X { X if(flushes.flush_of == 4) X { X res.hand_value = decision_A(deal); X if(res.hand_value == 11) X { X res.reject = 3; X improve(priles.cards,res.exchange,2); X } X else /* is 10 */ X { X res.reject = 1; X improve(flushes.cards,res.exchange,4); X } X } X else /* only a high pair */ X { X res.hand_value = 11; X res.reject = 3; X improve(priles.cards,res.exchange,2); X } X X } X } X X }/*switch*/ X X X}/* prile */ X X X Xvoid handle_no_prile(hand,first_deal) X playing_card *hand; X int first_deal; X X{ X if(hi_straight) X if(flushes.flush_of == 5) X { X if(hand[0].suit == 'H') /* Royal flush */ X { X res.hand_value = 20; X res.reject = 0; X } X else /* just hi_straight */ X { X res.hand_value = 19; X res.reject = 0; X } X } X else /* just hi straight */ X { X res.hand_value = 15; X res.reject = 0; X } X else X if(flushes.flush_of == 5) X { X res.hand_value = 16; X res.reject = 0; X } X else X X /* all hands that could win with no pairs */ X /* have been found at this point, the */ X /* following is only needed if improvements */ X /* can be made, so only do on second deal. */ X X if(first_deal) X { X X if(flushes.flush_of == straight.length && X strai_flush(flushes.cards,straight.card,straight.length)) X X switch (straight.length) X { X case 4 : res.hand_value = 12; X res.reject = 1; X improve(flushes.cards,res.exchange,4); X break; X case 3 : if(top_cards.number == 3) /* 3 hi cards */ X { X res.hand_value = decision_B(); X res.reject = 2; X if(res.hand_value == 7) /* 3 str flush */ X improve(flushes.cards,res.exchange,3); X else X improve(top_cards.cards,res.exchange,3); X } X else /* just 3 str flush */ X { X res.hand_value = 7; X res.reject = 2; X improve(flushes.cards,res.exchange,3); X }/* end case 3 */ X X }/* end switch */ X X else /* no straight flushes present */ X if(flushes.flush_of==4) X { X res.hand_value = 10; X res.reject = 1; X improve(flushes.cards,res.exchange,4); X } X else X if(straight.length == 4 && !straight.open_str) X { X res.hand_value = 9; X res.reject = 1; X improve(straight.card,res.exchange,4); X } X else X if(top_cards.number == 3) X { X res.hand_value = 6; X res.reject = 2; X improve(top_cards.cards,res.exchange,3); X } X else X if(straight.open_str) X { X res.hand_value = 5; X res.reject = 1; X improve(straight.card,res.exchange,4); X } X else X if(top_cards.number == 2) X { X if(flushes.flush_of == 3) X { X res.hand_value = decision_C(); X res.reject = ((res.hand_value == 4)?3:2); X improve((res.hand_value == 4)?top_cards.cards: X flushes.cards, X res.exchange, X (HAND_SIZE - res.reject)); X } X else /* just 2 hi cards */ X { X res.hand_value = 4; X res.reject = 3; X improve(top_cards.cards,res.exchange,2); X } X }/* end 2 hi cards */ X else X if(flushes.flush_of == 3) X { X res.hand_value = 3; X res.reject = 2; X improve(flushes.cards,res.exchange,3); X } X else X if(straight.length == 3) X { X if(top_cards.number == 1) X { X res.hand_value=decision_D(); X res.reject=((res.hand_value == 2)?2:3); X improve((res.hand_value == 2)?straight.card: X top_cards.cards, X res.exchange, X (HAND_SIZE - res.reject)); X } X else X { X res.hand_value=2; X res.reject=2; X improve(straight.card,res.exchange,3); X } X } X else X if(top_cards.number == 1) X { /* only 1 high card */ X res.hand_value = 1; X res.reject = 3; X improve(top_cards.cards,res.exchange,2); X } X else X { /* nothing */ X res.hand_value = 0; X res.reject = 3; X improve(top_cards.cards,res.exchange,2); X } X X }/* first_deal check */ X X X}/* no prile */ X X X X Xdescribe evaluate(hand,first_deal) X playing_card *hand; X int first_deal; X X/* The hand evaluation routine */ X X{ X X flushes = flusher(hand); X X hi_straight = high_straight(hand); X X priles = pairs(hand); X X if(first_deal && !hi_straight) X /* not needed second deal, as can not */ X /* improve any more or if hi straight found */ X if(priles.p_type <= 4) X X straight = runs(hand,(priles.p_type == 4),priles.cards[0]); X X top_cards = high_cards(hand); X X res.hand_value = 0; X res.reject = 0; X X X X if (priles.p_type > 2) X X handle_prile(hand,first_deal); X X else X X handle_no_prile(hand,first_deal); X X if(!first_deal) /* on 2nd deal all other Hv's are irrelevant */ X if(res.hand_value <13 && res.hand_value != 11 && res.hand_value !=8) X res.hand_value = 0; X X X return res; X X}/* absolute */ X X X X Xint det_winner(my_val,opp_val,my_hand,your_hand) X int my_val,opp_val; X playing_card *my_hand, *your_hand; X X/* determine the winner, particularly when the hand values are the same */ X X{ X int winner; X int my_hi,your_hi,my_lo,your_lo,count; X X winner = -1; X X if(my_val != opp_val) X winner = (my_val > opp_val); X X else X switch (my_val) { /* are equal */ X X case 19 : case 15 : /* straights */ X if(my_hand[HAND_SIZE - 1].face_value == X your_hand[HAND_SIZE - 1].face_value) /* hi cards equal */ X { X if(my_hand[HAND_SIZE - 1].face_value == 13) X if(my_hand[0].face_value != X your_hand[0].face_value) X X /* are the runs 9TKQK or ATJQK */ X X { X if(my_hand[0].face_value == 1) X winner = 1; /* i have AKQJT */ X X if(your_hand[0].face_value == 1) X winner = 0; /* you have AKQJT */ X } X } X else X X winner = my_hand[HAND_SIZE - 1].face_value > X your_hand[HAND_SIZE - 1].face_value; X break; X case 18 : case 14 : case 17 : X /* compare third cards of hands */ X /* full houses determined by the 3ok present */ X X if(my_hand[2].face_value == 1) X winner = 1; /* me */ X else X if(your_hand[2].face_value == 1) X winner = 0; /* you */ X else X winner = (my_hand[2].face_value > X your_hand[2].face_value); X break; X X case 13 : /* 2 pair */ X /* re-evaluate the pairs present */ X X priles = pairs(my_hand); X my_hi = my_hand[priles.cards[2]].face_value; X my_lo = my_hand[priles.cards[0]].face_value; X if(my_lo == 1) /* aces */ X { X my_lo = my_hi; X my_hi = 14;/* ace == 14 */ X } X X priles = pairs(your_hand); X your_hi = your_hand[priles.cards[2]].face_value; X your_lo = your_hand[priles.cards[0]].face_value; X if(your_lo == 1) /* aces */ X { X your_lo = your_hi; X your_hi = 14; X } X X if (my_hi != your_hi) X winner = (my_hi > your_hi); X else X if(my_lo != your_lo) X winner = (my_lo > your_lo); X X else /* 2 pairs the same */ X /* compare hi cards */ X X for(count=HAND_SIZE -1;(count >= 0 && winner == -1); X count ++) X X if(my_hand[count].face_value != X your_hand[count].face_value) X winner = (my_hand[count].face_value > X your_hand[count].face_value); X X break; X X case 11 : case 8 : /* pairs */ X X /* First get the value of the pair */ X X priles = pairs(my_hand); X my_hi = my_hand[priles.cards[0]].face_value; X X priles = pairs(your_hand); X your_hi = your_hand[priles.cards[0]].face_value; X X my_hi += (13 * (my_hi == 1)); X your_hi += (13 * (your_hi == 1)); X /* aces become 14 */ X X if(my_hi != your_hi) X winner = (my_hi > your_hi); X X else /* pairs the same */ X /* compare hi cards */ X X for(count=HAND_SIZE -1;(count >= 0 && winner == -1); X count ++) X X if(my_hand[count].face_value != X your_hand[count].face_value) X X winner = (my_hand[count].face_value > X your_hand[count].face_value); X X break; X X default : X if(my_hand[0].face_value != your_hand[0].face_value) X /* check for aces */ X if(my_hand[0].face_value == 1) X winner = 1; /* i have ace */ X else X if(your_hand[0].face_value == 1) X winner = 0; /* you have ace */ X X if(winner == -1) X X for(count=HAND_SIZE -1 ; count >= 0;count--) X if (my_hand[count].face_value != X your_hand[count].face_value) X X { X winner = (my_hand[count].face_value > X your_hand[count].face_value) ; X break; /* from for loop */ X } X X X }/* switch */ X X X return winner; X X}/* det_winner */ END_OF_FILE if test 13748 -ne `wc -c <'p_strat.c'`; then echo shar: \"'p_strat.c'\" unpacked with wrong size! fi # end of 'p_strat.c' fi if test -f 'poker.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'poker.c'\" else echo shar: Extracting \"'poker.c'\" \(8381 characters\) sed "s/^X//" >'poker.c' <<'END_OF_FILE' X /************************************************/ X /* */ X /* Five card Draw Poker */ X /* */ X /* Written by Nic Smith (csx43@uk.ac.kl.seq1) */ X /* As a final year project to illustrate */ X /* intelligent game play. */ X /* */ X /************************************************/ X /* */ X /* The files that need to be compiled together */ X /* and there main uses are : */ X /* */ X /* poker.h : include file for structure */ X /* definitons and configuration */ X /* locating rules. */ X /* poker.c : top level of code that pulls */ X /* together all the main procedures*/ X /* p_deal.c : handles the shuffling, sorting */ X /* and dealing of the cards. */ X /* p_hand.c : hand recognition routines. */ X /* p_strat.c: the strategy used to decide which*/ X /* hand type to play with, and how */ X /* to improve the given hand. */ X /* input.c : accepts most input from the */ X /* opponent. */ X /* p_decide.c: makes decisions based on */ X /* imperfect information, such as */ X /* call/raise etc. decisions made */ X /* using probabilities in 'percent'*/ X /* array. */ X /* p_scr.c : screen handling functions. This */ X /* uses the 'curses' library */ X /* poker_rules : Text file that contains the */ X /* rules and instructions for the */ X /* game. */ X /* */ X /************************************************/ X X#include "poker.h" X#include <signal.h> X#define source 0 X/* This is the file descriptor for input i.e. terminal */ X/* Most procedures can be reused to convert the program */ X/* to machine-machine play. This can be used to improve */ X/* and test the strategy. */ X X#define init_stake 250 X/* obviously the initial stake given to each player */ X X#define VOID 0 X#define STAY 1 X#define DROP 2 X#define CALL 3 X X#define flag int X X/********************************/ X/* */ X/* possible responses : */ X/* */ X/* 1 = stay */ X/* 2 = drop */ X/* 3 = call */ X/* 4-8 = bet 1-5 resp. */ X/* 9-13 = raise 1-5 resp. */ X/* */ X/********************************/ X Xplaying_card my_hand[HAND_SIZE], your_hand[HAND_SIZE]; X Xint your_stake,my_stake,pot; Xint action,last_action; Xint amount,last_bet,total_bet; Xint turn; Xflag i_go_first,whos_go,winner,first_deal; Xflag ante_again; X X Xdescribe mine,yours; X X Xlong rand(); Xdescribe evaluate(); X X X X Xint SDB(who) X flag who; X X{/* stay, drop or bet */ X /* used for returning both computer and opponent decisions */ X /* it will either call upon the user input routines are the*/ X /* decision making routines. */ X X int response; X X if(!who) /* i.e opponent go */ X response = choose_SDB(source,&amount); X else X { X X if (stay(mine.hand_value,last_action, X first_deal,(my_stake - init_stake))) X response = STAY; X else X { X if(drop(first_deal,yours.reject,mine.hand_value, X last_action,(my_stake - init_stake),turn)) X X response = DROP; X X else /* bet */ X response = 3 + increase(mine.hand_value,first_deal, X yours.reject); X } X i_do(response); X X } X X return response; X X X}/* SDB */ X X X X Xint RCD(who) X flag who; X X{ /* raise call or drop */ X /* used for returning both computer and opponent decisions */ X /* it will either call upon the user input routines are the*/ X /* decision making routines. */ X X int response; X X if(!who) X response = choose_RCD(source,&amount,turn); X else X X { X if(drop(first_deal,yours.reject,mine.hand_value, X last_action,(my_stake - init_stake),turn)) X response = DROP; X X else X { X if(calling(mine.hand_value,turn,first_deal,yours.reject)) X response = CALL; X X else /* raise */ X response = 8 + increase(mine.hand_value,first_deal, X yours.reject); X } X i_do(response); X X } X X return response; X X}/*RCD*/ X X X Xvoid ante() X X{/* ante is 5 */ X /* used for intial ante and re-ante, so does not reset pot */ X X your_stake -= 5; X my_stake -= 5; X pot += 10; X X inform_ante(pot); X X}/* ante */ X X X X Xmain() X X{ X int another_go; X X X srand(getpid()); X X i_go_first = rand()%01; /* a 1 means the computer goes first, a 0 means */ X /* opponent goes first */ X X another_go = 1; /*set to ensure that at least one game is played */ X X initialise_screen(); X title_screen(); /* can be altered to show owners mail address */ X instruct(); /* ask if instructions are required, and display if */ X /* necessary. The full pathname for poker_rules */ X /* must be set in here (p_scr.c). */ X initialise_cards(); X X X do X { X draw_screen(); X X your_stake=my_stake=300; X pot =0; X X do X { X new_deal(); X X deal_two_hands (your_hand,my_hand); X X clear_my_hand(); /* remove computer's old hand from screen */ X X show_hand(your_hand,0); /* display hand at top of screen */ X X action = VOID; X ante_again =0; X ante(); X X money(your_stake,my_stake,pot); /* update money situation on screen */ X X for(first_deal =1;first_deal >= 0 && !ante_again && action!=DROP; X first_deal--) X X { X last_bet=0; X total_bet=0; X last_action=VOID; X whos_go = i_go_first; X X mine = evaluate(my_hand,first_deal); X X X turn=1; /* there is a limited number of betting turns allowed */ X X action = SDB(whos_go); X X if(action == STAY) X { X turn ++; X whos_go = !whos_go; X last_action = STAY; X action = SDB(whos_go); X if(action == STAY) X if(first_deal) X ante_again = 1; X else X action = CALL; X } X if(!ante_again) X { X while(action!=DROP && action != CALL) X { X if (whos_go) /* my_go */ X amount = (action > 8)?((action - 8) * 5): X ((action - 3) * 5); X total_bet = amount + last_bet; X last_bet = amount; X pot += total_bet; X if(whos_go) X my_stake -= total_bet; X else X your_stake -= total_bet; X money(your_stake,my_stake,pot); X turn++; X whos_go = !whos_go; X last_action = action; X action = RCD(whos_go); X } /* while */ X X if(action == DROP) X { X if(whos_go) X your_stake += pot; X else X my_stake += pot; X pot = 0; X money(your_stake,my_stake,pot); X winner = !whos_go; X } X if(action == CALL) X { X if(whos_go) X my_stake -= last_bet; X else X your_stake -= last_bet; X pot += last_bet; X money(your_stake,my_stake,pot); X if(first_deal) X { X re_deal(my_hand,mine); X i_take(mine.reject); X get_user_changes(source,&yours.reject, X yours.exchange); X X re_deal(your_hand,yours); X show_hand(your_hand,0); X } X else X { X yours = evaluate(your_hand,first_deal); X winner = det_winner(mine.hand_value,yours.hand_value, X my_hand,your_hand); X } X X }/* call */ X }/* not ante again */ X }/*for*/ X if(!ante_again) X { X X if(action != DROP) X show_hand(my_hand,1); X X show_winner(winner); X if(winner == 1) X my_stake += pot; X if(winner == 0) X your_stake += pot; X if(winner != -1) X pot = 0; X X money(your_stake,my_stake,pot); X X if((my_stake <= 0 || your_stake <= 0) && !ante_again) X { X if(my_stake == your_stake) X winner = -1; X else X winner = my_stake > your_stake; X show_over_win(winner); X } X X another_go = ano_yes_no(source); X X i_go_first = !i_go_first; X X } X }/* 2nd do */ X while((my_stake > 0 && your_stake > 0) && (ante_again || another_go)); X X X }/* first do */ X while(another_go); X X if(my_stake > 0 && your_stake > 0) X { X if(my_stake == your_stake) X winner = -1; X else X winner = my_stake > your_stake; X show_over_win(winner); X } X Xdie(); X}/* end of main */ END_OF_FILE if test 8381 -ne `wc -c <'poker.c'`; then echo shar: \"'poker.c'\" unpacked with wrong size! fi # end of 'poker.c' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0