euchre-live

Euchre web-app for the socially distant family
git clone git://git.alexkarle.com/euchre-live.git
Log | Files | Refs | README | LICENSE

commit cefbde1de89e694abed78d2346c0fc9a2a5ebc78 (patch)
parent 32ca25cdf7882605df861859bfa2c5fc80a1f687
Author: Alex Karle <alex@karle.co>
Date:   Tue, 14 Apr 2020 22:41:17 -0400

Euchre::Game: [refactor] Teach card_value about trump/led

This commit splits up card_value into card_value and raw_card_value. The
latter does what the original intended (i.e. give a number 0-23) and the
former now gives a number 0-98 based on trump/led.

This refactor simplifies trick_winner a lot, but that's not the main
motivation. The real reasoning here is the Dealer will, in a future
commit, take on the job of sorting hands. To sort easily, it needs to
know what's valuable. Why not use the same sub Game does!

Diffstat:
Mlib/Euchre/Game.pm | 73++++++++++++++++++++++++++++++++++++++++---------------------------------
Mt/Game.t | 3++-
2 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/lib/Euchre/Game.pm b/lib/Euchre/Game.pm @@ -12,6 +12,7 @@ our @EXPORT = qw( deal trick_winner score_round + card_value ); use List::Util qw(shuffle); @@ -27,7 +28,7 @@ our @FULL_DECK = qw( NC TC JC QC KC AC ); -sub card_value { +sub raw_card_value { my ($c) = @_; if ($c eq 'X') { return -1; @@ -36,6 +37,43 @@ sub card_value { return (6 * $SUIT_VALS{$suit} + $CARD_VALS{$val}); } +sub card_value { + my ($c, $trump, $led) = @_; + + # Lower to numeric value + $trump = $SUIT_VALS{$trump}; + my $cval = raw_card_value($c); + + return $cval if $cval < 0; + + # Gather more data on it + my $suit = int($cval / 6); + my $is_jack = ($cval % 6 == 2); + my $is_trump = ($suit == $trump); + my $is_tcolor = (int($suit / 2) == int($trump / 2)); + my $is_bower = ($is_jack && $is_tcolor); + + # To create a absolute ordering we give + # +50 -- all bowers + # +25 -- all trump (not incl. J of color) + # +0 -- all others (use raw value) + $cval += 50 if $is_bower; + $cval += 25 if $is_trump; + + # If we are ranking based on suit led, all throwoffs are + # considered value 0 + # NOTE: not always defined, i.e. when sorting hand + if (defined $led) { + $led = $SUIT_VALS{$led}; + if ($suit != $led && !($is_trump || $is_bower)) { + # throwoff -> set value to zero + $cval = 0; + } + } + + return $cval; +} + sub deal { my @cards = shuffle @FULL_DECK; @@ -62,38 +100,7 @@ sub deal { sub trick_winner { my ($trump, $led, @cards) = @_; - $trump = $SUIT_VALS{$trump}; - $led = $SUIT_VALS{$led}; - my @values = map { card_value($_) } @cards; - - # Assign each card a value based on trump + led, either - # Bower: card + 50 - # Trump: card + 25 (including Bower) - # Suit Led: card - # Other: 0 - for (my $i = 0; $i < @values; $i++) { - next if $values[$i] < 0; # indicates loner - - # Identify the card - my $c = $values[$i]; - my $suit = int($c / 6); - my $is_jack = ($c % 6 == 2); - my $is_tcolor = (int($suit / 2) == int($trump / 2)); - my $is_bower = ($is_jack && $is_tcolor); - - # Assign it a value - if ($is_bower) { - $values[$i] += 50; - } - if ($suit == $trump) { - $values[$i] += 25; - } elsif ($suit != $led && !$is_bower) { - # throwoff -> set value to zero - $values[$i] = 0; - } else { - # non-trump led card -> use regular value - } - } + my @values = map { card_value($_, $trump, $led) } @cards; my $winning_ind = -1; my $winning_val = -1; diff --git a/t/Game.t b/t/Game.t @@ -35,11 +35,12 @@ sub test_deal { sub test_trick_winner { my @tests = ( - # [Trump, Cards], Winner Idx, Desc + # [Trump, Led, Cards], Winner Idx, Desc [['H', 'H', 'NH', 'TS', 'AS', 'QS'], 0, 'Trump suit led'], [['D', 'H', 'JH', 'TS', 'JD', 'QD'], 2, 'Jack trump beats all'], [['D', 'C', 'NC', 'JH', 'AD', 'AC'], 1, 'Jack color beats all others'], [['S', 'S', 'NS', 'JH', 'AD', 'JC'], 3, 'Jack color beats all others (2)'], + [['S', 'H', 'NS', 'JH', 'AD', 'AH'], 0, 'Trump beats ace'], [['C', 'H', 'NH', 'JH', 'QH', 'AH'], 3, 'No trump, highest of led'], [['C', 'H', 'NH', 'JH', 'AH'], 2, 'No trump, highest of led, 3 cards'], [['C', 'S', 'NH', 'JH', 'AH', 'NS'], 3, 'No trump, suit led wins'],