#!/usr/bin/perl -w

#===========================================================#
# Lay out an OOP structure for the puzzle code

package MyNode;

sub new {
	my $package = shift;
	my $self = { @_ };
	return bless($self, $package);
}

sub expand {
	my $self = shift;

	my $blankIndex;
	foreach (0..8) {
		$blankIndex = $_ if $self->{board}[$_] == 0;
	}

	my @adjacentBlocksTo = (
		[1,3],   [0,2,4],   [1,5],
		[0,4,6], [1,3,5,7], [2,4,8],
		[3,7],   [4,6,8],   [5,7],
	);

	my @movableBlocks = @{$adjacentBlocksTo[$blankIndex]};

	my @boardCopy = ();
	my @expandedNodelist = ();
	foreach (@movableBlocks) {
		my $newNode = $self->clone();
		$newNode->{board}[$blankIndex] = $newNode->{board}[$_];
		$newNode->{board}[$_] = 0;
		push(@expandedNodeList, $newNode);
	}
	return \@expandedNodeList;
}

sub clone {
	my $self = shift;
	my @boardCopy = @{$self->{board}};
	return bless {board => \@boardCopy};
}


sub isGoal {
	# Return true if goal state has been reached
	my $self = shift;
	foreach (0..8) {
		return 0 if $self->{board}[$_] != $_;
	}
	return 1;
}

sub areEqual {
	# Return true if two nodes have the same board state
	my $self = shift;
	my $other = shift;
	foreach (0..8) {
		return 0 if $self->{board}[$_] != $other->{board}[$_];
	}
	return 1;
}

sub asText{
	# Return node as text (for verbose output)
	my $self = shift;
	my @puzzle = @{$self->{board}};

	my $result = "\n[ $puzzle[0] $puzzle[1] $puzzle[2] ]\n";
	$result   .=   "[ $puzzle[3] $puzzle[4] $puzzle[5] ]\n";
	$result   .=   "[ $puzzle[6] $puzzle[7] $puzzle[8] ]\n\n";
	return $result;
}

#===========================================================#
1;
