Brian,

DId some more testing.... Never mind about separate fns for 4 or 5 cards. This combined fn will execute 18,000 times on my 2.4-gHz Macbook Pro in 0.01 second. :)

I'm also including versions of your routines for printing cards (which I presume will eventually be replaced by graphics) that seem much simpler to me.

Jay

local fn runs( h(5) as card, size as short ) as short
'~'1
' Assumes hand is sorted low to high
dim as short r, count, mult, top
mult = 1 : count = 1 : top = size - 1

for r = 1 to top
select h.rank(r+1) - h.rank(r)
case 1    : count ++ // consecutive
case 0    : mult += mult // match
case else : if count >= 3 then exit fn// end of run, if any
count = 1 : mult = 1
end select
next

if count < 3 then count = 0
end fn = count * mult

local fn countHand( h(5) as card, size as short ) as short
'~'1
dim as short c1, c2, v, count, total
dim as boolean five

five  = ( size == 5 )
total = h.value( 1 ) + h.value( 2 ) + h.value( 3 ) + h.value( 4 )
 if five then total += h.value( 5 )
count = -( total == 15 ) // 4/5-card 15

for c1 = 1 to size
if ( total - h.value(c1) ) == 15 then count ++ // 3/4-card 15

for c2 = c1 + 1 to size
if h.rank( c1 ) == h.rank( c2 ) then count++ // a pair
v = h.value( c1 ) + h.value( c2 )
if ( total - v ) == 15 then if five then count ++ // 3-card 15
if v == 15 then count ++ // 2-card 15
next

next

end fn = count * 2 + fn runs( h(0), size )


local fn GetRankClean( aCard as byte ) as Str15
'~'1
end fn = mid$("  A 2 3 4 5 6 7 8 910 J Q K", aCard * 2, 2 )


local fn GetSuitAsChar (aCard as byte) as Str15
'~'1
end fn = mid$("CDHS", acard, 1)//chr$(retVal) // see conversion comment for GetRankClean



On Jun 5, 2013, at 2:41 AM, Jay Reeve wrote:

On Jun 4, 2013, at 9:08 AM, Brian S wrote:

Most of the time is spent waiting for the user to pick the crib cards and play cards. Counting speed is particularly important because it is called thousands of times. Someone even wrote a semi-formal paper documenting how many times the counting functions are called. To quote page 2 of the document that link: "CountHand is a simple algorithm for counting a 5 card cribbage hand. The Decide20, Decide30 and Decide31 algorithms call this routine roughly 18,000 times per decision:"

I guess I have no idea what these Decide algorithms do--they must be far more sophisticated than anything my program did, because doing anything 18,000 times in Commodore Basic would have taken entire minutes.

If they are necessary, however, I think it makes an argument for having separate--if somewhat redundant--fns for counting 5 cards and for counting 4 cards. Trying to do both in one fn is likely to slow things down.

May I also suggest combining the pair counting with the fifteens? It's just a matter of adding one line, and would avoid adding a redundant loop and additional overhead. 

Here are my complete hand-counting functions, along with their ancillary run counter. (BTW, I believe the one you posted would fail with A 2 3 6 7, returning 4.)

Jay

--
To unsubscribe, send ANY message to: futurebasic-unsubscribe@... To access the list archives, go to: http://freegroups.net/groups/futurebasic/