# 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;