2015-04-03 4 views
0

Я пытаюсь создать генератор лабиринта, и у меня возникают проблемы с моим кодом. Я относительно новичок в Perl, так голый со мной. В начале моего скрипта я создаю многомерный массив (@maze) с X числом столбцов и Y числом строк. Существует цикл, который выполняет итерацию через массив и устанавливает все элементы в начальное значение 1. Подпрограмма get_neighbors предполагает создание хэша с ключами top, right, bottom, left. Затем он устанавливает значения для этих ключей на основе кодов x и y, которые передаются. Для ключа top я устанавливаю его значение непосредственно над элементом, который должен быть [ $y - 1 ][ $x ]. Я предполагал, что если, например, были переданы координаты 0, 0, то top будет установлен в undef, так как это не действительный элемент/позиция, но это не так. Оно установлено на 1. Не знаете, почему .. Наделся кто-то может определить и объяснить, почему это происходит. Вот весь сценарий:Неожиданные значения в хеше?

#!/usr/bin/perl 

use warnings; 
use strict; 
use Switch; 
use Data::Dumper; 

# Rows is set equal to the first arg passed in 
# unless it hasn't been. If it hasn't been, the 
# value defaults to 60. This also applies to the 
# columns. 
my $rows = (defined($ARGV[ 0 ]) ? $ARGV[ 0 ] : 60); 
my $cols = (defined($ARGV[ 1 ]) ? $ARGV[ 1 ] : 60); 
my $cells = $rows * $cols; 

my @maze; 

# "Pre-allocate" each "Cell" for the maze. 
for(my $y = 0; $y < $rows; ++$y) { 
    for(my $x = 0; $x < $cols; ++$x) { $maze[ $y ][ $x ] = 1; } 
} 

# Run 
main(); 

#-------------------------- 
# Main ~ 
#-------------------------- 
sub main { 
    print Dumper(get_neighbors(0, 0)); 

    generate(); 
    print_maze(); 

    return; 
} 

#-------------------------- 
# Generate the maze w/ BFS 
#-------------------------- 
sub generate { 

    return; 
} 

#-------------------------- 
# Print maze to console 
#-------------------------- 
sub print_maze { 
    for(my $y = 0; $y < $rows; ++$y) { 
     for(my $x = 0; $x < $cols; ++$x) { 
      print $maze[ $y ][ $x ] . " "; 
     } 
     print "\n"; 
    } 
} 

#-------------------------- 
# Returns the values of 
# neighboring cells 
#-------------------------- 
sub get_neighbors { 
    my $x = shift; 
    my $y = shift; 

    my %neighbors; 

    $neighbors{'top'} = defined($maze[ $y - 1 ][ $x ]) ? $maze[ $y - 1 ][ $x ] : undef; 
    $neighbors{'bottom'} = defined($maze[ $y + 1 ][ $x ]) ? $maze[ $y + 1 ][ $x ] : undef; 
    $neighbors{'left'} = defined($maze[ $y ][ $x - 1 ]) ? $maze[ $y ][ $x - 1 ] : undef; 
    $neighbors{'right'} = defined($maze[ $y ][ $x + 1 ]) ? $maze[ $y ][ $x + 1 ] : undef; 

    return %neighbors; 
} 

Выездной когда я бег этот сценарий:

# perl mazegen.pl 10 10 
$VAR1 = 'left'; 
$VAR2 = 1; 
$VAR3 = 'right'; 
$VAR4 = 1; 
$VAR5 = 'top'; 
$VAR6 = 1; 
$VAR7 = 'bottom'; 
$VAR8 = 1; 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 
+0

Заметим, что '$ соседей { 'сверху'} = определена ($ лабиринте [ $ y - 1] [$ x])? $ maze [$ y - 1] [$ x]: undef' * совпадает * с '$ neighbors {'top'} = $ maze [$ y-1] [$ x]'. Кроме того, вы можете использовать определенные или для 'my $ rows = (определенные ($ ARGV [0])? $ ARGV [0]: 60)' писать 'my $ rows = $ ARGV [0] // 60' , Также лучше избегать цикла 'for' C-стиля и итерации по диапазону, поэтому' for (my $ y = 0; $ y <$ rows; ++ $ y) {...} 'становится' для my $ y (0 .. $ rows-1) {...} ' – Borodin

ответ

2

В Perl, отрицательный индекс на подсчетах массива от конца массива.

Например:

my @foo = ('a', 'b', 'c', 'd', 'e'); 

say $foo[-2]; 

отображения будет d.

Это должно показать, что происходит:

use warnings; 
use strict; 
use feature 'say'; 

my @maze = ([ 'a' .. 'e' ], 
      [ 'f' .. 'j' ], 
      [ 'k' .. 'o' ], 
      [ 'p' .. 't' ], 
      [ 'u' .. 'y' ],); 

for my $row (@maze) { 
    say "@$row"; 
} 

my %neighbors; 
my ($x, $y) = (0, 0); 

# The // defined-or was added in Perl 5.10. These are equivalent: 
# $foo = defined($bar) ? $bar : 'toast'; 
# $foo = $bar // 'toast'; 

$neighbors{'top'} = $maze[ $y - 1 ][ $x ] // '-'; 
$neighbors{'bottom'} = $maze[ $y + 1 ][ $x ] // '-'; 
$neighbors{'left'} = $maze[ $y ][ $x - 1 ] // '-'; 
$neighbors{'right'} = $maze[ $y ][ $x + 1 ] // '-'; 

say " $neighbors{top}"; 
say "$neighbors{left} $maze[$y][$x] $neighbors{right}"; 
say " $neighbors{bottom}"; 

Выход:

a b c d e 
f g h i j 
k l m n o 
p q r s t 
u v w x y 
    u 
e a b 
    f 
+0

Также не ответ, просто предложение: не используйте [' Switch'] (https://metacpan.org/pod/ Переключатель # NAME). Это вызовет неприятные головные боли в будущем. –

+0

А, да, я думаю, что я помню, когда-то читал об этом. Я поменю свой код, чтобы проверить, находятся ли в коордах границы, и установите undef, если нет. Спасибо за быстрый ответ! – th3v0id

0

Try:

$neighbors{ top } = $y > 0    ? $maze[ $y - 1 ][ $x ] : undef; 
$neighbors{ bottom } = $y < $#maze   ? $maze[ $y + 1 ][ $x ] : undef; 
$neighbors{ left } = $x > 0    ? $maze[ $y ][ $x - 1 ] : undef; 
$neighbors{ right } = $x < $#{ $maze[0] } ? $maze[ $y ][ $x + 1 ] : undef; 
Смежные вопросы