heatblazer has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am almost done with all the code for a real poker game but I am totally stuck with the winning condition matching... why? Well here is it:

sub winner { my $match; my (@hand) = (@_); foreach (@hand) { if ( /^(A|J|K|Q|2|3|4|5|6|7|8|9|10) of (clubs|diamonds|spades| +hearts)/ ){ print $&, "\n"; } } }

I don`t know how to make it to match for example if we have a pair of Kings or two pairs of any cards. A triple cards, and 5 cards of the same color.. Any ideas?

p.s. I was thinking of card by card comparing starting from index0 since... if we have 2 Kings then we can skip the 5 same colors checks since it`s never possible to have 5 color cards if at least 1 pair, but I think that regex could do it easier, just don`t know how.

edit

Here is some algorihm I came up with... a noob one but still fixes the issue as matching pairs and finds the same color... kind of lame one but working. Opinions?

#!/usr/bin/perl -wT use strict; use utf8; my @hand = ('k of hearts', 'k of diamonds', 'j of spades', 'j of heart +s'); my $same_kind=0; my $same_color = 0; for ( my $i=0; $i<$#hand+1; $i++) { for ( my $j=$i+1; $j<$#hand+1; $j++) { my (@first) = split(" of ", $hand[$i]); my (@second) = split(" of ", $hand[$j]); print "Split1: $first[0]\n"; print "Split2: $second[0]\n"; if ( $first[0] eq $second[0] ) { #pair $same_kind +=1; } elsif ( $first[$#first] eq $second[$#second] ) { $same_color +=1; } } } print "You have same kind of cards: $same_kind\nand $same_color of sam +e color.\n";

Whew...

Replies are listed 'Best First'.
Re: Checking for a special matching
by JavaFan (Canon) on Apr 01, 2012 at 23:17 UTC
    I wouldn't use strings as a card representation. I'd either use bits (6 bits/card will do), or 2-element arrays (rank, suit).

    Testing for pairs is easy: see if there are two card with the same rank (considering that in most poker forms, a hand has 5 or 7 cards, you don't have to be smart, even a brute force algorithm runs fast enough on anything produced since Babbage). You could, for instance, use a hash for ranks, and a hash for suits. If the ranks values are "2, 1, 1, 1", it's a pair. If it's "2, 2, 1", it's two pair. If it's "3, 1, 1", it's three of a kind. It it's "3, 2", it's a full house. If it's "4, 1", it's four of a kind. If it's "5", it's five of a kind. For the suits, if all the suits are the same (easy to find out with a hash), you have a flush. To find out straights, sort the cards (by rank). If the result is a sequence, you have a straight (an ace high straight needs an extra check).

    Instead of hashes, you can sort right away, and determine pairs, etc, by inspecting the sorted hand.

    But regexes seems like the wrong way to do it. In fact, if you need a regex to inspect an internal representation 100 out of 99 times, you're doing it wrong.

      Actually my idea for regex was to take the 5 array elements, turn them into one big scalar string and then match patterns for example if K occurs 2 times it`s a pair of Kings, if clubs occurs 5 times its... dunno the name the all-colors-winning pattern, if 3 of 'these' and 2 of 'this' it`s 'full house'. But the idea was to turn the array into one big string and solve the problem with a 1-shot-2-rabbits.

        But the idea was to turn the array into one big string and solve the problem with a 1-shot-2-rabbits.
        Considering that lead to a post where you said to be totally stuck, it only strengthens my claim that using a regexp is the wrong way of doing it.

      I have a new edit. Check it out :)

Re: Checking for a special matching
by Marshall (Canon) on Apr 02, 2012 at 04:37 UTC
    I guess another approach is search CPAN for poker modules like: Poker.

      Good suggestion but I still need to make my own algorithm for this task.

        Look at the code as a reference point and also Javafan's suggestions, which I think are good (I like the 2 hash idea, but haven't coded it). Let us know how you get on with the next step.
        Before you write code you need to understand the specs. IOW, before you develop an algorithm and turn it into code, you need to get your facts straight.

        Becoming a good Perl programmer is possible without being an analyst... but when you're acting as your own analyst, step one is knowing the relevant facts. JavaFan mentioned a good many of them, but your subsequent posts show little sign that you recognized them as important to your progress.

        For example

        • most poker games (not blackjack, acey-ducey or the like) use either 5 card or 7 card hands -- sometimes with some of those shared ("in the middle"). But you've posted code with 4 cards in play and with 8.
        • "5 cards of the same color" wins nothing. Five cards in the same suit ("kind" is what you said at one point) in a different matter; that's a flush, and ranks higher than a straight, which is 5 cards (regardless) of suit, in numeric order, A..10 or 3..7, etc.
                  and then we come to the code:
        • Have you found a use for << in a comparison? Generally, it's documented with heredocs

        And BTW, a script (code) is an expression of an algorithm; not an algorithm itself.

        Clearly, you deserve (and are receiving) credit for effort, but ignoring most of the suggestions and making up operators and syntax won't be an efficient way to learn.

        A reply falls below the community's threshold of quality. You may see it by logging in.