The idea here is I want the initial hash to be run into the child function, have changes made, send the changes back to the parent. Then send the changed hash into the child for more changes to take place. I've been making a poker program to help me learn, and here are the functions in question:

It might not be the best way to make poker, but I did it like this in python and it worked.

#hand is fed 5 cards(an array) to be analyzed for what they're worth. The function #is all called with a number to indicate which player it is.
sub hand {
    my($cards) = shift;
    my %ply1score = (2 => "0", 3 => "0", 4 => "0", 5 => "0", 6 => "0", 7 => "0",
                     8 => "0", 9 => "0", 10 => "0", 11 => "0", 12 => "0", 13 => "0",
                     14 => "0", s => "0", c => "0", d => "0", h => "0");

    my %ply2score = (2 => "0", 3 => "0", 4 => "0", 5 => "0", 6 => "0", 7 => "0",
                     8 => "0", 9 => "0", 10 => "0", 11 => "0", 12 => "0", 13 => "0",
                     14 => "0", s => "0", c => "0", d => "0", h => "0");
    for (@$cards){
         print "card: $_\n";
         my @whatisit = split;
         if ($_[0] eq 1){ 
             calc($whatisit[0],$whatisit[2], %ply1score);
         }
         if ($_[0] eq 2){
             calc($whatisit[0],$whatisit[2], %ply2score);
         }
     }
}

sub calc {
    my $face = $_[0];
    my $suit = $_[1];
    my %score = @_;
    if ($face eq "Ace") {
        $score{14}++;
    }
    if ($face eq "Two") {
        $score{2}++;
    }
    if ($face eq "Three") {
        $score{3}++;
    }
    if ($face eq "Four") {
        $score{4}++;
    }
    if ($face eq "Five") {
        $score{5}++;
    }
    if ($face eq "Six") {
        $score{6}++;
    }
    if ($face eq "Seven") {
        $score{7}++;
    }
    if ($face eq "Eight") {
        $score{8}++;
    }
    if ($face eq "Nine") {
        $score{9}++;
    }
    if ($face eq "Ten") {
        $score{10}++;
    }
    if ($face eq "Jack") {
        $score{11}++;
    }
    if ($face eq "Queen") {
        $score{12}++;
    }
    if ($face eq "King") {
        $score{13}++;
    }
    if ($suit eq "Diamonds") {
        $score{d}++;
    }
    if ($suit eq "Clubs") {
        $score{c}++;
    }
    if ($suit eq "Hearts") {
        $score{h}++;
    }
    if ($suit eq "Spades") {
        $score{s}++;
    }
    return %score;
}

So after checking for the face and suit, there should be a change of values from 0 to 1. Which there is for %score. But once returned I would like ply1score to see that as well, but it stays at 0 throughout.

This is never going to work:

my $face = $_[0];
my $suit = $_[1];
my %score = @_;

What I would do is pass the reference to %score like this:

my $score=calc($whatisit[0],$whatisit[2], \%ply2score);
print "score for hearts: $$score->{h}";
sub calc{
   my ($face,$suit,$score)=@_;
   #do something to calculate
   if ($suit eq "Hearts") {
        $$score{h}++;
   }
   return $score;
}

I think you ought to look into complex data structures. You can push a has within a hash or and array in a hash. You can pass the entire thing back and forth, either as references or actual structures.

I don't have time today to show you how, but look into data structures in perl.

Edited 6 Years Ago by mitchems: n/a

This is never going to work:

my $face = $_[0];
my $suit = $_[1];
my %score = @_;

What I would do is pass the reference to %score like this:

my $score=calc($whatisit[0],$whatisit[2], \%ply2score);
print "score for hearts: $$score->{h}";
sub calc{
   my ($face,$suit,$score)=@_;
   #do something to calculate
   if ($suit eq "Hearts") {
        $$score{h}++;
   }
   return $score;
}

I think you ought to look into complex data structures. You can push a has within a hash or and array in a hash. You can pass the entire thing back and forth, either as references or actual structures.

I don't have time today to show you how, but look into data structures in perl.

MMk, ill take a look at this tomorrow as well as some data structures and take it from there. thanks

You may declare the %score as a global variable, then you able to access the variable across the program for the updated values

Try below codes in your declaration part.

### declare the global variable ...
our %score

Otherwise

## the declared variable considered as the global variable
use vars qw(%score $var1 $var2 @array1);

For More details:-
http://search.cpan.org/~jesse/perl-5.12.2/lib/vars.pm

Edited 6 Years Ago by k_manimuthu: n/a

The way to really do this right is to use something like:

http://search.cpan.org/~akarger/Games-Cards-1.45/lib/Games/Cards.pm

or

http://search.cpan.org/~pip/Games-Cards-Poker-1.2.565CHh5/Poker.pm

Those are modules that hold the cards/hands and shuffle and other such functions.

But if you want to dip your toe into data structures, you can try this:

use strict;
use warnings;

my %names=("1"=>"Ace","2"=>"Two","3"=>"Three","4"=>"Four","5"=>"Five","6"=>"Six","7"=>"Seven","8"=>"Eight","9"=>"Nine","10"=>"Ten","11"=>"Jack","12"=>"Queen","13"=>"King");
my @suits=qw(Spades Hearts Clubs Diamonds);

my @deck;
for (@suits){
	my $csuit=$_;
	for (keys %names){
		my %card = ("suit"=>"$csuit","value"=>"$_","name"=>"$names{$_} of $csuit");
		push @deck,\%card;
	}
}
for (@deck){
	print "$_->{name}\n";
}

Then, you can create a hand array and pass that back and forth. If you want you can create a player hash with the player number as the key and pointing to the hand array.

my %players=("1"=>\@hand1, "2"=>\@hand2);

or something like that.

Probably wouldnt hurt to do some toe dipping. Helps with the learning and such.

Dip away! If you want to jump in headfirst, use Moose - which is an object-oriented add-on for perl. That way you can crate the cards as objects with functions/methods. So, you can ask a card what it's value/score is. However, if you don't want to jump in that deep yet, I'd suggest using the references and data structures like above.

Remember that perl allows you to get a pointer (reference) to anything via a scalar.

my @array=qw (one two);
my $scalar=\@array;
print "$$scalar[0]\n";
my %hash=("key",$scalar);
print "${$hash{key}}[1]\n";
my @array1;
push @array1,\%hash;
print "$array1[0]->{key}[0]\n";

The last line is an array that contains a reference to a hash that in turn contains a reference to another array keyed by the word "key". You can go on and on and on.

As for your card game, think about what types each element should be. Cards should probably be hashes. Decks and Hands should be arrays. Players should be hashes that hold arrays (hands) and their names, scores, etc stored as hash values.


It's a lot like C without the memory management problems.

Dip away! If you want to jump in headfirst, use Moose - which is an object-oriented add-on for perl. That way you can crate the cards as objects with functions/methods. So, you can ask a card what it's value/score is. However, if you don't want to jump in that deep yet, I'd suggest using the references and data structures like above.

Remember that perl allows you to get a pointer (reference) to anything via a scalar.

my @array=qw (one two);
my $scalar=\@array;
print "$$scalar[0]\n";
my %hash=("key",$scalar);
print "${$hash{key}}[1]\n";
my @array1;
push @array1,\%hash;
print "$array1[0]->{key}[0]\n";

The last line is an array that contains a reference to a hash that in turn contains a reference to another array keyed by the word "key". You can go on and on and on.

As for your card game, think about what types each element should be. Cards should probably be hashes. Decks and Hands should be arrays. Players should be hashes that hold arrays (hands) and their names, scores, etc stored as hash values.


It's a lot like C without the memory management problems.

Haha dont say that. I tried learning C and its such a harsh language. I've never been into code when i was younger and slowly gotten into scripting languages.

Anyway, my overall plan with this learning exercise was to build it sequentially, and then refactor it to use classes and such. Ill see if i can grasp these data structures first.

This article has been dead for over six months. Start a new discussion instead.