Post by JonD on Oct 9, 2022 21:24:40 GMT
I have a created a program to generate random poker hands and display how likely it is to get each type of hand.
I was curious to know how much faster the tokenized (.tkn) file would run, so I added a timer and created the .tkn file.
But when I run the .tkn file, the output is different. Things display in different places in the window than they should.
I tried to include screenshots of this, but I couldn't figure out how to insert the pictures into the post. But here is the code:
I am running on Windows 10 if that matters.
Thanks for any help.
I was curious to know how much faster the tokenized (.tkn) file would run, so I added a timer and created the .tkn file.
But when I run the .tkn file, the output is different. Things display in different places in the window than they should.
I tried to include screenshots of this, but I couldn't figure out how to insert the pictures into the post. But here is the code:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' '
' Program to show frequency of all ranks of poker hands '
' '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''
' Written by: Jon Drechsel '
' Latest Revision : 10/9/22 '
'''''''''''''''''''''''''''''''''
' initialize some variables
limit=1000 ' set this to the number of hands you would like to have generated, no more than 99,999,999
true=1 : false=0
showHands=true ' set to true if you want the last hand of each rank displayed
lines=-1 ' set this to the number of empty lines between each rank's displayed 2 rows of data
totalHands=0 ' total number of poker hands that have been randomly generated
rankNameXpos=3 ' x position of upper left corner of area where rank names are listed
rankNameYpos=4 ' y position ... " " "
rankCountXpos=17+rankNameXpos ' x position of upper left corner of area where rank counts are listed
percentXpos=9+rankCountXpos ' x position of upper left corner of area where percentages are listed
oddsXpos=12+percentXpos ' x position of left end of area where odds are displayed
handXpos=13+oddsXpos ' x position of left end of area where hands are displayed
dim rankCount(10) ' the count of each type (rank) of poker hand
dim kindCount(13) ' the count of each card value, used for checking 2,3, or 4 of a kind, and full house
dim card(5) ' the cards in the randomly dealt hand (1-52, 1-13=spade, 14-26=heart, 27-39=diamond, 40-52=club)
dim cardSuit(5) ' the suit of each card in the hand (1=spade, 2=heart, 3=diamond, 4=club)
dim cardValue(5) ' the value of each card in the hand (1=Ace, 2=2,...., 11=J, 12=Q, 13=K)
dim sorted(5) ' sorted(1) holds the number of the lowest value card in the hand (1-5)
' sorted(2) holds the number of the next highest value, and so on.
' this is used to determine if a hand is a straight or not
' on 10/8/22 I changed "sort()" to "sorted()" because "sort" is now a command in Just Basic 2.0
' for displaying hands next to the count of each rank
dim dispSuit$(4) : data "S", "H", "D", "C"
dim dispValue$(13) : data " A", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", " J", " Q", " K"
for i=1 to 4 : read a$ : dispSuit$(i)=a$ : next i
for i=1 to 13 : read a$ : dispValue$(i)=a$ : next i
' \\\\\\\\\\\\\\\ START OF MAIN PROGRAM ///////////////
' lay out the screen
mainwin 85 26 ' set the size of the main window
' rank name calc % calc odds
data " Royal Flush", 0.000154, 649740
data " Straight Flush", 0.00139 , 72193.33
data " Four of a Kind", 0.0240 , 4165
data " Full House", 0.144 , 694.17
data " Flush", 0.197 , 508.8
data " Straight", 0.392 , 254.8
data "Three of a Kind", 2.11 , 47.3
data " Two Pair", 4.75 , 21.03
data " Pair", 42.3 , 2.36
data " High Card", 50.1 , 1.995
locate rankNameXpos, rankNameYpos-2 : print " Target : "
locate rankCountXpos, rankNameYpos-2 : print using("########", limit)
locate rankNameXpos, rankNameYpos-1 : print " Total Hands : "
locate oddsXpos, rankNameYpos-1 : print "Odds (1 in _)"
for i=1 to 10
read rankName$, rankCalculatedProbability, rankCalculatedOdds
locate rankNameXpos, rankNameYpos+(i-1)*(2+lines) : print rankName$
locate percentXpos-2, rankNameYpos+(i-1)*(2+lines) : print "0"
locate oddsXpos-2, rankNameYpos+(i-1)*(2+lines) : print "%"
' locate rankNameXpos, rankNameYpos+(i-1)*(2+lines)+1 : print " (Calculated)"
locate rankNameXpos, rankNameYpos+(i-1)+11 : print rankName$
locate percentXpos, rankNameYpos+(i-1)+11 : print using("###.######", rankCalculatedProbability)
locate oddsXpos-2, rankNameYpos+(i-1)+11 : print "%"
locate oddsXpos, rankNameYpos+(i-1)+11 : print using("########.###", rankCalculatedOdds)
next i
call makeMoreRandom 100 ' pull out a "random" number (using time$("ms")) of rnd() so it's "more" random
' Before adding makeMoreRandom, I had trouble with this program giving the exact same "random" result
' each time I ran it immediately after opening Just BASIC.
startMS=time$("ms") ' store current milliseconds since midnight to show elapsed time at the end
' start of loop
do
call makeMoreRandom 10 ' makes random numbers "more" random by wasting some of them
gosub [getRandomPokerHand] ' generates a random 5 card poker hand, and sorts it based on card value
totalHands=totalHands + 1
gosub [initializeVariables]
gosub [checkHandRank] ' determines the type of poker hand
rankCount(rank)=rankCount(rank) + 1
gosub [displayResults]
loop until totalHands=limit
elapsedMS=time$("ms")-startMS 'calculates elapsed time in ms
locate rankNameXpos+2, rankNameYpos+10 : print elapsedMS; " ms elapsed"
end ' /////////////// END OF MAIN PROGRAM \\\\\\\\\\\\\\\
function random(hi) ' returns a random number between 1 and hi, inclusive
random=int(rnd(1)*hi)+1
end function
sub makeMoreRandom n ' makes random numbers "more" random by wasting some of them, based on milliseconds since midnight
ti=time$("ms") ' get current milliseconds since midnight
randN=ti-n*int(ti/n) ' set randN to the right most digits, essentially a random number
for i=1 to randN : dummy=rnd(1) : next i ' burn randN random numbers, hopefully making cards "more" random
end sub
[getRandomPokerHand] ' generates a random 5 card poker hand, and sorts it based on card value
card(1)=random(52) : sorted(1)=1 : call getSuitAndValueOfCard 1
for i=2 to 5
do 'until redo is false; i.e. until new card is not the same as another card in the hand
card(i)=random(52) : redo=false
' now to make sure we haven't picked 2 of the exact same card from the deck
for j=1 to i-1
if card(j)=card(i) then redo=true : j=i-1 ' leave loop
next j
loop until redo=false
sorted(i)=i
call getSuitAndValueOfCard i
next i
' now to sort the cards by cardValue and store a pointer to each card in sorted()
for i=1 to 4
for j=i+1 to 5
if cardValue(sorted(i))>cardValue(sorted(j)) then temp=sorted(j) : sorted(j)=sorted(i) : sorted(i)=temp
next j
next i
return
sub getSuitAndValueOfCard i
cardSuit(i)=int((card(i)+12)/13)
cardValue(i)=card(i)-((cardSuit(i)-1)*13)
end sub
[initializeVariables]
for i=1 to 4 : suitCount(i)=0 : next i ' clear out suitCount from previous iteration
flush=true : straight=true
rank=10 ' assume rank is worst possible hand (High Card); this changes if the hand turns out to be a better hand
return
[checkHandRank] ' determines the type of poker hand
' now to check for a flush
flushSuit=cardSuit(1) ' remember the suit of the 1st card, then check cards 2-5 against it
for i=2 to 5
if cardSuit(i)<>flushSuit then flush=false : i=5 ' leave loop
next i
' flush remained true if hand is truly a flush
' now to check for a straight, starting with special case ace-hi straight
aceHiStraight=(cardValue(sorted(1))=1) ' first sorted card must be and ace for an ace-hi straight to be possible
for i=2 to 5 : aceHiStraight=aceHiStraight and (cardValue(sorted(i))=(i+8)) : next i ' 10 thru King
if flush and aceHiStraight then rank=1 : goto [endCheckHandRank] ' royal flush
' I could have just put "return" instead of "goto [endCheckHandRank]" but it just feels wrong to me
if aceHiStraight then rank=6 : goto [endCheckHandRank] ' a non-flush ace-hi straight is still just a straight
' if we're here then the hand is neither a royal flush nor an ace-hi straight
' now to check for a regular (non ace-hi) straight
' since cardValue() is sorted, we can check this sequentially
' first we check the first card; if its 10 or higher, we cannot have a straight
if cardValue(sorted(1))>9 then straight=false : goto [notAStraight]
for i=2 to 5
if cardValue(sorted(i))<>(cardValue(sorted(i-1))+1) then straight=false : i=5 ' exit loop
next i
' straight remained true if hand is truly a straight
if flush and straight then rank=2 : goto [endCheckHandRank] ' straight flush
if straight then rank=6 : goto [endCheckHandRank] ' straight
[notAStraight]
if flush then rank=5 : goto [endCheckHandRank] ' flush
' if we're here then the hand is not a flush or a straight
' now to check for 4-of-a-kind, full-house, etc.
for i=1 to 13 : kindCount(i)=0 : next i ' clear out kindCount() from previous iteration
for i=1 to 5 : kindCount(cardValue(i))=kindCount(cardValue(i)) + 1 : next i ' count up # of each card value
for i=1 to 13
if (rank<>7) and (rank<>9) then if kindCount(i)=2 then rank=9 : pairCard=i ' one pair at least
if kindCount(i)=3 then rank=7 ' 3-of-a-kind at least, maybe full house too
if kindCount(i)=4 then rank=3 : i=13 ' 4-of-a-kind; leave loop
next i
if rank=3 then [endCheckHandRank] ' 4 of a kind
if rank=10 then [endCheckHandRank] ' High Card
' if we're here then hand is 1 pair, 2 pair, 3 of a kind, or full house
if rank<>7 then [onePair] ' send one pair down to check for possible 2 pair
' if we're here then hand is at least 3 of a kind, now to check for full house
for i=1 to 13
if kindCount(i)=2 then rank=4 : i=13 ' leave loop; full house
next i
goto [endCheckHandRank]
[onePair]
' if we're here then hand is at least one pair, now to check for 2 pair
if pairCard=13 then [endCheckHandRank] ' pair of kings; no other pairs are possible
for i=pairCard+1 to 13
if kindCount(i)=2 then rank=8 : i=13 ' leave loop; 2 pair
next i
[endCheckHandRank]
return
[displayResults]
locate rankCountXpos, rankNameYpos-1 : print using("########", totalHands)
locate rankCountXpos, rankNameYpos+(rank-1)*(2+lines) : print using("########", rankCount(rank))
for i=1 to 10
locate percentXpos, rankNameYpos+(i-1)*(2+lines) : print using("###.######", rankCount(i)/totalHands*100)
if rankCount(i) then locate oddsXpos, rankNameYpos+(i-1)*(2+lines) : print using("########.###", totalHands/rankCount(i))
next i
if showHands then [showHand]
return
[showHand] ' displays the last hand of each rank beside the count and percentage for each rank
locate handXpos, rankNameYpos+(rank-1)*(2+lines)
for i=1 to 5
print dispValue$(cardValue(i));dispSuit$(cardSuit(i));" ";
next i
return
I am running on Windows 10 if that matters.
Thanks for any help.