in reply to Blackjack problems (multiple reference passes et al)

I got totally bored so I converted what was orginally posted to OO, perhaps not the neatest, but what the heck.
My line count is higher, but I created methods for almost everything despite the stability or lack of reuse of several of the parts. I was just wasting time. In that same vain I am aware there are modules to create decks of cards and/or deal them, I just found the exercise fun.

# This is my untested blackjack program. # Untested in I haven't tested it vs the rules of the game # or for all possible outcomes/conditions. # my trivial tests all show it to be fundamentally working # I was just doing this because I was looking for an # exercise in OOP not in producing a polished product. # if you find any error let me know and I will try to post # corrections # The program - save as anything you like use strict; use BlackJack; &play(); sub play { my $game = BlackJack->new->init(); $game->dealtwo(); } print "Play again?"; $_=<>; chomp; if (/y/i) { &play(); } else { print "Thanks for playing\n"; } # MAIN MODULE - save as BlackJack.pm package BlackJack; use strict; sub new { my ($class) = shift; my $self = {}; bless $self , $class; return $self; } sub init { my ($self) = @_; ##### # define the symbols for each card and each cards value ##### $self->def( { "h" => "hearts", "c" => "clubs", "d" => "diamonds", "s" => "spades", "j" => "jack", "q" => "queen", "k" => "king", "a" => "ace", # ace with a value of 11 "1" => "ace" } # ace with a value of 1 ); my $value; $self->suit( [ 'h','d','c','s' ] ); $self->face( [ 'j','q','k','a' ] ); foreach ( 1 .. 10, @{$self->face} ) { if ( !/[jqka]/ ) { $value->{$_} = $_; } elsif ( /a/ ) { $value->{$_} = 11; } else { $value->{$_} = 10; } } $self->value($value); $self->createdeck(); print "deck size: " , scalar(@{$self->{'deck'} }) , "\n"; $self->initial_hand(); return $self; } sub suit { my ($self,$set) = @_; return $self->{'suit'} if !$set; $self->{'suit'} = $set; } sub face { my ($self,$set) = @_; return $self->{'face'} if !$set; $self->{'face'} = $set; } sub value { my ($self,$set) = @_; return $self->{'value'} if !$set; $self->{'value'} = $set; } sub def { my ($self,$set) = @_; return $self->{'def'} if !$set; $self->{'def'} = $set; } sub createdeck { my ($self) = @_; my $deck; my ($i, $j); foreach $i ( @{$self->suit} ) { foreach $j ( 2 .. 10, @{$self->face} ) { push @{$deck}, "$i $j"; } } $deck = &shuffledeck($deck); $self->deck($deck); } sub deck { my ($self,$set) = @_; return $self->{'deck'} if !$set; $self->{'deck'} = $set; } sub playerhand { my ($self,$set) = @_; return $self->{'playerhand'} if !$set; push @{ $self->{'playerhand'} }, $set; } sub dealerhand { my ($self,$set) = @_; return $self->{'dealerhand'} if !$set; push @{ $self->{'dealerhand'} }, $set; } sub initial_hand { my ($self) = @_; for (0 .. 1) { $self->hit('playerhand'); $self->hit('dealerhand'); } } ##### # shuffle deck (fisher yates) ##### sub shuffledeck { my ($deck) = @_; my ($i, $j); for ($i = @$deck; --$i; ) { $j = int rand ($i+1); next if $i == $j; @$deck[$i,$j] = @$deck[$j,$i]; } return $deck; } sub hit { my ($self,$player) = @_; my $card = $self->next_card; my ($f,$v) = (split/\s+/,$card); my $ace = 1 if ($v eq "a"); if ($player =~ m/player/) { if ($self->player_score > 21) { $v = 1 }; $self->player_score($self->value->{$v}); } else { if ($self->dealer_score > 21) { $v = 1 } $self->dealer_score($self->value->{$v}); } $self->$player($card); } sub player_score { my ($self,$set) = @_; return $self->{'player_score'} if !$set; $self->{'player_score'} += $set; } sub dealer_score { my ($self,$set) = @_; return $self->{'dealer_score'} if !$set; $self->{'dealer_score'} += $set; } sub print_score { my ($self,$type) = @_; return $self->player_score() if $type =~ /player/; return $self->dealer_score() if $type =~ /dealer/; } sub next_card { my ($self) = @_; return shift @{ $self->{'deck'} } } sub valid_card { my ($self,$card) = @_; $card = $self->def->{$card} if exists $self->def->{$card}; return $card; } sub print_hand { my ($self,$type,$hand) = @_; my $player = 'Your'; $player = 'Dealer' if $hand eq 'dealerhand'; if ($type eq 'loop') { print "$player deal:\n"; foreach ( @{$self->$hand} ) { my ($f,$v) = (split/\s+/,$_); print " " . $self->valid_card($v) . " of " . $self->def +->{$f} . "\n"; } print "$player score: " . $self->print_score($hand) . "\n\n"; } else { print "\n$player deal:\n"; my ($f,$v) = (split/\s+/,$self->$hand->[0]); print " " . $self->valid_card($v) . " of " . $self->def->{$ +f} . "\n"; print "$player score: " . $self->value->{$v} . "\n\n"; } } sub dealtwo { my ($self) = @_; my ($hos, $score, $card); $self->print_hand('loop' ,'playerhand'); $self->print_hand('single','dealerhand'); print "Hit or Stay?"; $_=<>; chomp; if (/h/i) { $self->hit('playerhand'); $self->player_score > 21 ? $self->win_or_lose : $self->dealtwo( +); # another "hit or stay" for player } else { $self->end(); # call the dealer logic } } sub end { my ($self) = @_; my ($score, $card); $self->print_hand('loop','dealerhand'); while ( $self->dealer_score < 17 ) { #if the dea +lers score is less then 17 then hit print "The dealer hits!\n"; $self->hit('dealerhand'); $self->print_hand('loop','dealerhand'); } print "The deal stays!\n\n"; $self->win_or_lose(); } sub win_or_lose { my ($self) = @_; if ($self->dealer_score > 21) { print "Dealer over 21 You Win!\n"; return; } if ($self->player_score < 22 && $self->player_score > $self->deale +r_score) { $self->win(); return; } if ($self->player_score > 21 && $self->dealer_score > 21) { $self->no_win_over_21(); return; } if ($self->player_score > 21 && $self->dealer_score < 22) { $self->lose(); return; } if ($self->player_score < 22 && scalar(@{$self->playerhand}) >= 5) + { $self->win_with_5_deals(); return; } if ($self->player_score == $self->dealer_score) { $self->no_winner(); } } sub no_win_over_21 { my ($self) = @_; print "Your score: " . $self->player_score . " is over 21\n"; print "Dealer score: " . $self->dealer_score . " is over 21\n\n"; print "No Winner - Push\n" } sub no_winner_21 { my ($self) = @_; print "Your score: " . $self->player_score . "\n"; print "Dealer score: " . $self->dealer_score . "\n\n"; print "No Winner - Push\n" } sub lose { my ($self) = @_; print "Your score: " . $self->player_score . "\n"; print "Dealer score: " . $self->dealer_score . "\n\n"; print "Dealer Wins!\n" } ##### # player wins ##### sub win { my ($self) = @_; print "Your score: " . $self->player_score . "\n"; print "Dealer score: " . $self->dealer_score . "\n\n"; print "You win!\n\n" } ##### # player wins by having 5 cards under 21 ##### sub win_with_five_deals { my ($self) = @_; print "Your score with five cards is: " . $self->player_score . " a +nd have 5 cards!\n"; print "You win!" } 1;


If it gets tested and is proven to work/liked I will move it to another section.

Replies are listed 'Best First'.
Re: Re: Blackjack problems (multiple reference passes et al)
by Anonymous Monk on Feb 18, 2002 at 05:56 UTC
    Can't locate object method "no_winner" via package "BlackJack" at - line 298, <> line 1.