Poker Hand Evaluator Alpha 2 (upd 3/19)

By LIQUID_NiTrO on Mar 10, 2007

Alright, well here it is. Something I've been wanting to do for quite some time but never had the energy or motivation to get through. This is the beginning of hopefully my full script for online mIRC poker (not for real money, of course). Supply this alias with a "board" and an infinite number of "hole" hands, and it will tell you which hand wins and with what. It will also tell you if there is a split. Usage is $handeval(,,..,[handN]) Example: $handeval(JhTd8cAs3c,9hQs,8d8h) -- Evaluates two hands using the provided board. The first hand will win with a Queen high straight against the second hand's 3 of a kind 8's. You may also call this alias as a command, and it will echo the result to the active window. I AM LOOKING FOR PEOPLE TO HELP ME IMPROVE THIS SNIPPET AND HELP CODE ADDITIONAL PARTS OF THE REST OF THE SCRIPT. PM ME IF YOU ARE INTERESTED! Edit 3/10/07 - Full House collision problem fixed. Flush evaluation improved. Edit 3/19/07 - Kicker functionality added.

alias sortwithintok {
  var %n = $remove($1,s,c,d,h)
  var %s1 = $sorttok(%n,45,nr)
  var %x = 1,%y = $numtok(%s1,45)
  var %nl = $1
  while ( %x <= %y ) {
    if ( $istok(%nl,$gettok(%s1,%x,45) $+ s,45) && !$istok(%s1,$gettok(%s1,%x,45) $+ s,45) ) {
      %s1 = $reptok(%s1,$gettok(%s1,%x,45),$gettok(%s1,%x,45) $+ s,1,45)
    }
    elseif ( $istok(%nl,$gettok(%s1,%x,45) $+ c,45) && !$istok(%s1,$gettok(%s1,%x,45) $+ c,45) ) {
      %s1 = $reptok(%s1,$gettok(%s1,%x,45),$gettok(%s1,%x,45) $+ c,1,45)
    }
    elseif ( $istok(%nl,$gettok(%s1,%x,45) $+ h,45) && !$istok(%s1,$gettok(%s1,%x,45) $+ h,45) ) {
      %s1 = $reptok(%s1,$gettok(%s1,%x,45),$gettok(%s1,%x,45) $+ h,1,45)
    }
    elseif ( $istok(%nl,$gettok(%s1,%x,45) $+ d,45) && !$istok(%s1,$gettok(%s1,%x,45) $+ d,45) ) {
      %s1 = $reptok(%s1,$gettok(%s1,%x,45),$gettok(%s1,%x,45) $+ d,1,45)
    }
    inc %x 1
  }
  return %s1
}
alias handeval {
  ;SYNTAX: $handeval(board,hand1,..,handN)
  ;Returns a value of 1-N for the best poker hand
  ;If there is a split, it will separate the hands that split with spaces, ex 1 3 4 for a 3-way split between hands 1, 3, and 4.

  ;LEFTOFF- Problem with unnecessary report of a kicker with two pair.
  ;Unextensively tested
  ;Demo command- //echo f $handeval(AhTsJd7c9d,Ac7s,AdQh).debug

  var %board = $1
  tokenize 32 $replace($2-,t,10,j,11,q,12,k,13,a,14)

  var %x = $0
  set -l %tt
  while ( %x ) {
    set -l %hp [ $+ [ %x ] ] $replace(%board $+ $ [ $+ [ %x ] ],t,10,j,11,q,12,k,13,a,14)
    .echo -q $regsub(%hp [ $+ [ %x ] ],/([a-z])/ig,\1 $+ -,%tt)
    set -l %hp [ $+ [ %x ] ] $sortwithintok(%tt)
    set -l %hv [ $+ [ %x ] ] $replace(%hp [ $+ [ %x ] ],s,-,c,-,d,-,h,-)
    %hv [ $+ [ %x ] ] = $sorttok(%hv [ $+ [ %x ] ],45,nr)
    set -l %hs [ $+ [ %x ] ] $replace(%hp [ $+ [ %x ] ],1,-,2,-,3,-,4,-,5,-,6,-,7,-,8,-,9,-,0,-)
    %hs [ $+ [ %x ] ] = $sorttok(%hs [ $+ [ %x ] ],45)
    dec %x
  }
  if ( $prop == debug ) {
    echo hp1 %hp1
    echo hp2 %hp2
    echo hs1 %hs1
    echo hs2 %hs2
    echo hv1 %hv1
    echo hv2 %hv2
    echo --
  }
  var %x = 1,%b = 0,%v = 0,%s = 0
  set -l %tv
  set -l %slist
  set -l %fhv
  set -l %tfhv
  set -l %fl1
  set -l %fl2
  set -l %fl3
  set -l %fl4
  ;B values
  ;8 = Straight Flush
  ;7 = Quads
  ;6 = Boat
  ;5 = Flush
  ;4 = Straight
  ;3 = Trips
  ;2 = Two Pair
  ;1 = Pair
  ;0 = Highcard
  while ( %x <= $0 ) {
    if ( $issf(%hp [ $+ [ %x ] ]) ) {
      %tv = $v1
      if ( %b == 8 ) {
        if ( %tv > %v ) {
          %v = %tv
          %s = 1
          set -l %fhv
          set -l %slist %x
          inc %x
          continue
        }
        elseif ( %tv == %v ) {
          inc %s
          %slist = $addtok(%slist,%x,32)
          set -l %fhv
          inc %x
          continue
        }
        else {
          %s = 1
          set -l %slist %x
          set -l %fhv
          inc %x
          continue
        }
      }
      else {
        %b = 8
        %v = %tv
        %s = 1
        set -l %slist %x
      }
      inc %x
      continue
    }
    if ( %b > 7 ) {
      inc %x
      continue
    }
    var %d = $dupfinder(%hv [ $+ [ %x ] ])
    if ( $wildtok(%d,*:4,1,32) ) {
      %tv = $gettok($wildtok(%d,*:4,1,32),1,58)
      if ( %b == 7 ) {
        if ( %tv > %v ) {
          %v = %tv
          %s = 1
          set -l %fhv
          set -l %slist %x
          inc %x
          continue
        }
        elseif ( %tv == %v ) {
          inc %s
          %slist = $addtok(%slist,%x,32)
        }
      }
      else {
        %b = 7
        %s = 1
        %v = %tv
        set -l %slist %x
        set -l %fhv
      }
      inc %x
      continue
    }
    if ( %b > 6 ) {
      inc %x
      continue
    }
    if ( $numtok(%d,32) > 1 ) {
      if ( $wildtok(%d,*:2,0,32) && $wildtok(%d,*:3,0,32) ) || ( $wildtok(%d,*:3,0,32) > 1 ) {
        if ( $wildtok(%d,*:2,1,32) ) {
          %tv = $gettok($wildtok(%d,*:3,1,32),1,58)
          %tfhv = $gettok($wildtok(%d,*:2,1,32),1,58)
        }
        else {
          if ( $gettok($wildtok(%d,*:3,1,32),1,58) > $gettok($wildtok(%d,*:3,2,32),1,58) ) {
            %tv = $gettok($wildtok(%d,*:3,1,32),1,58)
            %tfhv = $gettok($wildtok(%d,*:3,2,32),1,58)
          }
          else {
            %tv = $gettok($wildtok(%d,*:3,2,32),1,58)
            %tfhv = $gettok($wildtok(%d,*:3,1,32),1,58)
          }
        }
        if ( %b == 6 ) {
          if ( %tv > %v ) {
            %v = %tv
            %fhv = %tfhv
          }
          elseif ( %tv == %v ) {
            if ( %fhv < $gettok($wildtok(%d,*:2,1,32),1,58) ) {
              %v = %tv
              %s = 1
              set -l %slist %x
              inc %x
              continue
              %fhv = %tfhv
            }
            elseif ( %fhv == $gettok($wildtok(%d,*:2,1,32),1,58) ) {
              inc %s
              %slist = $addtok(%slist,%x,32)
            }
          }
          else {
            inc %x
            continue
          }
        }
        else {
          %b = 6
          %v = %tv
          %s = 1
          set -l %slist %x
          %fhv = %tfhv
          inc %x
          continue
        }
      }
    }
    if ( %b > 5 ) {
      inc %x
      continue
    }
    if ( $isflush(%hs [ $+ [ %x ] ]) ) {
      set -l %asdf $v1
      %tv = $hcs(%hp [ $+ [ %x ] ],%asdf)
      var %z = 1
      while ( %z <= 4 ) {
        set -l %tfl [ $+ [ %z ] ] $hcs($deltok(%hp [ $+ [ %x ] ],1- %z,45),%asdf)
        if ( %tfl [ $+ [ %z ] ] > %fl [ $+ [ %z ] ] ) {
          var %iw = 1
        }
        elseif ( %tfl [ $+ [ %z ] ] < %fl [ $+ [ %z ] ] ) {
          var %icl = 1
        }
        inc %z
      }
      if ( %b == 5 ) {
        if ( %tv == %v ) {
          if ( %iw ) {
            %v = %tv
            %fl1 = %tfl1
            %fl2 = %tfl2
            %fl3 = %tfl3
            %fl4 = %tfl4
            %s = 1
            set -l %slist %x
            inc %x
            continue
          }
          elseif ( %icl ) {
            inc %x
            continue
          }
          else {
            inc %s
            set -l %slist $addtok(%slist,%x,32)
            inc %x
            continue
          }
        }
        elseif ( %tv > %v ) {
          %v = %tv
          %fl1 = %tfl1
          %fl2 = %tfl2
          %fl3 = %tfl3
          %fl4 = %tfl4
          %s = 1
          set -l %slist %x
          inc %x
          continue
        }
        else {
          inc %x
          continue
        }
      }
      else {
        %b = 5
        %v = %tv
        %fl1 = %tfl1
        %fl2 = %tfl2
        %fl3 = %tfl3
        %fl4 = %tfl4
        %s = 1
        set -l %slist %x
        inc %x
        continue
      }
    }
    if ( %b > 4 ) {
      inc %x
      continue
    }
    if ( $isstraight(%hv [ $+ [ %x ] ]) ) {
      %tv = $v1
      if ( %b == 4 ) {
        if ( %tv > %v ) {
          %v = %tv
          %s = 1
          set -l %slist %x
          inc %x
          continue
        }
        elseif ( %tv == %v ) {
          inc %s
          %slist = $addtok(%slist,%x,32)
          inc %x
          continue
        }
        else {
          inc %x
          continue
        }
      }
      else {
        %b = 4
        %v = %tv
        %s = 1
        set -l %slist %x
        inc %x
        continue
      }
    }
    if ( %b > 3 ) {
      inc %x
      continue
    }
    if ( $wildtok(%d,*:3,1,32) ) {
      %tv = $gettok($v1,1,58)
      if ( %b == 3 ) {
        if ( %tv > %v ) {
          %v = %tv
          %s = 1
          set -l %slist %x
          inc %x
          continue
        }
        elseif ( %tv == %v ) {
          inc %s
          %slist = $addtok(%slist,%x,32)
          inc %x
          continue
        }
        else {
          inc %x
          continue
        }
      }
      else {
        %b = 3
        %s = 1
        %v = %tv
        set -l %slist %x
        inc %x
        continue
      }
    }
    if ( %b > 2 ) {
      inc %x
      continue
    }
    if ( $numtok(%d,32) > 1 ) {
      if ( $wildtok(%d,*:2,0,32) == 2 ) {
        %tv = $gettok($iif($wildtok(%d,*:2,1,32) < $wildtok(%d,*:2,2,32),$wildtok(%d,*:2,1,32),$wildtok(%d,*:2,2,32)),1,58)
        %tfhv = $gettok($iif($wildtok(%d,*:2,1,32) > $wildtok(%d,*:2,2,32),$wildtok(%d,*:2,1,32),$wildtok(%d,*:2,2,32)),1,58)
        if ( %b == 2 ) {
          if ( %tv > %v ) {
            %v = %tv
            %fhv = %tfhv
            %s = 1
            set -l %slist %x
            inc %x
            continue
          }
          elseif ( %tv == %v ) {
            if ( %tfhv > %fhv ) {
              %v = %tv
              %fhv = %tfhv
              %s = 1
              set -l %slist %x
              inc %x
              continue
            }
            elseif ( %tfhv == %fhv ) {
              inc %s
              %slist = $addtok(%slist,%x,32)
            }
          }
          else {
            inc %x
            continue
          }
        }
        else {
          %b = 2
          %v = %tv
          %fhv = %tfhv
          %s = 1
          set -l %slist %x
          inc %x
          continue
        }
      }
    }
    if ( %b > 1 ) {
      inc %x
      continue
    }
    if ( $gettok(%d,1,58) >= %v && $gettok(%d,1,58) != 0 ) {
      if ( %b == 1 ) {
        if ( $gettok(%d,1,58) > %v ) {
          %v = $gettok(%d,1,58)
          %s = 1
          set -l %slist %x
        }
        else {
          inc %s
          %slist = $addtok(%slist,%x,32)
        }
        inc %x
        continue
      }
      %b = 1
      %s = 1
      set -l %slist %x
      %v = $gettok(%d,1,58)
      inc %x
      continue
    }
    if ( %b > 0 ) {
      inc %x
      continue
    }
    %tv = $gettok(%hv [ $+ [ %x ] ],1,45)
    var %z = 2
    while ( %z <= 7 ) {
      set -l %tfl [ $+ [ %z ] ] $gettok(%hv [ $+ [ %x ] ],%z,45)
      if ( %tfl [ $+ [ %z ] ] > %fl [ $+ [ $calc(%z -1) ] ] ) && ( !%iw ) {
        var %iw = %tfl [ $+ [ %z ] ]
      }
      elseif ( %tfl [ $+ [ %z ] ] < %fl [ $+ [ $calc(%z -1) ] ] ) && ( !%icl ) {
        var %icl = %fl [ $+ [ $calc(%z -1) ] ]
      }
      inc %z
    }
    if ( %tv > %v ) {
      %v = %tv
      %fl1 = %tfl2
      %fl2 = %tfl3
      %fl3 = %tfl4
      %fl4 = %tfl5
      %s = 1
      set -l %slist %x
      inc %x 1
      continue
    }
    elseif ( %tv == %v ) {
      if ( %iw ) {
        var %kicker = %iw
        %v = %tv
        %fl1 = %tfl1
        %fl2 = %tfl2
        %fl3 = %tfl3
        %fl4 = %tfl4
        %s = 1
        set -l %slist %x
        inc %x
        continue
      }
      elseif ( %icl ) {
        var %kicker = %icl
        inc %x
        continue
      }
      else {
        inc %s
        set -l %slist $addtok(%slist,%x,32)
        inc %x
        continue
      }
      inc %s
      %slist = $addtok(%slist,%x,32)
      inc %x 1
      continue
    }
    inc %x 1
  }
  if ( %s > 1 ) {
    var %x = %s,%upd = 0,%chgd = 0
    var %fl1 = %v
    set -l %fl2
    set -l %fl3
    set -l %fl4
    set -l %fl5
    while ( %x ) {
      var %z = 1
      while ( %z <= 5 ) {
        set -l %tfl [ $+ [ %z ] ] $gettok(%hv [ $+ [ %x ] ],%z,45)
        ;Good debugging echo for problems with kicker determination and split pot evaluation
        ;echo x %x it %z fl %fl [ $+ [ %z ] ] tfl %tfl [ $+ [ %z ] ]
        if ( %fl [ $+ [ %z ] ] < %tfl [ $+ [ %z ] ] ) || ( !%fl [ $+ [ %z ] ] ) {
          if ( !%fl [ $+ [ %z ] ] ) {
            %fl [ $+ [ %z ] ] = %tfl [ $+ [ %z ] ]
          }
          else {
            var %slist = %x
            var %chgd = 1
            var %upd = %tfl [ $+ [ %z ] ]
            %s = 1
          }
        }
        elseif ( %fl [ $+ [ %z ] ] > %tfl [ $+ [ %z ] ] ) && ( !%chgd ) {
          dec %s
          var %slist = $deltok(%slist,%x,32)
          var %kicker = %fl [ $+ [ %z ] ]
          break
        }
        elseif ( %chgd ) {
          inc %s
          var %slist = $addtok(%slist,%x,32)
        }
        if ( %upd ) {
          var %kicker = %upd
          %fl1 = %tfl1
          %fl2 = %tfl2
          %fl3 = %tfl3
          %fl4 = %tfl4
          %fl5 = %tfl5
        }
        var %upd = 0
        set -l %chgd
        inc %z
      }
      dec %x
    }
  }
  $iif($isid,return,echo -a) $iif(%s > 1,%s $+ -way split between hands numbers,Winner is hand number) $replace(%slist,$chr(32),$chr(44)) with $replace(%b,0,Highcard,1,Pair,2,TwoPair,3,Trips,4,Straight,5,Flush,6,FullHouse,7,Quads,8,StraightFlush) $replace(%v,10,Ten,11,Jack,12,Queen,13,King,14,Ace) $iif(%fhv,over $replace(%fhv,10,Tens,11,Jacks,12,Queens,13,Kings,14,Aces)) $iif(%kicker,- $replace(%kicker,10,Ten,11,Jack,12,Queen,13,King,14,Ace) kicker)
  return
}
;Format- Winners WinnerList Hand Highcard NextHighCard Kicker
;Winners is the number of winners (more than 1 indicates a split pot)
;WinnerList is a comma separated list of the winners (there will only be one value unless there's a split)
;Hand will be in the format of %b - See above notes
;NextHighCard is only used for Full Houses and Two Pairs.  It will be 0 if the winning hand was not a Full House or Two Pair.
;Kicker may or may not have a value
return %s %slist %b %v $iif(%fhv,%fhv,0) %kicker
}
alias dupfinder {
;SYNTAX: $dupfinder(text)
;text should be in %hvX format
;Returns sets of duplicates or 0 if there are no duplicates (used for finding pair, two pair, 3 of a kind, full house, 4 of a kind)
;Return format is value:duplicates where value is the "card" and duplicates is the number of duplicates found
;One or two sets of duplicates may be returned.  If it's two, they are space separated
;Ex if it returns 9:3 5:2 this indicates a full house with 3 nines and 2 fives

var %x = 1,%h = 99
var %asdf = $calc($len($remove($1,1,2,3,4,5,6,7,8,9,0)) +1)
set -l %l
set -l %m
while ( %x <= %asdf ) {
  if ( !$wildtok(%l,$gettok($1,%x,45) $+ :*,0,32) ) {
    %l = $addtok(%l,$gettok($1,%x,45),32) $+ :1
  }
  else {
    var %a = $wildtok(%l,$gettok($1,%x,45) $+ :*,1,32)
    var %l = $reptok(%l,%a,$gettok(%a,1,58) $+ : $+ $calc($gettok(%a,2,58) +1),1,32)
    var %m = $iif($istok(%m,%a,32),$reptok(%m,%a,$gettok(%a,1,58) $+ : $+ $calc($gettok(%a,2,58) +1),1,32),$addtok(%m,$gettok(%a,1,58) $+ : $+ $calc($gettok(%a,2,58) +1),32))
    if ( $gettok(%a,1,58) < %h ) %h = $gettok(%a,1,58)
  }
  inc %x
}
if ( $numtok(%m,32) > 2 ) {
  %m = $remtok(%m,$wildtok(%m,%h $+ :*,1,32),32)
}
return $iif(%m,%m,0)
}
alias isstraight {
;SYNTAX: $isstraight(text)
;Text should be in %hvX format
;NOTE- Text *MUST* be sorted descendingly!
;Returns highest card of the straight or 0 if there is no straight

var %x = 1
set -l %v
set -l %c
while ( %x <= $numtok($1,45) ) {
  if ( $gettok($1,%x,45) == 14 ) set -l %ha 1
  if ( $gettok($1,%x,45) == %v ) {
    inc %x
    continue
  }
  if ( $gettok($1,%x,45) == $calc(%v -1) ) {
    if ( %ha ) && ( %c == 3 ) && ( $gettok($1,%x,45) == 2 ) {
      %v = 2
      %c = 5
      break
    }
    inc %c
    if ( %c == 5 ) break
    dec %v
  }
  else {
    %c = 1
    %v = $gettok($1,%x,45)
  }
  inc %x
}
return $iif(%c == 5,$calc(%v +3),0)
}
alias isflush {
;Returns suit character (s,h,d,c) of a flush if there is one
;If there is no flush returns 0
;Should be formatted in %hsX

var %x = 1,%asdf = $calc($len($remove($1,s,c,d,h)) +1)
var %c = 0
var %h = 0
var %s = 0
var %d = 0
while ( %x <= %asdf ) {
  inc % [ $+ [ $gettok($1,%x,45) ] ]
  inc %x
}
if ( %c >= 5 ) return c
elseif ( %h >= 5 ) return h
elseif ( %s >= 5 ) return s
elseif ( %d >= 5 ) return d
else return 0
}
alias issf {
;Returns high card of a straight flush if there is one
;Returns 0 if there is no straight flush
;Should be formatted as %hpX

var %a = $isstraight($remove($1,s,c,d,h))
var %b = $isflush($remove($1,0,1,2,3,4,5,6,7,8,9))
if ( !%a ) || ( !%b ) {
  return 0
}
var %x = 1,%s = 0
while ( %x > 5 ) {
  if ( !$findtok($1,$calc(%a - %s) $+ %b,0,45) ) {
    return 0
    break
  }
  inc %s
  dec %x
}
inc %s
return %a
}
alias hcs {
;Syntax: $hcs(text,suit)
;Returns the highest card of a particular suit in a hand
;Used to find a flush's high card.
;Text should be formatted as hpX

var %x = 1,%h = 0
while ( %x <= $numtok($1,45) ) {
  if ( $2 !isin $gettok($1,%x,45) ) {
    inc %x
    continue
  }
  elseif ( $remove($gettok($1,%x,45),s,h,d,c) > %h ) { 
    %h = $remove($gettok($1,%x,45),s,h,d,c)
  }
  inc %x
}
return %h
}

Comments

Sign in to comment.
Pass   -  Mar 10, 2007

Great, original idea, LIQUID_NiTrO! This snippet has the potential to be a great game. Seeing snippets like this is rare around here lately.

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.