if(@ARGV<4) {print "\nUse: SIZE START_X START_Y [0,1]" and exit;} our ($N,$X0,$Y0,$VERBOSE) = @ARGV ; our ($MOVES,@moves,@board)= (0,([-2,-1], [-1,-2], [-2 ,1],[-1 ,2], [2 ,-1], [1, -2],[2, 1],[1, 2]),()); my $last_move = [$X0,$Y0] and inform_board(); $last_move = inform_board($last_move) while($MOVES< $N*$N); ############### SUBROUTINES ######################## sub init { return ($_[0]>$N/2)? init($N-1-$_[0],$_[1]) : ($_[1]>$N/2? init($_[0],$N-1-$_[1]):($_[0]>=2 && $_[1]>=2? 8:(($_[0] >=2 && $_[1]==1 || $_[1]>=2 && $_[0]==1)?6:($_[0]+$_[1]>1?4:($_[0]+$_[1]==1?3:2)))) )} sub inRange{ my ($pos, $D) = @_; my ($x,$y) = ($pos->[0]+$D->[0], $pos->[1]+$D->[1]); return ($x>=0 && $x<$N && $y >= 0 && $y<$N && $board[$x][$y]>=0)? [$x,$y] : 0; } sub inform_board { my ($moved_to) = @_; if($moved_to) { $MOVES++; print "\n$MOVES.",$moved_to->[0],",",$moved_to->[1] if $VERBOSE; my ($MIN,$next_to_move) = (10,[]); foreach(@moves) { if(my $finalPos = inRange($moved_to, $_)) { my $value_ref = \$board[$finalPos->[0]][$finalPos->[1]]; ($MIN,$next_to_move, $board[$moved_to-> [0]][$moved_to->[1]]) = ($$value_ref,$finalPos,0) if(--$$value_ref>=0 && $$value_ref < $MIN); } } return $next_to_move; } else { push @board, [(0)x $N] for(1..$N); for my $i (0..$N-1) { $board[$i][$_] = init($i,$_) for (0..$N-1);} } }