Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Hi, heres a few comments, plus an alternate solution to the problem. I fully empathize with your difficultly finding a way to learn to program. There is a large gap between the beginners books and the reference books.

It may be helpful to try something that you can use yourself. A very simple address book, or todo list would be a good start. If you do try something like this however make sure you start very simply. Don't try to add features until the basics are working. A simple, working application is much better than an ambitious broken one.

Now on to your code. You've written this in an OO'ish way, but thats not always necessary. I can appreciate that you might be practicing OO coding of course, and your syntax isn't bad. I think the largest problem with OO coding in your example is that your one object corresponds to the entire game. You are making it more difficult for yourself, as your trouble with the @history array shows. It needs to be visible to a couple of subs, but its not part of your object.

Your   _checkSum($self,$pile);

is better written as   $self->_checkSum($pile)

$self is automatically passed in as the first argument, because of the -> method call syntax.

I don't see a repetition of _checkSum if its successful. The rules of the game state that if you can remove the three cards you should check again, and keep removing any matches until you can't match.

Below is another solution to the problem. I haven't used any OO features. I also didn't bother implementing reading the card lists from STDIN.

Here are a few notes about my code that might interest you.

Most of the variables are visible throughout, since they are needed by the subs.

I've made liberal use of array slices. @$stack[0,1,-1] return the first, second and last items in from the arrayref $stack.

The % (modulo) operator returns the remainder from a division. 10 20 or 30 % 10 all return 0, while any of the other possible card sums will return some number. So we can condense three tests into one.

After getting the values form the stacks and pushing them on the deck, you have to remove the elements from the array. You did this with shifting, poping and spicing, but it can also be accomplished in other ways. I set the elements values to undef, then grep'ed the list onto itself.

To fix the bugs in your own program, you might want to add warn statements throughout similar to those below. I spent most of my time trying to figure out what was the "bottom" or "top" of the deck and stacks. But looking at the warn statements and checking each against the game rules let me fix the errors.

Good luck coding! There's always plenty more to learn, and I by no means consider myself proficient. If anyone wants to improve my code I'll be very happy.

#!/usr/bin/perl use strict; my @input = qw( 2 6 5 10 10 4 10 10 10 4 5 10 4 5 10 9 7 6 1 7 6 9 5 3 + 10 10 4 10 9 2 1 10 1 10 10 10 3 10 9 8 10 8 7 1 2 8 6 7 3 3 8 2 4 3 2 10 8 10 6 8 9 5 8 10 5 3 5 4 6 9 9 1 7 6 3 5 10 10 8 10 9 10 10 +7 2 6 10 10 4 10 1 3 10 1 1 10 2 2 10 4 10 7 7 10 10 5 4 3 5 7 10 8 2 3 9 10 8 4 5 1 7 6 7 2 6 9 10 2 3 10 3 4 4 9 10 1 +1 10 5 10 10 1 8 10 7 8 10 6 10 10 10 9 6 2 10 10 ); # variables need to be visible my ($initial_deck, $offset, $deck, $dealt); my @stacks; my @gamestates; # play the three games for ( 0..2 ) { $offset = $_ * 52; @$initial_deck = @input[ 0 + $offset .. 51 + $offset ]; play(); } # # play one game sub play { $deck = $initial_deck; $dealt = 0; @stacks = ([],[],[],[],[],[],[]); @gamestates = (); # warn 'INITIAL: ' . join ' ', @$initial_deck; while ( 1 ) { # warn "\n\nDEALT: $dealt -----------------------\n"; # warn "DECK: " . join ' ', @$deck; foreach my $stack ( @stacks ) { # warn "---------"; # deal card push @$stack, shift @$deck; $dealt++; return done( 'Loss' ) if ! scalar @$deck; # check for 10,20,30 $stack = check_stack($stack); # check for repeated game state return done( 'Draw' ) if repeated(); # die if $dealt >= 200; } @stacks = grep { scalar @$_ } @stacks; return done('Win') if ! scalar @stacks; } } # evaluate stack for ten twenty thirty and resize array sub check_stack { my $stack = shift; # warn "Stack: " . join ' ', @$stack; foreach my $card_combo ( ( [0,1,-1],[0,-2,-1],[-3,-2,-1] ) ) { my $sum; return $stack if scalar @$stack < 3; foreach ( @$stack[ @$card_combo ] ) { $sum += $_ }; next if ( $sum % 10 ); # warn "GOT ONE: @$card_combo / " . join '+', @$stack[ @$card_comb +o ]; push @$deck, @$stack[ @$card_combo ]; # remove elements from array @$stack[ @$card_combo]= undef; @$stack = grep { $_ } @$stack; check_stack( $stack ); } $stack; } sub repeated { my $gamestate = join ' ', map { join ' ', @$_ } @stacks; # $gamestate .= ' ' . join ' ', @$deck; foreach ( @gamestates ) { if ( $gamestate eq $_ ) { # warn "Seen: $_"; # warn "Now : $gamestate"; return 'draw'; } } push @gamestates, $gamestate; return 0; } sub done { print shift() . ": $dealt\n"; } 1;

In reply to Re: '96 ACM Problem A by Anonymous Monk
in thread '96 ACM Problem A by jjdraco

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • 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.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-04-25 13:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found