mIRC Home    About    Download    Register    News    Help

Print Thread
hand recognition #141043 04/02/06 12:38 AM
Joined: Mar 2005
Posts: 212
N
NeUtRoN_StaR Offline OP
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Mar 2005
Posts: 212
im stuck on getting mirc to recognize various hands
card format A-S,10-C,etc.,

i originally wanted to just have a list of the hands possible and have it check against that, upon doing some research i heard theres about 2 million hands so that became unusable

so i guess i would have to have mirc recognize aspects of a hand
something like this
Code:
var %x = 1
while (%x <= $numtok(%players,44)) {
if ($wildtok($($+(%,player.,$gettok(%players,%x,44)),2),*-S,0,44) >= 5) {
set $+(%,player.,$gettok(%players,%x,44),.,hand) flush
inc %x
}

but then it has to take into account the highest card in the flush and kickers with other hands

any help is appreciated

hand list
royal flush
straight flush
4 of a kind
full house
flush
straigh
3 of a kind
2 pair
1 pair
high card

Last edited by NeUtRoN_StaR; 04/02/06 12:41 AM.
Re: hand recognition #141044 04/02/06 01:41 AM
Joined: Oct 2005
Posts: 1,741
G
genius_at_work Offline
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
You will probably have to make algorithms that can check for the existance of each type of hand and the strength of the hand.

To compare the hands, the algorithms could assign each hand a two-part score. The first part of the score would be the rank of the hand as you have shown above (high card = 1, 1 pair = 2, etc..). The second score would be the strength of the hand compared to other hands of the same type (pair of 2s = 1, pair of 3s = 2, etc). Then you just have to sort the first set of scores (and the second set if there are more than one of a particular type of hand).

-genius_at_work

Re: hand recognition #141045 04/02/06 01:53 AM
Joined: Mar 2005
Posts: 212
N
NeUtRoN_StaR Offline OP
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Mar 2005
Posts: 212
yep dont know anything about algorhythms
example maybe?

Re: hand recognition #141046 04/02/06 06:11 AM
Joined: Oct 2005
Posts: 1,741
G
genius_at_work Offline
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
I was bored.. :P

Code:
hand {
  ;var %hand = 2-S.1-C.13-C.4-D.8-H
  ;var %hand = 2-S.A-C.K-C.4-D.8-H
  var %hand = $$1

  echo -a -
  echo 3 -a Cards: %hand

  var %sa = 1, %sb, %t

  ; Check for high card, 1 pair, 2 pair, 3 of a kind, 4 of a kind, full house
  %t = $remove(%hand,-C,-D,-H,-S)
  %t = $replace(%t,J,11,Q,12,K,13,A,14)
  %t = $sorttok(%t,46,nr)

  var %c = 15, %w
  while (%c > 0) {
    dec %c
    %w = $wildtok(%t,%c,0,46)

    if (%w == 4) {
      %sa = 8
      %sb = $instok(%sb,%c,1,46)
    }

    ;3 matching cards
    elseif (%w == 3) {

      ;Full house
      if (%sa == 2) {
        %sa = 7
        %sb = $instok(%sb,%c,1,46)
      }

      ;3 of a kind
      elseif (%sa <= 4) {
        %sa = 4
        %sb = $instok(%sb,%c,1,46)
      }
    }

    ;2 matching cards
    elseif (%w == 2) {

      ;Full house
      if (%sa == 4) {
        %sa = 7
        %sb = $instok(%sb,%c,2,46)
      }

      ;2 pair
      elseif (%sa == 2) {
        %sa = 3
        %sb = $instok(%sb,%c,2,46)
      }

      ;1 pair
      elseif (%sa <= 2) {
        %sa = 2
        %sb = $instok(%sb,%c,1,46)
      }
    }

    ;1 matching card and no other matches
    elseif (%w == 1) {
      %sb = $addtok(%sb,%c,46)
    }

    ;remove current card from hand
    while ($istok(%t,%c,46)) %t = $remtok(%t,%c,1,46)
  }
  if (%t != $null) echo -a Invalid card(s): %t



  ;Check for straight, straight flush, royal flush

  var %suits = $remove(%hand,14,13,12,11,10,9,8,7,6,5,4,3,2,1,A,K,Q,J)
  var %f = $iif($count(%suits,$gettok(%suits,1,46)) >= 5,1,0)

  %t = $remove(%hand,-C,-D,-H,-S)
  %t = $replace(%t,J,11,Q,12,K,13,A,1.14)
  %t = $sorttok(%t,46,nr)

  var %s = 0, %prevcard, %card, %c = 0

  while (%c < 6) {
    inc %c
    %card = $gettok(%t,%c,46)

    if ((!%prevcard) || (%card == $calc(%prevcard - 1))) inc %s
    %prevcard = %card

  }

  if ($gettok(%t,1,46) == 14) {
    if ($gettok(%t,2,46) == 13) %t = $deltok(%t,6,46)
    else %t = $deltok(%t,1,46)
  }

  ;5 sequential cards
  if (%s >= 5) {

    ;royal flush
    if ((%f) && (%t == 14.13.12.11.10)) %sa = 10

    ;straight flush
    elseif (%f) %sa = 9

    ;straight
    elseif (%sa <= 5) %sa = 5

    %sb = %t
  }
  ;flush
  elseif ((%sa <= 6) && (%f)) {
    %sa = 6
    %sb = %t
  }


  var %hands = High Card,One Pair,Two Pairs,Three of a Kind,Straight,Flush,Full House,Four of a Kind,Straight Flush,Royal Flush
  echo 5 -a Hand: $gettok(%hands,%sa,44) 
  echo 7 -a Comparison: %sb

  return %sa $+ : %sb

}


Usage: $hand(<card>-<suit>.<card>-<suit>.<card>-<suit>.<card>-<suit>.<card>-<suit>)
Returns: <hand score>:<comparison string>

Example 1: $hand(A-C.Q-C.K-C.10-C.J-C)
Result 1: 10:14.13.12.11.10

Example 2: $hand(2-H.6-D.8-S.2-S.K-C)
Result 2: 2:2.13.8.6

The identifier accepts 2-10 and A,J,Q,K for card values and C,D,H,S for suit values. Ace (1) is tested as high and low in straights, and considered high in pairs, etc. Note that there is no error checking to ensure that the values given to this identifier are valid. Invalid values will return unexpected results.

The <hand score> returned is a number from 1-10 that corresponds to "(1) High Card,One Pair,Two Pairs,Three of a Kind,Straight,Flush,Full House,Four of a Kind,Straight Flush,Royal Flush (10)".

The <comparison string> is has a different format for different <hand scores>. The relevant numbers are farthest to the left, and the extra numbers are farthest right. The number of relevant and extra numbers varies depending on the hand. In most of the hands in poker, if the relevant cards (pairs, three of a kind, etc) are a tie between two players, the extra cards are used to decide who has the higher hand.

------
Comparison string formats:

Royal Flush = All the cards
Straight Flush = All the cards
Four of a Kind = value of the 4 relevant cards, 1 extra
Full House = value of the 3 relevant cards, value of the 2 relevant cards
Flush = All the cards
Straight = All the cards
Three of a Kind = value of the 3 relevant cards, 2 extra cards
Two pairs = value of highest 2 relevant cards, value of second 2 relevent cards, 1 extra card
One pair = value of 2 relevant cards, 3 extra cards
High card = All the cards
------

** All extra cards are in decending order.

To compare two hands get the value of each hand using the above identifier. Then create another identifier which first compares the <hand score> of each hand. If one hand has a higher <hand score> than the other, that hand wins immediately. If the two hands have the same <hand score>, then another comparison must be done to compare the relevant cards from each hand. If all of the relevant cards are the same in each hand, then the extra cards must be compared. If all the extra cards are the same in each hand, then the hand is a tie.
** The comparisons of the relevant and extra cards will have to depend on the <hand score> because the format of the <comparison string> varies. I don't have time to write the comparison identifier right now, but I can do it tomorrow if you want.

There may be some rules of poker that I am not familiar with, so let me know if there are any errors in the results. I used this page as information while making the code.

-genius_at_work

Re: hand recognition #141047 04/02/06 07:47 AM
Joined: Mar 2005
Posts: 212
N
NeUtRoN_StaR Offline OP
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Mar 2005
Posts: 212

its appreciated i dont know if ill get a chance to look at it long and hard tonight

when i do ill let you know if i find anything

Last edited by NeUtRoN_StaR; 04/02/06 07:53 AM.
Re: hand recognition #141048 04/02/06 11:31 AM
Joined: Sep 2003
Posts: 4,230
D
DaveC Offline
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
My personal congrates on that code, in my opion its very nicely written, i especially liked the looping gathering up the 4,3,2 or one of a kinds, and grouping them into a resulting hand.

I didnt run the code, rather just examined it here, thinking my way down (which got a bit harder on the second half i must say, trying to see whats happening)
And these two small points that could be adjusted are in no way saying anything is wrong, i just noticed them as i was going along.

(1) "while (%c > 0) {"
this can be "while (%c > 2)" since when %c = 2, it well be decreased to 1, and there is no 1 cards only 2 to 14. (of course having %c = 2 and 1 makes no differnce as it just scans for cards matching 1 and 0 and find none)

(2) ;1 pair
elseif (%sa <= 2) {
should be < not <= since it cant be == as thats taken up in the elseif above it (this is so minor i almost didnt mention it)

Re: hand recognition #141049 04/02/06 10:18 PM
Joined: Mar 2005
Posts: 212
N
NeUtRoN_StaR Offline OP
Fjord artisan
OP Offline
Fjord artisan
N
Joined: Mar 2005
Posts: 212
i dont recall if i mentioned that its texas holdem
so the hand check will draw from seven cards 2 of the players and 5 community

trying to make the best 5 card hand
ill try to make the necessary modification myself though

here the initial code ive got
(bear in mind this is so far from done)
Code:
#cards on
alias reset {
  unset %play
  unset %deck
  unset %player.*
  unset %comcards
}
alias make.deck {
  set %deck A-S,A-C,A-H,A-D,K-S,K-C,K-H,K-D,Q-S,Q-C,Q-H,Q-D,J-S,J-C,J-H,J-D,10-S,10-C,10-H,10-D,9-S,9-C,9-H,9-D,8-S,8-C,8-H,8-D,7-S,7-C,7-H,7-D,6-S,6-C,6-H,6-D,5-S,5-C,5-H,5-D,4-S,4-C,4-H,4-D,3-S,3-C,3-H,3-D,2-S,2-C,2-H,2-D
}
alias deal {
  var %i = 1
  while (%i &lt;= 2) {
    var %card = $gettok(%deck,$rand(1,$numtok(%deck,44)),44)    
    set -s $+(%,player.,$$1) $($+(%,player.,$$1),2) $+ %card $+ $chr(44)
    notice $$1 %card    
    set %deck $remtok(%deck,%card,1,44)
    inc %i
  }
}
alias flop {
  var %i = 1
  while (%i &lt;= 3) {
    var %card = $gettok(%deck,$rand(1,$numtok(%deck,44)),44)    
    set -s %comcards %comcards $+ %card $+ $chr(44)
    msg %cardroom The Flop : %card    
    set %deck $remtok(%deck,%card,1,44)
    inc %i
  }
}
alias turn {
  var %card = $gettok(%deck,$rand(1,$numtok(%deck,44)),44)    
  set -s %comcards %comcards $+ %card $+ $chr(44)
  msg %cardroom The Turn : %comcards     
  set %deck $remtok(%deck,%card,1,44)
}
alias river {
  var %card = $gettok(%deck,$rand(1,$numtok(%deck,44)),44)    
  set -s %comcards %comcards $+ %card $+ $chr(44)
  msg %cardroom The River : %comcards     
  set %deck $remtok(%deck,%card,1,44)
  var %x = 1
  while (%x &lt;= $numtok(%players,44)) {
    set -s $+(%,player.,$gettok(%players,%x,44)) $($+(%,player.,$gettok(%players,%x,44)),2) $+ %comcards 
    inc %x    
  }      
}
on *:text:!sit:#:{
  if ($nick !isin %players) {  
    set %players %players $+ $nick $+ ,
  }
}

on *:text:!play:#:{
  if ((%play == $null) &amp;&amp; ($numtok(%players,44) &gt;= 2)) {
    set %play on
    make.deck    
    var %n = 1
    while (%n &lt;= %numtok(%players,44)) {
      set %player. $+ $gettok(%players,%n,44) $chr(44)
      inc %n
    }
    var %x = 1
    while (%x &lt;= $numtok(%players,44)) {
      deal $gettok(%players,%x,44)
      inc %x    
    }
  }
  .timer $+ flop 1 5 flop
  .timer $+ turn 1 10 turn
  .timer $+ river 1 15 river
}

#cards end


right now the flop turn and river are on timers as im not dealing with the betting system that will provide the delay later yet

Re: hand recognition #141050 06/02/06 02:18 AM
Joined: Oct 2005
Posts: 1,741
G
genius_at_work Offline
Hoopy frood
Offline
Hoopy frood
G
Joined: Oct 2005
Posts: 1,741
Since you are making a texas-holdem game, you need to be able to test each of the possible 5-card hands that can be made from 7 cards in total. Since you already have the comparison code, I think that it would be easier to make an alias that will loop through all possible combinations of the 7 cards, and feed them 2 at a time into a comparison alias.

I'm not sure how the loop itself would work, but it would have to go through every combination of 5 cards than can be made from 7 cards. There wouldn't be very many combinations since all permutations don't need to be tested (cards 1,2,3,4,5 are the same as 2,4,3,5,1 and 5,2,3,4,1).

As each item of the loop comes up, it needs to be tested against the winner of the last test. So if hand B in loop 5 won, then it would be tested against hand A of loop 6. After all hands have been tested, the result will be the highest hand.

The comparison alias was described in my last post.

-genius_at_work