Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Faster Poker Evaluator

0 views
Skip to first unread message

Jazbo Burns

unread,
Jul 10, 1996, 3:00:00 AM7/10/96
to

A couple of weeks ago someone (I forgot to grab the "From:" line, drat it)
made the following proposition:

>>Anyway, I'll let you know if I come up with something faster than
>>the poker.tar evaluator.
>
>You willing to offer any action on that? :-) How about this, I'll give
>you 2:1 that you can't double the speed, 3:1 you can't triple it,
>etc. Both using gcc and running on a 32mb Pentium 133 running SCO
>Unix.

Since I happened to be working on speeding up my C++ hand evaluator, I
decided to download poker.tar.gz & compare it to what I was doing. If
you're still out there, what stakes are you offering & how would we
run the test? (Note: I'm willing to put my result, converted to C, up
on the appropriate ftp server if someone will offer to take it.)

--jazbo
--
-----
Return mail should go to jbu...@monmouth.com, regardless of what From: says!

Charles Haynes

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

In article <JBURNS.96J...@wildcat.monmouth.com>,
Jazbo Burns <jbu...@monmouth.com> wrote:

>A couple of weeks ago someone (I forgot to grab the "From:" line, drat it)
>made the following proposition:

>>>Anyway, I'll let you know if I come up with something faster than
>>>the poker.tar evaluator.

>>You willing to offer any action on that? :-) How about this, I'll give
>>you 2:1 that you can't double the speed, 3:1 you can't triple it,
>>etc. Both using gcc and running on a 32mb Pentium 133 running SCO
>>Unix.

>Since I happened to be working on speeding up my C++ hand evaluator, I
>decided to download poker.tar.gz & compare it to what I was doing. If
>you're still out there,

Just try and get rid of me. :-)

>what stakes are you offering & how would we run the test?

Well given that you can figure out in advance if you've won I'm at a
bit of a disadvantage, but hey, I'm game. I have problems throwing
away my losing hands too... :-)

Would $10 tempt you? How about $20? How about humiliating me in public
and earning the approval and undying gratitude of r.g.p. readers?

As for running the test we could agree on a "test harness" with two
components. First, untimed, test accuracy. give each evaluator a set
of 200 hands to evaluate and verify correctness. We could each submit
100 hands for this part. Second, timed, test speed. Evaluate 100
million hands each and time it to the nearest second. seed the random
number generator with a constant to make sure each evaluates the same
hands. Subtract out the overhead of the shuffle, deal, loop, and call
to the evaluator (time a null evaluator that returns a constant).

the evaluator would take a hand H (seven integers from 0-51,
{0=2c,1=2d,2=2h,3=2s...,51=as}) and return an integer I such that if
hand Ha returned integer Ia and hand Hb returned integer Ib, Ia < Ib
if and only if hand Ha loses to hand Hb.

The evaluator could take different input parameters by mutual
agreement. For example four integer bit sets representing which clubs,
diamonds, hearts, and spades were in the hand.

If an evaluator fails the correctness test it loses. If both fail all
bets are off. If the fast evaluator takes less than 2 times as long as
yours I win $20. If the fast evaluator takes 2 times or more but less
than 3 times you win $40. If it takes 3 times or more but less than 4
times you win $60. Etc. Except I want to limit my high end to 1:10. If
your evaluator is more than 10 times faster than the "fast" evaluator
I'll pay off at 10:1.

>(Note: I'm willing to put my result, converted to C, up
>on the appropriate ftp server if someone will offer to take it.)

I'd be more than happy to make it available to the r.g.p. community by
hosting it on my ftp server.

FWIW I'm working on porting the fast evaluator to Windows now. I'll
make the front end available on my server as soon as it's done. Anyone
got nice card bitmaps I could use?

-- Charles

--
http://www.fifth-mountain.com/

Eric J. Holtman

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

In article <4s3ufn$d...@shellx.best.com>, hay...@best.com says...

>
>
>As for running the test we could agree on a "test harness" with two
>components. First, untimed, test accuracy. give each evaluator a set
>of 200 hands to evaluate and verify correctness. We could each submit
>100 hands for this part. Second, timed, test speed. Evaluate 100
>million hands each and time it to the nearest second. seed the random
>number generator with a constant to make sure each evaluates the same
>hands. Subtract out the overhead of the shuffle, deal, loop, and call
>to the evaluator (time a null evaluator that returns a constant).
>

Aww.. cmon... we're talking *fast* hand evaluators here. Why not just
feed all the possible seven card hands into them?

--
------
Eric J. Holtman | Managing programmers is like herding cats.
#include <stdjunk.h> |
http://www.jaeger.com/~erich/ | There's no government like no government


Charles Haynes

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

In article <4s447h$a...@news4.digex.net>,

Eric J. Holtman <er...@jaeger.com> wrote:

>Aww.. cmon... we're talking *fast* hand evaluators here. Why not just
>feed all the possible seven card hands into them?

Too easy to cook, but a good test none the less. It's what I use to
test new evaluators both for speed and for bugs.

Jazbo Burns

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

>Just try and get rid of me. :-)

I assumes that means you are the one that made the original proposition.

>Would $10 tempt you? How about $20? How about humiliating me in public
>and earning the approval and undying gratitude of r.g.p. readers?

You originally offered 2 to 1. How about $50 even money that I can
halve the speed of the ctm evaluator? If that's too rich, make a
counter-offer.

>As for running the test we could agree on a "test harness" with two
>components. First, untimed, test accuracy. give each evaluator a set
>of 200 hands to evaluate and verify correctness. We could each submit
>100 hands for this part. Second, timed, test speed. Evaluate 100
>million hands each and time it to the nearest second. seed the random
>number generator with a constant to make sure each evaluates the same
>hands. Subtract out the overhead of the shuffle, deal, loop, and call
>to the evaluator (time a null evaluator that returns a constant).

If it don't work, you win. (If a program doesn't need to be correct,
I can make it *really* fast. :-)

I don't think there is a fair way to subtract out the set up time
-- the speed of the evaluator depends on having things in a "nice"
form. For example, if the evaluator is passed a bit string
representing pips for each suit, a count for each pip value, and a
total number of cards for each suit, it can obviously run faster than
if it is given only minimal information & has to deduce other things.

In the poker.tar.gz file, there is a program called "cmp2" that
evaluates two hold'em hands heads up for all 1,712,304
possible boards. I propose making the evaluation as follows: you pick
fifty random heads up pairings. Compress, encrypt, uuencode and send
them to me. After I get the hands, I'll send you my code. (I think
the race will close -- if you get to choose worst-case hands for my
particular strategy it could make a significant difference). Then you
send me the decryption key so I can check the results myself.

Note: cmp2 as currently written only takes one hand at a time, whereas
my evaluator reads a list of combinations from a file. You (or I) can
modify cmp2 so that we can run 20 hands in one go. No fair speeding
up ctm's original code in doing this.

Just to be clear: I'm talking about beating the version of
poker_tar.gz that I recently downloaded. It's compressed size is
54565 bytes and the README file is dates Jan 29 08:02 1995.
You will compile & run both version on your hardware, a Pentium 133, I
believe. [Cliff's original code was designed to take advantage of the
64 bit word size on an Alpha --- I could modify my code to take
advantage of double word operations, but I don't have an Alpha lying
around to test with.]

Finally, if you agree to the proposition, I nominate Cliff Matthews to
referee any disputes, assuming he agrees (are you out there Cliff)?

I'm still debugging, but I expect to have an evaluator ready to ship
to you in a week (probably Monday if Bertha keeps me in doors this
weekend).

BTW, I don't see you on the BARGE list, so I guess we can't resolve
this in person. However, a check will be fine :-).

Charles Haynes

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

This discussion continuing in email.

Synopsis: we've agreed on terms. Now down to cases...

Charles Haynes

unread,
Jul 11, 1996, 3:00:00 AM7/11/96
to

In article <31E5B9...@netcom.com>, Ray Tayek <rta...@netcom.com> wrote:

>A few years ago I wrote a hand evaluator. I thought it was pretty
>fast then. It uses a table of all of the poker hands (with the
>flushes in a seperate table) and 4 arrays for each table. Have you
>guys discovered a faster way?

In a word - yes.

Ray Tayek

unread,
Jul 12, 1996, 3:00:00 AM7/12/96
to

Jazbo Burns wrote:
>
> A couple of weeks ago someone (I forgot to grab the "From:" line, drat it)
> made the following proposition:
>
> >>Anyway, I'll let you know if I come up with something faster than
> >>the poker.tar evaluator.
> >
> >You willing to offer any action on that? :-) How about this, I'll give
> >you 2:1 that you can't double the speed, 3:1 you can't triple it,
> >etc. Both using gcc and running on a 32mb Pentium 133 running SCO
> >Unix.
>
> Since I happened to be working on speeding up my C++ hand evaluator, I
> decided to download poker.tar.gz & compare it to what I was doing. If
> you're still out there, what stakes are you offering & how would we
> run the test? (Note: I'm willing to put my result, converted to C, up

> on the appropriate ftp server if someone will offer to take it.)
>
> --jazbo
> --
> -----
> Return mail should go to jbu...@monmouth.com, regardless of what From: says!

A few years ago I wrote a hand evaluator. I thought it was pretty fast then. It uses a table of all of the

poker hands (with the flushes in a seperate table) and 4 arrays for each table. Have you guys discovered a

faster way? The lookup code is as follows (everything not decared is a short or a char):


/* constants for the cards */

#define RANKS 13
#define SUITS 4
#define CARDS (RANKS*SUITS)

#define ACE_LOW 0
#define DUECE 1
#define TREY 2
#define FOUR 3
#define FIVE 4
#define SIX 5
#define SEVEN 6
#define EIGHT 7
#define NINE 8
#define TEN 9
#define JACK 10
#define QUEEN 11
#define KING 12
#define ACE_HIGH 13
#define JOKER1 14
#define NAC 15
#define BACK1 16
#define BACK2 17
#define BACK3 18
#define BACK4 19
#define BACK5 20
#define BACK6 21
#define BACK7 22
#define BACK8 23
#define BACK9 24
#define BACK10 25
#define CLUBS 0
#define DIAMONDS 1
#define HEARTS 2
#define SPADES 3
#define NAS 4

/* constants for poker hands */

#define HIGH_HANDS 7462
#define ACES_STRAIGHTS_AND_FLUSHES 1
#define FLUSHES 1287
#define WILD 13
#define OTHERS (HIGH_HANDS+WILD-FLUSHES)
#define TOTAL (HIGH_HANDS+WILD)

#define HAND_TYPES 10
#define NO_PAIR 0
#define ONE_PAIR 1
#define TWO_PAIR 2
#define THREE_OF_A_KIND 3
#define STRAIGHT 4
#define FLUSH 5
#define FULL_HOUSE 6
#define FOUR_OF_A_KIND 7
#define STRAIGHT_FLUSH 8
#define FIVE_OF_A_KIND 9
#define NAH 10

#define JACKS_OR_BETTER 4218
#define TENS_OR_BETTER 4438

/* typedef's for cards */

typedef char RANK; /* card rank */
typedef char SUIT; /* card suit */

/* structures for cards */

typedef struct a_card CARD;
struct a_card /* a card structure */
{
RANK rank; /* the rank */
SUIT suit; /* the suit */
BOOL used; /* has the card been used? */
HANDLE h; /* handle to bitmap */
};

/* structures for poker hands */

typedef struct a_poker_hand POKER_HAND;
struct a_poker_hand /* a five card poker hand */
{
char c[5]; /* the five cards */
char type; /* the type of this hand */
short n; /* the hand number */
};


/* global variables */

global POKER_HAND far *other; /* most of the poker hands */
global POKER_HAND far *flush; /* the flushes */
global CARD *deck;


static POKER_HAND far *lookup(int the_hand[5]) /* look up the hand */
{
RANK t;
int i;
RANK r[5];
SUIT s[5];
POKER_HAND far *h;
for(i=0;i<5;i++) /* copy the hand */
{
CARD *c=&deck[the_hand[i]];
r[i]=c->rank;
s[i]=c->suit;
}
if(r[0]<r[1]) /* sort the cards */
{ t=r[0]; r[0]=r[1]; r[1]=t; }
if(r[0]<r[2])
{ t=r[0]; r[0]=r[2]; r[2]=t; }
if(r[0]<r[3])
{ t=r[0]; r[0]=r[3]; r[3]=t; }
if(r[0]<r[4])
{ t=r[0]; r[0]=r[4]; r[4]=t; }
if(r[1]<r[2])
{ t=r[1]; r[1]=r[2]; r[2]=t; }
if(r[1]<r[3])
{ t=r[1]; r[1]=r[3]; r[3]=t; }
if(r[1]<r[4])
{ t=r[1]; r[1]=r[4]; r[4]=t; }
if(r[2]<r[3])
{ t=r[2]; r[2]=r[3]; r[3]=t; }
if(r[2]<r[4])
{ t=r[2]; r[2]=r[4]; r[4]=t; }
if(r[3]<r[4])
{ t=r[3]; r[3]=r[4]; r[4]=t; }
if(s[0]==s[1]&&s[1]==s[2]&&s[2]==s[3]&&s[3]==s[4]) /* flush? */
h=flush+b0[r[0]]+b1[r[1]]+b2[r[2]]+b3[r[3]]+r[4]; /* yes */
else h=other+a0[r[0]]+a1[r[1]]+a2[r[2]]+a3[r[3]]+r[4]; /* no */
return(h);
}
--

Ray

Clifford T. Matthews

unread,
Jul 13, 1996, 3:00:00 AM7/13/96
to

>>>>> "Ray" == Ray Tayek <rta...@netcom.com> writes:
In article <31E5B9...@netcom.com> Ray Tayek <rta...@netcom.com> writes:

Ray> A few years ago I wrote a hand evaluator. I thought it was
Ray> pretty fast then. It uses a table of all of the poker hands
Ray> (with the flushes in a seperate table) and 4 arrays for each
Ray> table. Have you guys discovered a faster way?

Yes. *Much* faster.

Included below are single steppings through the fast evaluator's
analysis of a flush, two pair, one pair and no pair, just to give you
and any lurkers an idea of the order of magnitude of speed we're
talking about. I didn't provide a trace for other types of hands
because I'm lazy, not because they'll take up many more instructions
(at least I don't think they will -- I haven't looked at my own code
for a long time).

The code was generated by gcc 2.7.2 using the compile time options:

CFLAGS=-g -O4 -Wall -finline-functions -Winline -DNDEBUG -fomit-frame-pointer

The source code is all in C, and up until now I haven't even bothered
to look at the assembly that was being generated. Mat Hostetter and I
coded most of the fast hand evaluator in one night, although I didn't
actually finish it up until some time later when I was wide awake on
vacation a few hours before my wife would get up.

At one point I volunteered to run a "poker source" mailing list, but
there were too few contributions to make it worth my (and probably
anyone else's) time. Michael Maurer did make some contributions to
the evaluaton code, but I was unhappy with the exact way he did it and
I never got a chance to merge his code with ours. That's really a
shame, and it's not something I'm proud of, but my "day job" keeps me
busy 7 days a week (http://www.ardi.com/) for more info.

I've put a very slightly newer version of the poker source in

ftp://ftp.ardi.com/private/poker.tar.gz

The "private" directory is accessible but not readable, meaning you
will not be able to list the directory, but if you request
poker.tar.gz by name, you should be able to pick it up. Use binary
mode. You won't be able to do much with it directly unless you have
gcc on your system. If you want to get good performance, I recommend
gcc 2.7.x or greater -- older versions might slow the code down
significantly.

Actually, if you're interested in the algorithm that we use (I think
it's similar to what Steve Brecher described in his post, although I
didn't read his post in depth yet -- I'll do that now), you can always
pick up the source and eyeball it even if you don't have gcc.

--Cliff
c...@ardi.com

Code trace when evaluating a flush (23 instructions):
1: x/i $eip 0x800947e <main+36734>: movl %edi,%edx
1: x/i $eip 0x8009480 <main+36736>: orl 0x1c(%esp,1),%edx
1: x/i $eip 0x8009484 <main+36740>: orl 0x28(%esp,1),%edx
1: x/i $eip 0x8009488 <main+36744>: orl %ebp,%edx
1: x/i $eip 0x800948a <main+36746>: movl %edx,0x20(%esp,1)
1: x/i $eip 0x800948e <main+36750>: addl $0xfffffffd,%edx
1: x/i $eip 0x8009491 <main+36753>: cmpl $0x1fbd,%edx
1: x/i $eip 0x8009497 <main+36759>: ja 0x80116c0 <main+70080>
1: x/i $eip 0x800949d <main+36765>: jmp *0x80094b0(,%edx,4)
1: x/i $eip 0x80113f0 <main+69360>: movl 0x14(%esp,1),%edi
1: x/i $eip 0x80113f4 <main+69364>: movl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x80113fb <main+69371>: movl 0x1c(%esp,1),%edi
1: x/i $eip 0x80113ff <main+69375>: orl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x8011406 <main+69382>: movl 0x28(%esp,1),%esi
1: x/i $eip 0x801140a <main+69386>: orl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x8011411 <main+69393>: movl %edx,%ebx
1: x/i $eip 0x8011413 <main+69395>: orl 0x8032ec4(,%ebp,4),%ebx
1: x/i $eip 0x801141a <main+69402>: je 0x80116b0 <main+70064>
1: x/i $eip 0x8011420 <main+69408>: movl 0x802aec4(,%ebx,4),%edx
1: x/i $eip 0x8011427 <main+69415>: testl %edx,%edx
1: x/i $eip 0x8011429 <main+69417>: jne 0x8011697 <main+70039>
1: x/i $eip 0x8011697 <main+70039>: xorl $0x30000000,%edx
1: x/i $eip 0x801169d <main+70045>: jmp 0x80116d0 <main+70096>

Evaluation of a pair (36 instructions):
1: x/i $eip 0x800947e <main+36734>: movl %edi,%edx
1: x/i $eip 0x8009480 <main+36736>: orl 0x1c(%esp,1),%edx
1: x/i $eip 0x8009484 <main+36740>: orl 0x28(%esp,1),%edx
1: x/i $eip 0x8009488 <main+36744>: orl %ebp,%edx
1: x/i $eip 0x800948a <main+36746>: movl %edx,0x20(%esp,1)
1: x/i $eip 0x800948e <main+36750>: addl $0xfffffffd,%edx
1: x/i $eip 0x8009491 <main+36753>: cmpl $0x1fbd,%edx
1: x/i $eip 0x8009497 <main+36759>: ja 0x80116c0 <main+70080>
1: x/i $eip 0x800949d <main+36765>: jmp *0x80094b0(,%edx,4)
1: x/i $eip 0x80115f0 <main+69872>: movl 0x14(%esp,1),%edi
1: x/i $eip 0x80115f4 <main+69876>: movl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x80115fb <main+69883>: movl 0x1c(%esp,1),%edi
1: x/i $eip 0x80115ff <main+69887>: orl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x8011606 <main+69894>: movl 0x28(%esp,1),%esi
1: x/i $eip 0x801160a <main+69898>: orl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x8011611 <main+69905>: movl %edx,%ebx
1: x/i $eip 0x8011613 <main+69907>: orl 0x8032ec4(,%ebp,4),%ebx
1: x/i $eip 0x801161a <main+69914>: jne 0x80116a0 <main+70048>
1: x/i $eip 0x8011620 <main+69920>: movl 0x1c(%esp,1),%ecx
1: x/i $eip 0x8011624 <main+69924>: orl 0x14(%esp,1),%ecx
1: x/i $eip 0x8011628 <main+69928>: orl %ebp,%ecx
1: x/i $eip 0x801162a <main+69930>: andl 0x28(%esp,1),%ecx
1: x/i $eip 0x801162e <main+69934>: movl 0x14(%esp,1),%edx
1: x/i $eip 0x8011632 <main+69938>: orl %ebp,%edx
1: x/i $eip 0x8011634 <main+69940>: andl 0x1c(%esp,1),%edx
1: x/i $eip 0x8011638 <main+69944>: orl %edx,%ecx
1: x/i $eip 0x801163a <main+69946>: movl 0x14(%esp,1),%edx
1: x/i $eip 0x801163e <main+69950>: andl %ebp,%edx
1: x/i $eip 0x8011640 <main+69952>: orl %ecx,%edx
1: x/i $eip 0x8011642 <main+69954>: movl 0x803aec4(,%edx,4),%edx
1: x/i $eip 0x8011649 <main+69961>: movl %edx,%ecx
1: x/i $eip 0x801164b <main+69963>: shll $0xd,%ecx
1: x/i $eip 0x801164e <main+69966>: xorl 0x20(%esp,1),%edx
1: x/i $eip 0x8011652 <main+69970>: orl 0x8022ec4(,%edx,4),%ecx
1: x/i $eip 0x8011659 <main+69977>: movl %ecx,%edx
1: x/i $eip 0x801165b <main+69979>: jmp 0x80116d0 <main+70096>

Evaluation of two pair (51 instructions):
1: x/i $eip 0x800947e <main+36734>: movl %edi,%edx
1: x/i $eip 0x8009480 <main+36736>: orl 0x1c(%esp,1),%edx
1: x/i $eip 0x8009484 <main+36740>: orl 0x28(%esp,1),%edx
1: x/i $eip 0x8009488 <main+36744>: orl %ebp,%edx
1: x/i $eip 0x800948a <main+36746>: movl %edx,0x20(%esp,1)
1: x/i $eip 0x800948e <main+36750>: addl $0xfffffffd,%edx
1: x/i $eip 0x8009491 <main+36753>: cmpl $0x1fbd,%edx
1: x/i $eip 0x8009497 <main+36759>: ja 0x80116c0 <main+70080>
1: x/i $eip 0x800949d <main+36765>: jmp *0x80094b0(,%edx,4)
1: x/i $eip 0x8011440 <main+69440>: movl 0x14(%esp,1),%esi
1: x/i $eip 0x8011444 <main+69444>: movl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x801144b <main+69451>: movl 0x1c(%esp,1),%esi
1: x/i $eip 0x801144f <main+69455>: orl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x8011456 <main+69462>: movl 0x28(%esp,1),%edi
1: x/i $eip 0x801145a <main+69466>: orl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x8011461 <main+69473>: movl %edx,%ebx
1: x/i $eip 0x8011463 <main+69475>: orl 0x8032ec4(,%ebp,4),%ebx
1: x/i $eip 0x801146a <main+69482>: movl 0x14(%esp,1),%eax
1: x/i $eip 0x801146e <main+69486>: andl %esi,%eax
1: x/i $eip 0x8011470 <main+69488>: movl %edi,%edx
1: x/i $eip 0x8011472 <main+69490>: andl %ebp,%edx
1: x/i $eip 0x8011474 <main+69492>: orl %edx,%eax
1: x/i $eip 0x8011476 <main+69494>: movl %edi,%ecx
1: x/i $eip 0x8011478 <main+69496>: andl 0x14(%esp,1),%ecx
1: x/i $eip 0x801147c <main+69500>: movl %esi,%edx
1: x/i $eip 0x801147e <main+69502>: andl %ebp,%edx
1: x/i $eip 0x8011480 <main+69504>: orl %edx,%ecx
1: x/i $eip 0x8011482 <main+69506>: andl %ecx,%eax
1: x/i $eip 0x8011484 <main+69508>: je 0x80114a0 <main+69536>
1: x/i $eip 0x80114a0 <main+69536>: testl %ebx,%ebx
1: x/i $eip 0x80114a2 <main+69538>: jne 0x80116a0 <main+70048>
1: x/i $eip 0x80114a8 <main+69544>: jmp 0x80115a0 <main+69792>
1: x/i $eip 0x80115a0 <main+69792>: movl 0x1c(%esp,1),%ecx
1: x/i $eip 0x80115a4 <main+69796>: orl 0x14(%esp,1),%ecx
1: x/i $eip 0x80115a8 <main+69800>: orl %ebp,%ecx
1: x/i $eip 0x80115aa <main+69802>: andl 0x28(%esp,1),%ecx
1: x/i $eip 0x80115ae <main+69806>: movl 0x14(%esp,1),%edx
1: x/i $eip 0x80115b2 <main+69810>: orl %ebp,%edx
1: x/i $eip 0x80115b4 <main+69812>: andl 0x1c(%esp,1),%edx
1: x/i $eip 0x80115b8 <main+69816>: orl %edx,%ecx
1: x/i $eip 0x80115ba <main+69818>: movl 0x14(%esp,1),%edx
1: x/i $eip 0x80115be <main+69822>: andl %ebp,%edx
1: x/i $eip 0x80115c0 <main+69824>: orl %ecx,%edx
1: x/i $eip 0x80115c2 <main+69826>: movl 0x801aec4(,%edx,4),%edx
1: x/i $eip 0x80115c9 <main+69833>: movl %edx,%ecx
1: x/i $eip 0x80115cb <main+69835>: shll $0xd,%ecx
1: x/i $eip 0x80115ce <main+69838>: xorl 0x20(%esp,1),%edx
1: x/i $eip 0x80115d2 <main+69842>: movl 0x803aec4(,%edx,4),%edx
1: x/i $eip 0x80115d9 <main+69849>: orl $0x8000000,%edx
1: x/i $eip 0x80115df <main+69855>: orl %ecx,%edx
1: x/i $eip 0x80115e1 <main+69857>: jmp 0x80116d0 <main+70096>

Evaluation of no pair (21 instructions):
1: x/i $eip 0x800947e <main+36734>: movl %edi,%edx
1: x/i $eip 0x8009480 <main+36736>: orl 0x1c(%esp,1),%edx
1: x/i $eip 0x8009484 <main+36740>: orl 0x28(%esp,1),%edx
1: x/i $eip 0x8009488 <main+36744>: orl %ebp,%edx
1: x/i $eip 0x800948a <main+36746>: movl %edx,0x20(%esp,1)
1: x/i $eip 0x800948e <main+36750>: addl $0xfffffffd,%edx
1: x/i $eip 0x8009491 <main+36753>: cmpl $0x1fbd,%edx
1: x/i $eip 0x8009497 <main+36759>: ja 0x80116c0 <main+70080>
1: x/i $eip 0x800949d <main+36765>: jmp *0x80094b0(,%edx,4)
1: x/i $eip 0x80113b0 <main+69296>: movl 0x14(%esp,1),%esi
1: x/i $eip 0x80113b4 <main+69300>: movl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x80113bb <main+69307>: movl 0x1c(%esp,1),%esi
1: x/i $eip 0x80113bf <main+69311>: orl 0x8032ec4(,%esi,4),%edx
1: x/i $eip 0x80113c6 <main+69318>: movl 0x28(%esp,1),%edi
1: x/i $eip 0x80113ca <main+69322>: orl 0x8032ec4(,%edi,4),%edx
1: x/i $eip 0x80113d1 <main+69329>: movl %edx,%ebx
1: x/i $eip 0x80113d3 <main+69331>: orl 0x8032ec4(,%ebp,4),%ebx
1: x/i $eip 0x80113da <main+69338>: jne 0x80116a0 <main+70048>
1: x/i $eip 0x80113e0 <main+69344>: movl 0x20(%esp,1),%esi
1: x/i $eip 0x80113e4 <main+69348>: movl 0x8042ec4(,%esi,4),%edx
1: x/i $eip 0x80113eb <main+69355>: jmp 0x80116d0 <main+70096>


Clifford T. Matthews

unread,
Jul 13, 1996, 3:00:00 AM7/13/96
to

I just skimmed my post and realized that it may not be obvious exactly
what the code traces are. Specifically, those are every single
instruction that is executed by the hand evaluator in four different
runs of the hand evaluator.

Different hands wind up with different sequences of code being
executed, but the code that actually is determining whether or not we
have a flush, straight, etc. *is* part of the trace. In other words,
the trace output does *not* start from where the evaluator has already
determined what kind of hand you have, it always starts from the
beginning (in this case pc 0x800947e) and it always ends up with a
jump to the remainder of the program (in this case pc 0x80116d0).

So, in the examples I've provided, the hand has been evaluated in 23,
36, 51, and 21 instructions for example hands which evaluated out to a
flush, a pair, two pair, and no pair respectively. The value that the
evaluator has left in edx can either be used to compare to the results
of another evaluation (so you can tell whether a given hand beats,
ties or leses to a particular hand), or can be parsed to reveal
specifically what sort of hand the cards represent (e.g. aces over
eights with a ten kicker, high hand composed of jack, ten, eight, trey
and deuce, seven high straight flush, etc.).

I hope that clears things up a bit. I should have been more explicit
when I first posted, but I was in "talking to computers" mode, rather
than "talking to humans".

--Cliff
c...@ardi.com

Charles Haynes

unread,
Jul 13, 1996, 3:00:00 AM7/13/96
to

In article <ufk9w8a...@ftp.ardi.com>,

Clifford T. Matthews <c...@ardi.com> wrote:

>I hope that clears things up a bit. I should have been more explicit
>when I first posted, but I was in "talking to computers" mode, rather
>than "talking to humans".

Just to be maybe a little clearer still. I think Cliff's code traces are
assuming the hands are represented as bit masks. Either one 64 bit bit
mask or 4 16 bit bit masks I can't tell.

0 new messages