#!/usr/bin/perl -w

my (@deck, @dealer, @player, $hands, $total);
$total = 0;

die "usage: $0 number_of_hands" if ($#ARGV < 0);
$hands = $ARGV[0];

sub shuf {
  my ($i, $r, $t);
  @deck = (1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
           5, 5, 5, 5, 5, 5, 5, 5);
  foreach $i (0..23) {
    $r = int(rand(24));
    $t = $deck[$i];
    $deck[$i] = $deck[$r];
    $deck[$r] = $t;
  }
}

sub deal {
  @player = ();
  @dealer = ();
  push @player, pop @deck;
  push @player, pop @deck;
  push @dealer, pop @deck;
  push @dealer, pop @deck;
}

sub value {
  my @hand = @_;
  my ($card, $val, $aces);
  $val = 0;
  $aces = 0;
  foreach $card (@hand) {
    $val += $card;
    if ($card == 1) {
      $aces++;
      $val+=5;
    }
  }
  # Aces count as 6 or 1.
  while ( ($aces > 0) && ($val > 11) ) {
    $aces--;
    $val-=5;
  }
  return $val;
}

sub play {
  my ($p, $d, $multiplier),;

  # Natural 11 for the player is immediate 5:1 payout (44 profit)
  $p = value @player;
  if ($p == 11) {
    $total += 44;
    return;
  }

  # Assume the player always doubles down on natural 5 or 6
  $multiplier = 1;
  if ( ($p == 5) || ($p == 6) ) {
    push @player, pop @deck;
    $multiplier = 2;
    goto DEALER;
  }

  # Assume player draws on 8 or less, stands on 9 or more.
  $p = value @player;
  while ( ($p <= 8) && ($#player < 5) ) {
    push @player, pop @deck;
    $p = value @player;
    goto DEALER if ($p >= 12);
  }

  # 5 cards without busting is auto-win
  if ($#player == 5) {
    $total += (11 * $multiplier);
    return;
  }

DEALER:
  $p = value @player;
  if ($p >= 12) {
    $total -= (11 * $multiplier);
    return;
  }

  # Dealer draws on 8 or less, stands on 9 or more.
  $d = value @dealer;
  while ($d <= 8) {
    push @dealer, pop @deck;
    $d = value @dealer;
    if ($d >= 12) {
      $total += (11 * $multiplier);
      return;
    }
  }

  if ($p == $d) {
    # Push (tie) -- nothing lost or gained.
    return;
  } elsif ($p < $d) {
    $total -= (11 * $multiplier);
    return;
  } else {
    $total += (11 * $multiplier);
    return;
  }
}

# Main loop
my ($i);
$i = 0;
while (++$i <= $hands) {
  shuf;
  deal;
  play;
}
print "Total: $total  Average: " . $total/$hands . "\n";
