Problem 54

Perl6

  1enum Hand-types (High-Card => 1, One-Pair => 2, Two-Pair => 3, Three-Kind => 4, Staight => 5, Flush => 6, 
  2Full-House => 7, Four-Kind => 8, Straight-Flush => 9, Royal-Flush => 10);
  3enum HIGH-CARDS ( TEN => 10, JACK => 11, QUEEN => 12, KING => 13, ACE => 14 );
  4
  5sub check-high-card(@nums) {
  6    if @nums.contains('A') { return ACE.value }
  7    elsif @nums.contains('K') { return KING.value }
  8    elsif @nums.contains('Q') { return QUEEN.value }
  9    elsif @nums.contains('J') { return JACK.value }
 10    elsif @nums.contains('T') { return TEN.value }
 11    else { return max @nums} ;
 12}
 13
 14sub is-two-pair(@nums) {
 15    if @nums.unique.elems == 5 { return High-Card.value }
 16    else { return Two-Pair.value }
 17}
 18
 19sub is-three-kind(@nums) {
 20    if @nums.unique.elems >= 4 { return is-two-pair(@nums)  }
 21    else { return Three-Kind.value } ;
 22}
 23
 24sub is-four-kind(@nums) {
 25    if @nums.unique.elems >= 3 { return is-three-kind(@nums) }
 26    else { return Four-Kind.value }
 27}
 28
 29sub is-full-house(@nums, $in-flush) {
 30    if is-two-pair(@nums) and is-three-kind(@nums) {
 31        my $iterator = 0;
 32        if @nums[$iterator] ~~ @nums[$iterator + 1] {
 33            if @nums[$iterator] ~~ @nums[$iterator + 2] {
 34                $iterator = 3
 35            }
 36            else{
 37                $iterator = 2
 38            } 
 39        } 
 40        else {
 41            if $iterator ~~ 3 {
 42                if @nums[$iterator] ~~ @nums[$iterator + 1] { return Full-House.value; }
 43                else { return is-straight(@nums, False) ; }
 44            }
 45            elsif $iterator == 2 {
 46                if @nums[$iterator] ~~ @nums[$iterator + 1] ~~ @nums[$iterator + 2] {
 47                    return Full-House.value
 48                }
 49                else { return is-straight(@nums, False) ; }
 50            }
 51        }
 52    }
 53    else { return False; }
 54}
 55
 56sub check-suits(@suits) {
 57    my $suit-to-check = @suits[0];
 58    for @suits -> $suit {
 59        if $suit !eq $suit-to-check { return False; }
 60    }
 61    return True;
 62}
 63
 64sub is-royal-flush(@nums) {
 65    #sorted will put A J K Q T
 66    return @nums ~~ <'A' 'J' 'K' 'Q' 'T'>
 67}
 68
 69sub is-straight(@nums, $check-for-flush) {
 70    if (@nums[0].Numeric !~~ Failure) == True and @nums[0] == 9 {
 71        #check for 9 Ten J Q K
 72        if @nums ~~ < 9 'J' 'K' 'Q' 'T'> { return True; }
 73        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) } }
 74    } 
 75    elsif (@nums[0].Numeric !~~ Failure) == True and @nums[0] <= 5 { 
 76        if @nums ~~ < (@nums[0]) (@nums[0] + 1) (@nums[0] + 2) (@nums[0] + 3) (@nums[0] + 4) > { return True; }
 77        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) }}
 78    } 
 79    elsif (@nums[0].Numeric !~~ Failure) == False { #if first element isn't a number there's only face cards or 10  
 80        if @nums ~~ < 'A' 'J' 'K' 'Q' 'T' > { return True; }
 81        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) } }
 82    }
 83    elsif (@nums[0].Numeric !~~ Failure) == True and @nums[0] == 6 {
 84        if @nums ~~ < 6 7 8 9 'T' > { return True; }
 85        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) } }
 86    }
 87    elsif (@nums[0].Numeric !~~ Failure) == True and @nums[0] == 7 {
 88        if @nums ~~ < 7 8 9 'J' 'T' > { return True; }
 89        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) } }
 90    }
 91    elsif (@nums[0].Numeric !~~ Failure) == True and @nums[0] == 8 {
 92        if @nums ~~ < 8 9 'J' 'Q' 'T' > { return True; }
 93        else { if $check-for-flush { return False; } else { return is-three-kind(@nums) } }
 94    }   
 95    else{
 96        say "ERROR with checking straight @nums[]"
 97    }
 98}
 99
100sub is-flush(@hands){
101    my @suits;
102    my @nums;
103    for @hands -> @hand {
104        @suits.push: @hand[1];
105        @nums.push: @hand[0];
106    }
107    if check-suits(@suits) {
108        if is-royal-flush(@nums.sort) { return Royal-Flush.value; }
109        elsif is-straight(@nums.sort, True) { return Straight-Flush.value; }
110        elsif is-four-kind(@nums.sort) { return Four-Kind.value; }
111        elsif is-full-house(@nums.sort, True) == Full-House.value { return Full-House.value; }
112        else { return Flush.value } 
113    }
114    else { return is-full-house(@nums, False); } 
115    return 1;
116}
117
118sub Player-One-Wins(@player1, @player2){
119    say "Player 1: @player1[] -- Player 2: @player2[]";
120    my $player1-hand-type = get-hand-type(@player1);
121    my $player2-hand-type = get-hand-type(@player2);
122    if $player1-hand-type > $player2-hand-type {
123        say "PLAYER 1 WINS: $player1-hand-type[] beats $player2-hand-type[]";
124        return 1;
125    } 
126    elsif $player1-hand-type == $player2-hand-type {
127        my @temp = @player1>>.comb;
128        my @temp2 = @player2>>.comb;
129        my @player1nums;
130        my @player2nums;
131        for @temp -> @i { @player1nums.push: @i[0]; }
132        for @temp2 -> @j { @player2nums.push: @j[0]; }
133        if check-high-card(@player1nums) > check-high-card(@player2nums) { say "PLAYER 1 WINS! &check-high-card(@player1nums)[] beats &check-high-card(@player2nums)[]"; return 1; }
134        else { say "PLAYER 2 WINS!"; return 0; }
135    }
136    else { say "PLAYER 2 WINS! $player2-hand-type[] beats $player1-hand-type[]"; return 0; }
137}
138sub get-hand-type(@hand){
139    return is-flush(@hand>>.comb);
140}
141
142my @player-hands = slurp.lines.words.rotor(5);
143my $iterator = 0;
144my $count = 0;
145for @player-hands -> @player1, @player2 {
146    $count += Player-One-Wins(@player1, @player2); 
147}
148say $count