Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Sorry if this is an easy one, but I'm just not grokking it. I need to create a 2 dimensional field, and scatter randomly every letter in the alphabet in that field (This is for a concentration-type simple game).

I was thinking that I'd just use a two dimensional array and for each letter in the alphabet I'd randomly pick one of the scalars in that array, and if it already had a letter assigned, pick another scalar randomly until it found one that wasn't in use. But that seems really hokey. Does anyone have a more coherent idea of how to do this?

Replies are listed 'Best First'.
Re: Random distribution
by BrowserUk (Patriarch) on Oct 24, 2003 at 19:23 UTC

    Something like this?

    #! perl -slw use strict; use Data::Dumper; use List::Util qw[ shuffle ]; use constant { X => 10, Y => 10 }; my @list = shuffle 'A' .. 'Z', (' ') x (X * Y - 25); my @a2d = map{ [ @list[ ($_*10) .. (($_+1) * 10) ] ] } 0 .. 9; $Data::Dumper::Indent = 0; print Dumper \@a2d; __END__ $VAR1 = [ [' ',' ','V',' ',' ',' ','P',' ','A',' ','R'], ['R','S',' ',' ',' ',' ',' ',' ',' ',' ','J'], ['J',' ',' ','D',' ',' ','C',' ',' ','T',' '], [' ','G','W',' ','U',' ','K',' ',' ',' ',' '], [' ',' ',' ','N',' ','L',' ',' ',' ',' ',' '], [' ','Y','E',' ',' ','B',' ',' ',' ',' ',' '], [' ',' ',' ',' ','X',' ','M',' ',' ','O',' '], [' ',' ',' ','H',' ','Z',' ',' ',' ','F',' '], [' ',' ',' ',' ',' ',' ',' ',' ',' ','Q',' '], [' ',' ',' ',' ',' ',' ',' ',' ','I',' ',' '] ];

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!

Re: Random distribution
by hardburn (Abbot) on Oct 24, 2003 at 19:10 UTC

    I'd start with an 1-dim array defined as @start_array = ('a' .. 'z'), and then shuffle it using Algorith::Numerical::Shuffle. Then you can break it into the 2-dim array.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    :(){ :|:&};:

    Note: All code is untested, unless otherwise stated

      I suggested using List::Util below, and was just curious (since you recommended the Algorth::... module) do you see significant tradeoffs for either of those modules? I haven't done any benchmarking, but thought you might have some idea.
        The Algorithm::Numeric::Shuffle is a pure Perl solution. I wrote it years ago, 5.005 era I guess. The one in List::Util is in XS and should be much faster than the one in Algorithm::Numeric::Shuffle. I'd go for the one in List::Util, unless you have an old version of Perl and can't easily build XS modules yourself.

        Abigail

        No reason beyond the fact that it was the first thing thing that came up on search.cpan.org for the term 'shuffle'. If List::Util is XS, it's almost certainly faster, so that probably is a better module to use.

        ----
        I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
        -- Schemer

        :(){ :|:&};:

        Note: All code is untested, unless otherwise stated

Re: Random distribution
by ChrisS (Monk) on Oct 24, 2003 at 19:13 UTC
    I'd use the List::Util module to randomize the input, then drop the randomized letters in place.
    use List::Util qw(shuffle); my @letters = shuffle(A .. Z); print @letters; # prints something like WOGJLMXQCDVIPNESURZHTFYKBA for $r (1 .. 2) { # or whatever size you need for $c (1 .. 13) { # same here $data[$r][$c] = shift @letters; } }
Re: Random distribution
by KPeter0314 (Deacon) on Oct 24, 2003 at 19:43 UTC
    Having played a "concentration-type simple game" which involves finding matches from under a set of cards layed out on the table with my kids recently begat the question:

    Shouldn't each letter be dropped into the two-dimensional array twice? That way you would have something to match...

    -Kurt

Re: Random distribution
by diotalevi (Canon) on Oct 24, 2003 at 19:12 UTC
    Whose class are you doing this for?