Poker hand analyser: Difference between revisions

m
→‎{{header|REXX}}: added/changed comments, simplified the function.
m (used more consistent indentations in the task's preamble.)
m (→‎{{header|REXX}}: added/changed comments, simplified the function.)
Line 1,759:
2x 2h 3h 4h 5h Error: invalid suit x in 2x</pre>
 
===version 2 with suit glyphs===
This REXX version supports:
::* &nbsp; upper/lower/mixed case for suits and pips
::* &nbsp; allows commas or blanks for card separation
::* &nbsp; alternate names for a aces and tens
::* &nbsp; alphabetic letters for suits and/or glyphs
::* &nbsp; specification of number of cards in a hand
::* &nbsp; the dealt hands can be in a file &nbsp; (blank lines are ignored)
::* &nbsp; dealt hands in the file can have comments after a semicolon (''';''')
<lang rexx>/*REXX program analyzes an N-card poker hand, and displays what the poker hand is. */
parse arg iFID .; if iFID=='' | iFID=="," then iFID='POKERHAN.DAT'
/* [↓] read the poker hands dealt. */
do while lines(iFID)\==0; ox=linein(iFID); if ox='' then iterate
say right(ox, max(30, length(ox) ) ) ' ◄─── ' analyze(ox)
end /*while*/ /* [↑] analyze/validate the poker hand.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────ANALYZE subroutine──────────────────*/
analyze: procedure; arg x ';',mc; hand=translate(x, '♥♦♣♠1', "HDCSA,")
kinds=0; suit.=0; flush=0; pairs=0; @.=0; run=copies(0 ,13); pips=run
if mc=='' then mc=5; n=words(hand); if n\==mc then return 'invalid'
/* [↓] PIP can be 1 or 2 chars characters.*/
do j=1 for n; _=word(hand, j); pip=left(_,length(_)-1); ws=right(_,1) /*obtain a card from the dealt hand. */
if pip==10left(_, length(_)-1); then pip='T' ws=right(_, 1) /*obtain the card's pip; /*allow alternate form forget athe TENsuit.*/
if pip==10 then pip='T' /*allow an alternate form for a "TEN". */
@._=@._+1; #=pos(pip, 123456789TJQK) /*bump the card ctrcounter, get pip index.*/
if pos(ws, "♥♣♦♠")==0 | #==0 | @._\==1 then return 'invalid'
suit.ws=suit.ws+1; flush=max(flush,suit.ws) /*count suits for a flush; run=overlay(.,run,find #) suits*/
_=substr(pips,#,1)+1; pips=overlay(_,pips, #); kinds=max(kinds,_)
run=overlay(.,run,#); _=substr(pips,#,1)+1 /*convert run to series of dots. */
end /*i*/ /*keep track of N-of-a-kind. [↑] */
pips=overlay(_,pips,#); kinds=max(kinds,_) /*convert certain pips to their number.*/
end /*i*/ /* [↑] keep track of N-of-a-kind. [↑] */
 
pairs=countstr(2, pips) /*count #number of pairs (2s in PIPS).*/
straight=pos(....., run || left(run, 1))\==0 /*does the RUN contains a straight? */
if flush==5 & straight then return 'straight-flush'
select
if kinds==4 when flush==5 & straight then return 'straightfour-of-a-flushkind'
whenif kinds==4 3 & pairs==1 then return 'four-of-afull-kindhouse'
if flush==5 when kinds==3 & pairs==1 then return 'full-houseflush'
if when flush==5 straight then return 'flushstraight'
if kinds==3 when straight then return 'straightthree-of-a-kind'
whenif kinds==3 2 & pairs==2 then return 'three-of-atwo-kindpair'
if kinds==2 when kinds==2 & pairs==2 then return 'twoone-pair'
when kinds==2 then return 'onehigh-paircard'</lang>
otherwise return 'high-card'
end /*select*/</lang>
Programming note: some older REXXes don't have the '''countstr''' BIF, so that REXX statement (above, line 21) can be replaced with:
<lang rexx>pairs=13-length(space(translate(pips,,2),0)) /*count # of 2's in PIPS.*/</lang>
Line 1,818:
ah 2h 3h 4h
</pre>
{{out}}'''output''' &nbsp; when using the (above) input file:
<pre>
2♥ 2♦ 2♠ k♠ q♦ ◄─── three-of-a-kind
Line 1,833:
</pre>
 
===version 3 (with suit glyphs and jokers)===
This REXX version has three additional features:
::* &nbsp; "invalid" hands have additional diagnostic information
::* &nbsp; supports up to two ''jokers''
::* &nbsp; the ''joker'' card may be abbreviated (and can be in upper/lower/mixed case)
<lang rexx>/*REXX program analyzes an N-card poker hand, and displays what the poker hand is., */
/*─────────────────────────────────────────────────────────────────────────── poker hands may contain up to 2two jokers.*/
parse arg iFID .; if iFID=='' | iFID=="," then iFID='POKERHAJPOKERHAN.DAT'
/* [↓] read the poker hands dealt. */
do while lines(iFID)\==0; ox=linein(iFID); if ox='' then iterate
say right(ox, max(30, length(ox) ) ) ' ◄─── ' analyze(ox)
end /*while*/ /* [↑] analyze/validate the poker hand.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────ANALYZE subroutine──────────────────*/
analyze: procedure; arg x ';',mc; hand=translate(x, '♥♦♣♠1', "HDCSA,")
kinds=0; suit.=0; flush=0; pairs=0; @.=0; run=copies(0 ,13); pips=run
if mc=='' then mc=5; n=words(hand) /*N is the #number of cards in hand. */
if n\==mc then return 'invalid number of cards, must be' mc
/* [↓] the PIP can be 1 or 2 chars. */
do j=1 for n; _=word(hand,j); pip=left(_,length(_)-1); ws=right(_,1) /*obtain a card from the dealt hand. */
if pip==10left(_, length(_)-1); then pip ws='T' right(_, 1) /*allowobtain alternatecard's formpip; forobtain acard's TENsuit*/
if pip==10 if abbrev('JOKER',_,1) then _pip="JK"'T' /*allow alternamealternate form for a formsTEN of JOKERpip.*/
if abbrev('JOKER',_,1) then _="JK" /*allow altername forms of JOKER names.*/
@._=@._+1; #=pos(pip,123456789TJQK) /*bump card ctrcounter, get the pip index.*/
if _=='JK' then do
if _=='JK' then do; if @.j>2 then return 'invalid, too many jokers'
iterate
end
if pos(ws, "♥♣♦♠")==0 then return 'invalid suit in card:' _
if #==0 then return 'invalid pip in card:' _
if @._\==1 then return 'invalid, duplicate card:' _
suit.ws=suit.ws+1; flush=max(flush,suit.ws) /*count suits for a flush; run=overlay(.,run,find #) suits*/
run=overlay(.,run,#); _=substr(pips,#,1)+1; pips=overlay(_,pips,/*convert #);run to kinds=max(kinds,_)series of dots. */
pips=overlay(_,pips,#); kinds=max(kinds,_) /*convert certain pips to their number.*/
end /*i*/ /*keep track of N-of-a-kind. [↑] */
end /*i*/ otherwise return /* 'high[↑] keep track of N-card'of-a-kind. */
 
run=run || left(run, 1) /*AceAn ace can be high -or- low. */
jok=@.jk; kinds=kinds+jok; flush=flush+jok /*N-of-a-kind,N─of─a─kind; adjustments jokerfor adjustjokers.*/
straight= pos(..... , run)\==0 |, /*does the RUN containscontain a straight? */
(pos(.... , run)\==0 & jok>=1) |, /* " " " " " " */
(pos(..0.. , run)\==0 & jok>=1) |, /* " " " " " " */
(pos(...0. , run)\==0 & jok>=1) |, /* " " " " " " */
(pos(.0... , run)\==0 & jok>=1) |, /* " " " " " " */
(pos(... , run)\==0 & jok>=2) |, /* " " " " " " */
(pos(..0. , run)\==0 & jok>=2) |, /* " " " " " " */
(pos(.0.. , run)\==0 & jok>=2) |, /* " " " " " " */
(pos(.00.. , run)\==0 & jok>=2) |, /* " " " " " " */
(pos(..00. , run)\==0 & jok>=2) |, /* " " " " " " */
(pos(.0.0. , run)\==0 & jok>=2) /* " " " " " " */
pairs=countstr(2, pips) /*count #number of pairs (2s in PIPS). */
if jok\==0 then pairs=pairs-1 /*adjust #number of pairs with jokers. */
if kinds>=5 then return select'five-of-a-kind'
if when kindsflush>=5 & straight then return 'five-of-astraight-kindflush'
if kinds>=4 when flush>=5 & straight then return 'straightfour-of-a-flushkind'
whenif kinds>=4 3 & pairs>=1 then return 'four-of-afull-kindhouse'
if flush>=5 when kinds>=3 & pairs>=1 then return 'full-houseflush'
if when flush>=5 straight then return 'flushstraight'
if kinds>=3 when straight then return 'straightthree-of-a-kind'
whenif kinds>=3 =2 & pairs==2 then return 'three-of-atwo-kindpair'
if kinds==2 when kinds==2 & pairs==2 then return 'twoone-pair'
when kinds==2 then return 'onehigh-paircard'</lang>
when kinds==2 then return 'one-pair'
otherwise return 'high-card'
end /*select*/</lang>
Programming note: the method used for analyzing hands that contain jokers are limited to a maximum of two jokers.
<br>A different methodology would be needed for a generic number of jokers (and/or wild cards [such as deuces and one-eyed jacks]).
 
'''input file''':
Line 1,924 ⟶ 1,922:
J♥ Q♦ K♠ A♠ jok
</pre>
{{out}}'''output''' &nbsp; when using the (above) input file:
<pre>
joker 2♦ 2♠ k♠ q♦ ◄─── three-of-a-kind