# Boggle.pm
#
# A package that simulates the Boggle board.
#
# John Gamble, 4 Mar 1999, using perl 5.00404.
#

package Boggle;

use integer;
use vars qw(@ISA @EXPORT $VERSION);
use Carp;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(shake_board board_string);

$VERSION = 0.01;

my(@cubes) = qw(
       UOICTM MIUQHN PKSAFF LRNHNZ
       REYTLT RWVTHE AOTTOW HEGEWN
       CAPOHS EUISNE DRLYEV IEXRDL
       ANGAEE ESITSO SYTITD OOBBAJ);

sub shake_board()
{
       my(@board, @letters);
       my($l, $r);

       foreach (@cubes)
       {
               @letters = split(//, $_, 6);
               push(@board, $letters[rand(6 * 256)/256]);
       }

       #
       # Shuffle the array.
       #
       foreach (0..$#cubes)
       {
               $l = $board[$r = rand(scalar(@cubes) * 256)/256];
               $board[$r] = $board[$_];
               $board[$_] = $l;
       }
       @board;
}

sub board_string()
{
       my($board) = join("\n", &semijoin('  ', 4, @_));
       $board =~ s/Q /Qu/;
       $board;
}

=item semijoin()

@newlist = semijoin($expr, $itemcount, @list);

$expr      - A string to be used in a join() call.
$itemcount - The number of items in a list to be joined.
             It may be negative.
@list      - The list

Create a new list by performing a join on I<$itemcount> elements at a
time on the original list. Any leftover elements from the end of the
list become the last item of the new list, unless I<$itemcount> is
negative, in which case the first item of the new list is made from the
leftover elements from the front of the list.

=back

=cut
sub semijoin($$@)
{
       my($jstr, $itemcount, @oldlist) = @_;
       my($idx);
       my(@newlist) = ();

       return @oldlist if ($itemcount <= 1 and $itemcount >= -1);

       if ($itemcount > 0)
       {
               push @newlist, join $jstr, splice(@oldlist, 0, $itemcount) while @oldlist;
       }
       else
       {
               $itemcount = -$itemcount;
               unshift @newlist, join $jstr, splice(@oldlist, -$itemcount, $itemcount)
                       while $itemcount <= @oldlist;
               unshift @newlist, join $jstr, splice( @oldlist, 0, $itemcount) if @oldlist;
       }

       return @newlist;
}

1;