Perl, 293 bytes
-9 bytes graças a @Dom Hastings
{$==7+rand 30;@r=$"=();@a=((C)x4,(E)x3,("#")x1369,(" ")x1369);for$i(0..7+rand 30){$r[$i][$_]=splice@a,rand@a,1for 0..$=}$r[0][$=]=F;$r[-1][0]=P;$_=$r=join$/,$v="#"x($=+=3),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say
Adicione -E
sinalizador para executá-lo:
perl -E '{$==7+rand 30;@r=$"=();@a=((C)x4,(E)x3,("#")x1369,(" ")x1369);for$i(0..7+rand 30){$r[$i][$_]=splice@a,rand@a,1for 0..$=}$r[0][$=]=F;$r[-1][0]=P;$_=$r=join$/,$v="#"x($=+=3),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say'
No entanto, leva muito tempo para ser executado, então eu recomendo usar esta versão:
perl -E '{${$_}=8+rand 30for"=","%";@r=$"=();@a=((C)x4,(E)x3,("#")x($v=rand $=*$%),(" ")x($=*$%-$v));for$i(0..$%-1){$r[$i][$_]=splice@a,rand@a,1for 0..$=-1}$r[0][$=-1]=F;$r[$%-1][0]=P;$_=$r=join$/,$v="#"x($=+=2),(map"#@$_#",@r),$v;1while$r=~s/F(.{$=})?[^#F]/F$1F/s||$r=~s/[^#F](.{$=})?F/F$1F/s;$r!~/[CEP]/&&/C.*C/s&&/E/?last:redo}say'
Experimente online!
Explicação
{ # insira um bloco (que é usado como um loop) { $ == 7 + rand 30 ; # selecione aleatoriamente a largura do mapa -2 # (-2 porque ainda não incluímos as bordas) @r = $ "= (); # reset @r e defina $" como undef @a = ( # create uma lista do personagem que pode estar no tabuleiro ( C ) x4 , # 4 moedas 'C' ( E ) x3 , # 3 inimigos 'E' ( "#" ) x1369 , # 37 * 37 '#' (
"" ) x 1369 ); # 37 * 37 espaços para $ i ( 0..7 + margem 30 ) # crie o mapa 2D (7 + margem 30 é a altura, que é gerada agora) para $ _ ( 0 .. $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # índice [$ i] [$ _] recebe ...
emenda @ a , rand @ a , 1 # .. um caractere aleatório da lista gerada anteriormente # (o caractere é removido da lista graças a 'splice') } }
$ r [
0 ] [ $ =] = F ; # adicione a célula final
$ r [- 1 ] [ 0 ] = P ; # adicione a célula inicial
$ _ = $ r = # aqui nós geramos uma representação em cadeia do mapa
join $ /, # junte os seguintes elementos com novas linhas
$ v = "#" x ( $ = + = 3 ), # pela primeira vez linha de # only ( map "# @ $ _ #" , @r ), # adicione um # ao início e ao fim de cada linha
$ v ; # a última linha de #
Enquanto isso #, o seguinte regex substituirá todas as células acessíveis por uma célula F
$ r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # uma célula à direita ou na parte inferior de uma célula Célula F é substituída || # ou
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # uma célula à esquerda ou a parte superior de uma célula F é substituída
$ r ! ~ / [CEP] / # se não houver C, E ou P no mapa (o que significa que todos estavam acessíveis) &&
/C.*C/ s # e há pelo menos 2 moedas && / E / ? # e 1 inimigo por último : # o mapa é válido, saímos do loop refazer # else, começar de novo }
dizer # e imprimir o quadro
Demora muito tempo para ser executado, porque a lista da qual escolhemos aleatoriamente os personagens para colocar no tabuleiro ( @a
) contém 1369 espaços em branco e #
, e apenas 4 moedas e 3 inimigos. Portanto, se o tamanho da largura e da altura for pequeno, haverá muitos espaços e #
comparados à moeda e aos inimigos, portanto, é bem provável que um mapa aleatório não seja válido. É por isso que a versão "otimizada" é mais rápida: a lista da qual escolhemos os caracteres é um pouco maior que o mapa (a lista é @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: um número aleatório $v
de #
(inferior ao tamanho do mapa) e size of the map - $v
espaços em branco).