package TenTwentyThirty;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = { DECK => shift,# a references to an array
RESULTS => 0, # scalar for play, win,
# lose, draw
# integers are 0, 1, 2,
# 3 respectfully
DEALT => 0, # scalor for number of
# cards dealt
TABLE => [ # list of lists
[],
[],
[],
[],
[],
[],
[]
],
};
bless $self,$class;
return $self;
} #### end of constructor
sub play { # this will play the game
my $self = shift;
my $testres; # used to store
# return value of
# _checkSum()
do{ # do..until game over
DONE: for my $pile (0..6) { # works through one pile at a time
no warnings; # first time for each pile
# in TABLE its undef
if( $self->{'TABLE'}->[$pile]->[0] != -1) {
use warnings;
last DONE if @{$self->{'DECK'}} == 0;
# exits for loop if no more
# cards can be dealt
push @{$self->{'TABLE'}->[$pile]}, shift @{$self->{'DECK'
+}};
$self->{'DEALT'}++;
# takes card from top of deck and puts on
# top of pile
# I feel I have to go into detail on what I mean by top of deck and to
+p of pile
# for someone might get confused on why i did the above statement this
+ way
# when you play cards, all the cards in the deck are face down and the
+ top
# of the deck is the first card in the deck, that is where you'll be d
+rawing
# cards from, the top
# know you'll be placing cards on the pile face up, the first card on
+the
# pile will end up being at the bottom of the pile as you place more
# cards on the pile, and the top of the pile is the last card you play
+ed
$testres = _checkSum($self,$pile);
# not sure if this is
# in good style
_removeCards($self,$testres,$pile);
# still not sure if this
# is in good style
} # end of if
} # end of for
}until(_gameOver($self)); # loop until game over
} #### end of play method
sub display { # this will display the results
# of the game
my $self = shift;
print "\n#########\n";
if( $self->{'RESULTS'} == 1) {
print "WIN : ";
} elsif( $self->{'RESULTS'} == 2) {
print "LOSS: ";
} elsif( $self->{'RESULTS'} == 3) {
print "DRAW: ";
} else {
print "INVALID RESULTS: ";
}
print $self->{'DEALT'};
print "\n#########\n";
} #### end of display method
# _checkSum makes 3 checks to a
# given array that is referenced
# by @{$self->{'TABLE'}->[$pile]}
# checks for sum of 10,20, or 30
# for following array elements
# 1. first, second, last
# 2. first, and last two
# 3. last three
# returns 0 if none sum right
# returns 1,2,3 for the respected
# test case that summed right
sub _checkSum {
my $self = shift;
my $pile = shift;
my $check;
if( @{$self->{'TABLE'}->[$pile]} >= 3 ) {
$check = $self->{'TABLE'}->[$pile]->[0] +
$self->{'TABLE'}->[$pile]->[1] +
$self->{'TABLE'}->[$pile]->[-1];
if( $check == 10 ||
$check == 20 ||
$check == 30 ) { return 1; }
$check = $self->{'TABLE'}->[$pile]->[0] +
$self->{'TABLE'}->[$pile]->[-1] +
$self->{'TABLE'}->[$pile]->[-2];
if( $check == 10 ||
$check == 20 ||
$check == 30 ) { return 2; }
$check = $self->{'TABLE'}->[$pile]->[-1] +
$self->{'TABLE'}->[$pile]->[-2] +
$self->{'TABLE'}->[$pile]->[-3];
if( $check == 10 ||
$check == 20 ||
$check == 30 ) { return 3; }
} # end of if
return 0;
} #### end of _checkSum method
sub _removeCards {
my ($self,$results,$pile) = @_;
if( $results==1) {
push @{$self->{'DECK'}}, shift @{$self->{'TABLE'}->[$pile]};
push @{$self->{'DECK'}}, shift @{$self->{'TABLE'}->[$pile]};
push @{$self->{'DECK'}}, pop @{$self->{'TABLE'}->[$pile]};
} elsif( $results==2 ) {
push @{$self->{'DECK'}}, shift @{$self->{'TABLE'}->[$pile]};
push @{$self->{'DECK'}}, splice( @{$self->{'TABLE'}->[$pile]}, -
+2);
} elsif( $results==3 ) {
push @{$self->{'DECK'}}, splice( @{$self->{'TABLE'}->[$pile]}, -
+3);
}
$self->{'TABLE'}->[$pile]->[0] = -1 if( @{$self->{'TABLE'}->[$pile]
+}==0 );
} #### end of _removeCards method
{
my @history;
sub _gameOver {
my $self = shift;
my $emptyPile = 0; # count number of
# empty piles
foreach my $pile (@{$self->{'TABLE'}}) {
$emptyPile++ if( $pile->[0] == -1);
}
# all piles must be empty
# to win the game
if( $emptyPile == 7) {
$self->{'RESULTS'} = 1;
return 1; # game over WIN
} elsif( @{$self->{'DECK'}} == 0) {
$self->{'RESULTS'} = 2;
return 1; # game over LOSS
} elsif(_draw($self)) {
$self->{'RESULTS'} = 3;
return 1; # game over DRAW
} else {
my $table;
for my $pile (0..6) {
$table .= join(" ",@{$self->{'TABLE'}->[$pile]});
$table .= " ";
}
push @history, $table;
return 0;
# game not over
}
} #### end of _gameOver method
sub _draw {
my $self = shift;
foreach my $table (@history) {
my $currentTable;
for my $pile (0..6) {
$currentTable .= join(" ",@{$self->{'TABLE'}->[$pile]});
$currentTable .= " ";
}
return 1 if($currentTable eq $table);
}
return 0;
}
}
1; #### end of TenTwentThirty.pm
#!perl
use strict;
use warnings;
use TenTwentyThirty;
use Array::Reform;
my @decks;
ReadCards(\@decks);
foreach my $deck (@decks) {
my $ttt = TenTwentyThirty->new($deck); # starts a new game
$ttt->play(); # Plays a game
$ttt->display(); # displays results of game
}
sub ReadCards {
my $decks = shift;
READ: while(<>) {
push @{$decks}, $_;
last READ if(/\b0/);
}
chomp @{$decks};
@{$decks} = split /\s+/,join(" ", @{$decks});
@{$decks} = Array::Reform->reform(52,\@{$decks});
pop @{$decks};
my $i = 0;
foreach my $item (@{$decks}) {
$i++;
if ( @{$item} != 52 ) {
die "$i doesn't have 52 cards\n";
}
}
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.