in reply to Puzzle

Speaking of that rewrite ... (This compiles in 5.6.0 and higher, due to use warnings; ... replace that with the -w switch if in 5.0x.)
#!/usr/bin/perl use strict; use warnings; srand; my @board = (1 .. 8, ''); print "\n" x 100; draw(\@board); print "Your goal is to match this pattern.\n"; print "You may move any square that is next to the blank spot.\n"; print "Press enter when ready. "; <>; randomize(\@board); while (1) { draw(\@board); check_win(\@board); { print "Which square will you move? "; chomp(my $move = <>); exit if $move =~ /^q($|\D)/i; my ($from) = move_is_ok(\@board, $move); redo unless $from; make_move(\@board, $from, $move); } } sub move_to_index { my $move = shift; my ($x, $y) = $move =~ /^([a-c])([1-3])$/; (ord($x) - ord('a')) * 3 + $y - 1; } #checks to make sure a proper piece is selected sub move_is_ok { my $board = shift; my ($move) = @_; my ($x, $y) = $move =~ /^([a-c])([1-3])$/; return undef unless $x && $y; my @neighbors_1 = grep { /[a-c]/ } (chr(ord($x) - 1), chr(ord( +$x) + 1)); my @neighbors_2 = grep { /[1-3]/ } ($y - 1, $y + 1); my @neighbors; push @neighbors, map { "${x}${_}" } @neighbors_2; push @neighbors, map { "${_}${y}" } @neighbors_1; grep { !$board->[$_] } map { move_to_index($_) } @neighbors; } # randomizes order of pieces for initial game play sub randomize { my $board = shift; $board->[4] = ''; my @squares = (0..3,5..8); my @values = (1 .. 8); while (@squares) { my $spot = splice @squares, rand $#squares, 1; $board->[$spot] = splice @values, rand $#values, 1; } } sub make_move { my $board = shift; my $from = shift; my $to = move_to_index(shift); @{$board}[$to, $from] = @{$board}[$from, $to]; } # checks for winning sequence sub check_win { my $board = shift; unless (grep { $_ + 1 != $board->[$_]} grep { length $board->[ +$_] } 0 .. $#$board) { print "YOU WIN!\n"; exit; } } # draws board sub draw { print "\n" x 100; print " 1 2 3\n"; print " +---+---+---+\n"; printf " a| %1s | %1s | %1s |\n", @{$_[0]}[0..2]; print " +---+---+---+\n"; printf " b| %1s | %1s | %1s |\n", @{$_[0]}[3..5]; print " +---+---+---+\n"; printf " c| %1s | %1s | %1s |\n", @{$_[0]}[6..8]; print " +---+---+---+\n"; print "\n" x13; }

The major differences are:

Looks like you got your homework cut out for you, AnonyMonk! Good original posting. Your code did satisfy the First Criterion - it worked. The Second Criterion is much harder - making it maintainable. Good luck!

If you have any questions about what I did, please let me know. I deliberately didn't comment my code so that you'd have to dig around in the literature to understand the more advanced features I used.

------
We are the carpenters and bricklayers of the Information Age.

The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.