poker- how to compare hands

Started by
18 comments, last by bkt 19 years, 1 month ago
If you were making a poker game, what would be the best way to check one hand against the other hand if the game was texas hold'em? Assume that the cards are in an array A-2-3..Q-K(clubs)A-2-3..Q-K(spades)A-2-3..Q-K(diamonds)A-2-3..Q-K(heart). If there is a better way to structure the data for these comparisons, I'm open to suggestions. I've never made a card based game, so I want to make a game with the fastest response time possible. I want to make this a network game that will have a form of a ranking system for regular 10 man tables, but that's a long way from now..
Advertisement
Check the cards present against possible hands, then assign a point value based on the rank of the hand that it compares to. Whoever has the higher point value winds.
Disclaimer: "I am in no way qualified to present advice on any topic concerning anything and can not be held responsible for any damages that my advice may incurr (due to neither my negligence nor yours)"
I guess I should have been more clear, I need to know how to figure out the what hand the person has as well. That is the part I would like to know about the most.
Funnily enough I've been thinking about how you'd evaluate a poker hand recently too.

There are two separate things here (just to make sure we're all on the same page):

(Let's assume we're talking about Texas Holdem)

1) Evaluate a hand based on the cards in play - find out what it (currently) is - eg. Flush, High Card etc and rank it based on this (eg 100%=Royal Flush)
2) Evaluate a hand based on the possibility of improvement. For example you currently have 2 clubs in your hand and 2 clubs from the flop - what is the probability of improvment to a Flush etc

Number 2 can also be used to find out what 'the nuts' is - if you just gave it the community cards.

I haven't thought too much about number 2 yet - but I have some ideas on number 1. Which are you interested in?
It should just randomly throw out cards, not have a percentage to hit a hand like a flush or a straight.

Example, have a multidimensioan array of size 52 for every card, representing all cards from each suit and if they are in use, or something.

So then you just deal to each player a card and continue clock-wise around the table until every player has 2 cards. Then, just discard a randomly generated card using the same method and not assigning it to a current player's ID, but instead assigning it to MUCK ID.

Works well and makes sure you don't have duplicates or rigging.

EDIT: This might become fairly inefficient if it generates a random int between 0 and 51, and keeps picking a number that has already been generated, so another card has to be picked.
There are 10 types of people in the world. Those who understand binary, and those who don't.
The 100%, I believe, was meant to indicate that a royal flush beats all other hands. It doesn't say anything about the probability of getting such a hand (which is, for reference, 4 / (52 choose 5)).

Honestly, I wouldn't worry about speed for the moment. You're unlikely to be doing anything very processor-intensive with the rest of the game as it is; this isn't exactly the latest 3D FPS. Work on making an accurate game first. Then run a profiler on your code to see what parts need to be optimized, if any. Only then should you really start worrying about speed. In the meantime, just don't make dumbassed algorithm decisions.
Jetblade: an open-source 2D platforming game in the style of Metroid and Castlevania, with procedurally-generated levels
Oh, I gotcha. Sorry for the misunderstanding.
There are 10 types of people in the world. Those who understand binary, and those who don't.
Here's what I'd do Each card has these identifiers when your calculating

int hand
int power

so if you have a Royal Flush you'd have a hand of 100.
If you have four of a kind you'd have a hand of 90
if you have a straight flush you'd have a hand of 80.

and so on (I don't know all the hands so just give them divisions of 10 and makes sure to do a "has no hand" at 0. then for power

If you have a Royal Flush (assuming all suits are the same) give power of 13.
If you have a four of a kind then Power=rank of card. (so 4 2s would get a power of 2 and 4 10s would get a power of 10, because a 4 10s beat a 4 2s)
For flushes and straights you take the high card.

Then you compare the hands, if you have the same hand you check the power.

This CAN fail you when the high cards are exactly the same, so maybe you should use power[5] so you can compare all five cards, in flushes but that's another story.
Don't forget kickers!

After all, AAAKQ beats AAAQJ

sourceforge has a poker library that can handle all of the stuff for you if you'd like.

also, here's code I've written to do the same thing [albeit for Omaha Hi/Lo, but the high test is identical to Hold Em]:
//// omahasim.cc // // Simple brute force app to calculate winning percentages of hands in the//  poker game Omaha hi/lo.//#include <fstream>#include <iostream>#include <stdlib.h>#include <string.h>#ifdef	_WIN32	#include <time.h>#else	#include <sys/time.h>#endif#include <stdio.h>long	cmdlen=512;//int	logging=1;//char	*logname="omahasim.log";int	logging=0;char	*logname="";#include "vine.h"vine            *vinetocharvine(vine *inv){if (inv->type==CMD){return(inv->clone());}}#define		T	10#define		J	11#define		Q	12#define		K	13#define		A	14char	*cardletters[]={"","","2","3","4","5","6","7","8","9","T","J","Q","K","A"};enum	suits	{C,H,D,S};char	*suitletters[]={"c","h","d","s"};enum	hands	{KICKER,PAIR,TRIPS,QUADS,STRAIGHT,LOW};char	*handchar[]={"kicker","pair","trips","quads","straight","low"};#define		DEFAULTPLAYERS	9#define		DEFAULTDEALS	10#define		DEFAULTGAMES	1000unsigned short	deck[52];long		resultcounter[10];	// hands + flush + fh + strfl + 2p + lowint		players=DEFAULTPLAYERS;int		deals=DEFAULTDEALS;int		games=DEFAULTGAMES;char    *usage=" Usage: omahasim [-p {# of players (2-9)}] [-s {# of simulations}] [-g {# of games per simulation}]\n\n";void	initdeck		();void	resetcounter		();void	vinecat			(vine **);void	sorthands		(vine **);vine	*omahahigh		(struct omahahole *, struct community *);vine	*cardstohands		(vine **);vine	*cardstolowhands	(vine **);int	cmphands		(vine *, vine *);void	handkiller		(vine *);void	winner			(vine **);void	winnerlow		(vine **);void	parsecli		(int,char **);void		initdeck(){for (int x=0;x<52;x++){	deck[x]=0;}}void		resetcounter(){for (int x=0;x<10;x++){	resultcounter[x]=0;}}struct  card{        suits   suit;        short   rank;           // 2-14        card    (short inr, suits ins){                suit=ins;                rank=inr;		deck[ins*13+inr-2]=1;        }	card(){		suit=C;		rank=0;	}	~card(){		deck[suit*13+rank-2]=0;	}        vine    *cardtoa(){                char *tmp;                tmp=(char *)malloc(cmdlen);                bzero(tmp,cmdlen);                strcat(tmp,cardletters[rank]);                strcat(tmp,suitletters[suit]);                return(new vine(tmp));        }};struct	phand:	public	card{	hands		hand;	unsigned short	flushflag;	phand(hands inh,unsigned short inff,short inr,suits ins):card(inr,ins){		hand=inh;		flushflag=inff;	}	phand(hands inh,unsigned short inff,card *inc){		suit=inc->suit;		rank=inc->rank;		hand=inh;		flushflag=inff;	}	sout(){		vine *v=cardtoa();		cout << handchar[hand] << " ";		if (flushflag){			cout << "flush ";		}		v->sout();		v->nuke(&v);	}		};	card	*drawcard(){//// Deal a card from the deck and return it.//// WARNING: dealing from an empty deck will lead to inf-loop. //  Shouldn't be a problem for standard poker.//	suits	rs;	short	rr;	int	x;		while (1){		//		// NOTE: slight bug here. rand() sucks, and will produce decidedly unrandom results		//  should the suit be done seperately from the rank.		//		//		x=rand()%52;		rs=(suits)x/13;		rr=x%13;		//rs=(suits)rand()%4;		//rr=rand()%13;				if (!deck[rs*13+rr]){			return(new card(rr+2,rs));		}	}}struct	omahahole{	card	*h1;	card	*h2;	card 	*h3;	card	*h4;	omahahole(){		h1=drawcard();		h2=drawcard();		h3=drawcard();		h4=drawcard();	}	~omahahole(){		delete h1;		delete h2;		delete h3;		delete h4;	}	vine	*holetoa(){		vine	*v=0;		(h1->cardtoa())->bottom(&v);		(h2->cardtoa())->bottom(&v);		(h3->cardtoa())->bottom(&v);		(h4->cardtoa())->bottom(&v);		vinecat(&v);		return(v);	}};	struct	community{	card    *h1;        card    *h2;        card    *h3;        card    *h4;	card	*h5;        community(){                h1=drawcard();                h2=drawcard();                h3=drawcard();                h4=drawcard();		h5=drawcard();        }        ~community(){                delete h1;                delete h2;                delete h3;                delete h4;		delete h5;        }        vine    *holetoa(){                vine    *v=0;                (h1->cardtoa())->bottom(&v);                (h2->cardtoa())->bottom(&v);                (h3->cardtoa())->bottom(&v);                (h4->cardtoa())->bottom(&v);		(h5->cardtoa())->bottom(&v);                vinecat(&v);                return(v);        }};vine	*omahahigh(omahahole *inoh, community *inc){//// Send an omaha hand through the checker to determine player's best cards.//vine	*v,*max=0;card	*oh[4];card	*co[5];phand	*h;int	i[5];int	maxx[5];oh[0]=inoh->h1;oh[1]=inoh->h2;oh[2]=inoh->h3;oh[3]=inoh->h4;co[0]=inc->h1;co[1]=inc->h2;co[2]=inc->h3;co[3]=inc->h4;co[4]=inc->h5;for (i[0]=0;i[0]<3;i[0]++){	for (i[1]=i[0]+1;i[1]<4;i[1]++){		for (i[2]=0;i[2]<3;i[2]++){			for (i[3]=i[2]+1;i[3]<4;i[3]++){				for (i[4]=i[3]+1;i[4]<5;i[4]++){					v=0;					(new vine(CARD,oh[i[0]]))->bottom(&v);					(new vine(CARD,oh[i[1]]))->bottom(&v);					(new vine(CARD,co[i[2]]))->bottom(&v);					(new vine(CARD,co[i[3]]))->bottom(&v);					(new vine(CARD,co[i[4]]))->bottom(&v);					v=cardstohands(&v);					if (1==cmphands(v,max)){						handkiller(max);						max->nuke(&max);						max=v;									}else{						handkiller(v);						v->nuke(&v);					}				}			}		}		}}return(max);}vine	*omahalow(omahahole *inoh, community *inc){//// Send an omaha hand through the checker to determine player's best low cards.//vine    *v,*max=0;card    *oh[4];card    *co[5];phand   *h;int     i[5];int     maxx[5];vine	*om;oh[0]=inoh->h1;oh[1]=inoh->h2;oh[2]=inoh->h3;oh[3]=inoh->h4;co[0]=inc->h1;co[1]=inc->h2;co[2]=inc->h3;co[3]=inc->h4;co[4]=inc->h5;for (i[0]=0;i[0]<3;i[0]++){        for (i[1]=i[0]+1;i[1]<4;i[1]++){                for (i[2]=0;i[2]<3;i[2]++){                        for (i[3]=i[2]+1;i[3]<4;i[3]++){                                for (i[4]=i[3]+1;i[4]<5;i[4]++){                                        v=0;					om=max;                                        (new vine(CARD,oh[i[0]]))->bottom(&v);                                        (new vine(CARD,oh[i[1]]))->bottom(&v);                                        (new vine(CARD,co[i[2]]))->bottom(&v);                                        (new vine(CARD,co[i[3]]))->bottom(&v);                                        (new vine(CARD,co[i[4]]))->bottom(&v);                                        v=cardstolowhands(&v);					if (v){					if (!max){						max=v;					}else{                                        if (-1==cmphands(v,max)){						handkiller(max);                                                max->nuke(&max);                                                max=v;                                        }else{                                                handkiller(v);                                                v->nuke(&v);                                        }					}					if (om && !max){						cout << "max existed, then nulled.\n";					}					}                                }                        }                }        }}return(max);}void	result(vine *inhand){//// Take high hand and add result-counter//phand	*h;vine	*v;if (!inhand){	return;}h=(phand *)inhand->data;if (h->hand==STRAIGHT && h->flushflag){	resultcounter[7]++;	return;}if (h->flushflag){	resultcounter[5]++;	return;}if (h->hand==TRIPS){	for (v=inhand;v;v=v->next){		h=(phand *)v->data;		if (h->hand==PAIR){			// then it's a boat, not just trips.			resultcounter[6]++;			return;		}	}	resultcounter[TRIPS]++;	return;}if (h->hand==PAIR){	v=inhand->next->next;	h=(phand *)v->data;	if (h->hand==PAIR){		resultcounter[8]++;		return;	}	resultcounter[PAIR]++;	return;}if (h->hand==LOW){	resultcounter[9]++;	return;}resultcounter[h->hand]++;}void	printresults(){//// Print results of resultcounter//long	total;total=0;for (int x=0;x<9;x++){	total+=resultcounter[x];}cout 	<< "high only:  " << resultcounter[0] << "(" << ((float)resultcounter[0]/total)*100 << "%)\n"      	<< "1p:         " << resultcounter[1] << "(" << ((float)resultcounter[1]/total)*100 << "%)\n" 	<< "2p:         " << resultcounter[8] << "(" << ((float)resultcounter[8]/total)*100 << "%)\n"    	<< "trips:      " << resultcounter[2] << "(" << ((float)resultcounter[2]/total)*100 << "%)\n" 	<< "quads:      " << resultcounter[3] << "(" << ((float)resultcounter[3]/total)*100 << "%)\n" 	<< "straight:   " << resultcounter[4] << "(" << ((float)resultcounter[4]/total)*100 << "%)\n" 	<< "flush:      " << resultcounter[5] << "(" << ((float)resultcounter[5]/total)*100 << "%)\n" 	<< "full house: " << resultcounter[6] << "(" << ((float)resultcounter[6]/total)*100 << "%)\n"	<< "str flush:  " << resultcounter[7] << "(" << ((float)resultcounter[7]/total)*100 << "%)\n"	<< "low:        " << resultcounter[9] << "(" << ((float)resultcounter[9]/total)*100 << "%)\n";} 			vine	*cardstolowhands(vine **inv){//// convert vine of card to a vine of poker hands [low, assume 8 min]//int	lowtotal[8];vine    *v,*w;vine	*rtn=0;card    *c1,*c2;int	y;int 	x;for (x=0;x<8;x++){	lowtotal[x]=0;}if (!*inv){        return(0);}if ((*inv)->count()!=5){        return(0);}for (v=*inv;v;v=v->next){	c1=(card *)v->data;	if (c1->rank==A){		lowtotal[0]++;	}else{		if (c1->rank<=8){			lowtotal[c1->rank-1]++;		}else{			(*inv)->nuke(inv);               		 return(0);		}	}}y=0;for (x=0;x<8;x++){	y+=lowtotal[x];}if (y!=5){	(*inv)->nuke(inv);	return(0);}for (x=0;x<8;x++){	if (lowtotal[x]>1){		(*inv)->nuke(inv);		return(0);	}}for (v=*inv;v;v=v->next){	c1=(card *)v->data;	if (c1->rank==A){		c1->rank=1;	}	(new vine(HAND,new phand(LOW,0,c1)))->top(&rtn);	if (c1->rank==1){		c1->rank=A;	}}(*inv)->nuke(inv);sorthands(&rtn);return(rtn);}						vine	*cardstohands(vine **inv){//// convert vine of card to a vine of poker hands//vine	*v,*w;vine	*rtn=0;int	p=0;int	f=0;card	*c1,*c2;int	s[5];int	x;if (!*inv){	return(0);}if ((*inv)->count()!=5){	return(0);}// first, check for flushv=*inv;c1=(card *)v->data;for (v=(*inv)->next;v;v=v->next){	c2=(card *)v->data;	if (c2->suit==c1->suit){		f++;	}}if (f==4){	f=1;}else{	f=0;}// next, run through cardsfor (v=(*inv)->next;v;v=v->next){	p=0;	c1=(card *)v->data;	for (w=*inv;w;w=w->next){		if (w!=v){			c2=(card *)w->data;			if (c2->rank==c1->rank){				p++;			}		}	}	(new vine(HAND,new phand((hands)p,f,c1)))->top(&rtn);}// next check for straights.for (v=(*inv)->next;v;v=v->next){	for (x=0;x<5;x++){s[x]=0;}	s[0]=1;	c1=(card *)v->data;	for (w=*inv;w;w=w->next){                if (w!=v){			c2=(card *)w->data;			if (c1->rank==A){				if (c2->rank-1<5 && c2->rank-1>0){					s[c2->rank-1]++;				}			}else{				if (c2->rank-c1->rank<5 && c2->rank-c1->rank>0){					s[c2->rank-c1->rank]++;				}			}		}	}	if (s[0] && s[1] && s[2] && s[3] && s[4]){		(new vine(HAND,new phand(STRAIGHT,f,c1)))->top(&rtn);	}}(*inv)->nuke(inv);sorthands(&rtn);return(rtn);}void	sorthands(vine **inv){//// Sort hands according to hand//phand	*h1, *h2;vine	*v, *vv;int	flag;flag=1;//cout << "in sort\n";while(flag){	flag=0;	for (v=*inv;(v && !flag);v=v->next){		vv=v->next;		if (vv){			h1=(phand *)v->data;			h2=(phand *)vv->data;			if (h2->hand>h1->hand){				v->swapwith(vv,inv);				flag=1;			}else if (h2->hand==h1->hand && h2->flushflag==1 && h1->flushflag==0){				v->swapwith(vv,inv);                        	flag=1;			}else if (h2->hand==h1->hand && (h2->rank > h1->rank)){				v->swapwith(vv,inv);                        	flag=1;			}		}	}}}int	cmphands(vine *a,vine *b){//// compare hands//// 0 if equal, 1 if a, -1 if b//// Returns the "better" hand, so reverse for low tests.//  [and ensure both hands exist...]//phand	*h1,*h2,*ht;vine	*v,*vv;if (!b && !a){	return(0);}if (!b){	return(1);}if (!a){	return(-1);}h1=(phand *)a->data;h2=(phand *)b->data;//cout << "in cmphands\n";// Straight flushesif (h1->hand==STRAIGHT && h1->flushflag==1){	if (h2->hand!=STRAIGHT || h2->flushflag==0){		return(1);	}	if (h1->rank > h2->rank){		return(1);	}else if(h1->rank==h2->rank){		return(0);	}else{		return(-1);	}}if (h2->hand==STRAIGHT && h2->flushflag==1){        return(-1);}// Quadsif (h1->hand==QUADS){	if (h2->hand!=QUADS){		return(1);	}	if (h1->rank > h2->rank){		return(1);	}else{		return(-1);	}}if (h2->hand==QUADS){	return(-1);}// Flushesif (h1->flushflag==1){	if (h2->flushflag==1){		v=a;		vv=b;		while (v){			h1=(phand *)v->data;			h2=(phand *)vv->data;			if (h1->rank>h2->rank){				return(1);			}else if (h2->rank>h1->rank){				return(-1);			}						v=v->next;				vv=vv->next;		}		return(0);	}else if (h2->hand!=TRIPS){		return(1);	}else{		// possible full house beating the flush		for (v=b;v;v=v->next){			ht=(phand *)v->data;			if (ht->hand==PAIR){				return(-1);			}		}		// oops, no 2nd pair, flush beats trips.		return(1);	}}if (h2->flushflag==1){	if (h1->hand!=TRIPS){		return(-1);	}else{		// possible full house beating the flush                for (v=a;v;v=v->next){                        ht=(phand *)v->data;                        if (ht->hand==PAIR){                                return(1);                        }                }                // oops, no 2nd pair, flush beats trips.                return(-1);	}}// Straightsif (h1->hand==STRAIGHT){	if (h2->hand==STRAIGHT){		if (h1->rank>h2->rank){			return(1);		}else if (h1->rank==h2->rank){			return(0);		}else{			return(-1);		}	}else{		return(1);	}}if (h2->hand==STRAIGHT){	return(-1);}// Tripsif (h1->hand==TRIPS){	if (h2->hand!=TRIPS){		return(1);	}	v=a->next->next->next;	vv=b->next->next->next;	while(v){		h1=(phand *)v->data;                h2=(phand *)vv->data;		if (h1->hand==PAIR && h2->hand!=PAIR){			// full house beats trips.			return(1);		}		if (h1->hand!=PAIR && h2->hand==PAIR){			// full house beats trips.			return(-1);		}		if (h1->hand==PAIR && h2->hand==PAIR){			// check trip size of the boat.			if (((phand *)a->data)->rank > ((phand *)b->data)->rank){				// bigger boat wins.				return(1);			}			if (((phand *)a->data)->rank < ((phand *)b->data)->rank){                                // bigger boat wins.                                return(-1);                        }			// check the little size of the boat			if (h1->rank>h2->rank){				return(1);			}			if (h2->rank>h1->rank){				return(-1);			}			// and you can't split with boats.		}		// otherwise, just trips.		if (((phand *)a->data)->rank > ((phand *)b->data)->rank){                        return(1);                }                if (((phand *)a->data)->rank < ((phand *)b->data)->rank){                        return(-1);                }		// otherwise, even trips, check the kickers.		if (h1->rank>h2->rank){			return(1);		}		if (h1->rank<h2->rank){			return(-1);		}		// else, first kicker even		v=v->next;		vv=vv->next;	}	// else even kickers with the trips.	return(0);}if (h2->hand==TRIPS){	return(-1);}// pairsif (h1->hand==PAIR){	if (h2->hand!=PAIR){		return(1);	}	v=a->next->next;	vv=b->next->next;	while(v){                h1=(phand *)v->data;                h2=(phand *)vv->data;                if (h1->hand==PAIR && h2->hand!=PAIR){                        return(1);                }                if (h1->hand!=PAIR && h2->hand==PAIR){                        return(-1);                }                if (h1->hand==PAIR && h2->hand==PAIR){                        if (((phand *)a->data)->rank > ((phand *)b->data)->rank){                                return(1);                        }                        if (((phand *)a->data)->rank < ((phand *)b->data)->rank){                                return(-1);                        }                        if (h1->rank>h2->rank){                                return(1);                        }                        if (h2->rank>h1->rank){                                return(-1);                        }                }                // otherwise, just pair.                if (((phand *)a->data)->rank > ((phand *)b->data)->rank){                        return(1);                }                if (((phand *)a->data)->rank < ((phand *)b->data)->rank){                        return(-1);                }                if (h1->rank>h2->rank){                        return(1);                }                if (h1->rank<h2->rank){                        return(-1);                }                v=v->next;                vv=vv->next;        }	return(0);}if (h2->hand==PAIR){		return(-1);}// Only high card.v=a;vv=b;while(v){	h1=(phand *)v->data;        h2=(phand *)vv->data;	if (h1->rank>h2->rank){		return(1);	}	if (h1->rank<h2->rank){		return(-1);	}	v=v->next;	vv=vv->next;}return(0);}	void	handkiller(vine *inv){//// Delete hands out of vines//phand	*h;for (vine *v=inv;v;v=v->next){	if (v->type==HAND){		h=(phand *)v->data;		delete h;	}}}		void		vinecat(vine **inv){//// Concatenated cmd vines without newlines.//vine	*v;if (!*inv){	return;}for (v=*inv;v;v=v->next){	while(v->next && v->type==CMD && v->next->type==CMD && !strstr((char *)v->data,"\n") && cmdlen > strlen((char *)v->data) + strlen((char *)v->next->data)){		strcat((char *)v->data,(char *)v->next->data);		v->next->remove(inv);	}}}void	winner(vine **inv){//// Take vine *foo[9] and pair down the array to only winning hands.//vine	*v,*vv;int	x,y;int	rtn;for (x=0;x<9;x++){	for (y=0;y<9;y++){		if (inv[x]){			v=inv[x];			if (inv[y]){				vv=inv[y];				if (y!=x){					rtn=cmphands(v,vv);					if (rtn==1){						handkiller(vv);						inv[y]->nuke(&inv[y]);					}else if (rtn==-1){						handkiller(v);                                		inv[x]->nuke(&inv[x]);					}else{                                	}				}			}		}	}}}					void    winnerlow(vine **inv){//// Take vine *foo[9] and pair down the array to only winning hands.//vine    *v,*vv;int     x,y;int     rtn;for (x=0;x<9;x++){        for (y=0;y<9;y++){                if (inv[x]){                        v=inv[x];                        if (inv[y]){                                vv=inv[y];                                if (y!=x){                                        rtn=cmphands(v,vv);                                        if ((rtn<0 && v)||!vv){                                                handkiller(vv);                                                inv[y]->nuke(&inv[y]);                                        }else if (rtn==1){                                                handkiller(v);                                                inv[x]->nuke(&inv[x]);                                        }else{                                        }                                }                        }                }        }}}void	parsecli(int argc,char *argz[]){//// Parse through argv and set info.//int 	x;int	flag;flag=0;for (x=1;x<argc;x++){	if (argz[x]==strstr(argz[x],"-p")){		if (x+1!=argc){			players=atoi(argz[x+1]);			flag++;		}	}else if (argz[x]==strstr(argz[x],"-s")){		if (x+1!=argc){                        deals=atoi(argz[x+1]);			flag++;                }	}else if (argz[x]==strstr(argz[x],"-g")){                if (x+1!=argc){                        games=atoi(argz[x+1]);			flag++;                }	}}if (!flag && argc>1){	cout << usage;	exit(1);}if (players<2){ players=2; }if (players>9){ players=9; }if (deals<1){ deals=1; }if (games<1){ games=1; }}void	main(int argc, char *argz[]){//////omahahole	*oh[9];community	*co;int		rtn;vine		*v,*vv,*c;vine		*vh[9];int		t;float		w;float		lw;long		lp;int		z,zz;int		winnah;#ifdef	_WIN32	long    t;        time(&t);        srand(x);#else	srand(time(0));#endiffor (z=0;z<9;z++){	oh[z]=0;	vh[z]=0;}parsecli(argc,argz);cout << "Simulating "<< deals << " times.\n" << players-1 <<" opponents will play "<< games << " hands.\n\n";for (int x=0;x<deals;x++){	initdeck();	oh[0]=new omahahole();	c=(oh[0]->holetoa());	c->sout();	c->nuke(&c);	t=0;w=0;lw=0;lp=0;	for (int y=0;y<games;y++){		t++;		co=new community();		for (z=1;z<players;z++){			oh[z]=new omahahole();		}		for (z=0;z<players;z++){			vh[z]=omahahigh(oh[z],co);		}		result(vh[0]);		winner(vh);		zz=0;		if (vh[0]){ winnah=1; }else{ winnah=0; }		for (z=0;z<9;z++){			if (vh[z]){				zz++;				handkiller(vh[z]);				vh[z]->nuke(&vh[z]);			}		}		if (winnah){			w=w+1/zz;		}				for (z=0;z<players;z++){                        vh[z]=omahalow(oh[z],co);                }                result(vh[0]);                winnerlow(vh);		if (vh[0]){ winnah=1; }else{ winnah=0; }                zz=0;                for (z=0;z<9;z++){                        if (vh[z]){                                zz++;                                handkiller(vh[z]);                                vh[z]->nuke(&vh[z]);                        }                }		if (zz){			lp++;                	if (winnah){                        	lw=lw+1/zz;                	}		}		for (z=1;z<players;z++){			delete oh[z];		}		                delete co;				}	cout << "high wins: "<<w/t*100<<"%   low wins: "<<lw<<"("<<lw/t*100<<"% of total; "<<lw/lp*100<<"% of low; "<<lw/resultcounter[9]*100<<"% of participated) \n";	printresults();	cout << "\n";	resetcounter();	//cout << "vinecount: " << vinecount << "\n";	delete oh[0];}}
To compare two hands:- In each hand, if all cards are the same, mark hand as a flush.- In each hand:  - Group matching cards. Represent each group as a pair (rank, number of cards).  - Sort the groups by number of cards, then by rank. If there are five groups:    - We know there are no matched cards. If the rank differs by 4 between first and last:      - mark hand as a straight.- If both hands are straight AND flush:  - Compare ranks of first group, and report the winner from that.- Elsif one hand is straight AND flush:  - That hand wins.(Otherwise, neither hand is a straight flush...)- Elsif both hands are straight OR flush: (must be exclusive or at this point)  - If one is flush and the other is straight, the flush wins.  - Else, compare groups from the beginning down (to handle flushes).- Elsif one hand is a straight OR flush (and thus the other isn't):  - If the non-straight/flush hand has two groups:    - It is four of a kind or full house, and wins.  - Otherwise, the other hand wins.(Otherwise, neither hand is a straight or a flush).- Compare group sizes from first group to last. If there is any mismatch:  - The hand with the larger group wins.- Otherwise, the hand types are the same; compare group ranks from first group to last.


[Edited by - Zahlman on March 8, 2005 10:26:39 PM]

This topic is closed to new replies.

Advertisement