Perl, 293 bytes
-9 bytes gracias 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
Agregar -E
bandera para ejecutarlo:
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'
Sin embargo, lleva mucho tiempo ejecutarlo, por lo que recomiendo usar esta versión en su lugar:
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'
Pruébalo en línea!
Explicación
{ # ingrese un bloque (que se utiliza como un bucle) { $ == 7 + rand 30 ; # selecciona al azar el ancho del mapa -2 # (-2 porque todavía no incluimos los bordes) @r = $ "= (); # reset @r, y establece $" en undef @a = ( # create una lista del personaje que puede estar en el tablero ( C ) x4 , monedas # 4 'C' ( E ) x3 , enemigos # 3 'E' ( "#" ) x1369 , # 37 * 37 '#' (
"" ) x1369 ); # 37 * 37 espacios para $ i ( 0..7 + rand 30 ) # crea el mapa 2D (7 + rand 30 es la altura, que se genera ahora) por $ _ ( 0 .. $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # índice [$ i] [$ _] recibe ...
splice @ a , rand @ a , 1 # .. un carácter aleatorio de la lista generada anteriormente # (el carácter es luego eliminado de la lista gracias a 'splice') } }
$ r [
0 ] [ $ =] = F ; # agregue la celda de finalización
$ r [- 1 ] [ 0 ] = P ; # agregue la celda de inicio
$ _ = $ r = # aquí generamos una representación de cadena del mapa
unir $ /, # unir los siguientes elementos con nuevas líneas
$ v = "#" x ( $ = + = 3 ), # un primero línea de # solamente ( mapa "# @ $ _ #" , @r ), # agregue un # al principio y al final de cada línea
$ v ; # la última línea de #
1 mientras que # la siguiente expresión regular reemplazará cada celda accesible con una F
$ r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # una celda a la derecha o al final de un La celda F se reemplaza || # o
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # una celda a la izquierda o la parte superior de una celda F se reemplaza
$ r ! ~ / [CEP] / # si no hay C, E o P en el mapa (lo que significa que todos eran accesibles) &&
/C.*C/ s # y hay al menos 2 monedas && / E / ? # y 1 enemigo al final : # el mapa es válido, salimos del ciclo rehacer # más, comenzamos de nuevo }
di # e imprimimos el tablero
Tarda mucho tiempo en ejecutarse, porque la lista de la que elegimos al azar los personajes para poner en el tablero ( @a
) contiene 1369 espacios en blanco y #
, y solo 4 monedas y 3 enemigos. Entonces, si el tamaño del ancho y la altura son pequeños, hay muchos espacios y en #
comparación con la moneda y los enemigos, por lo que es muy probable que un mapa aleatorio no sea válido. Es por eso que la versión "optimizada" es más rápida: la lista de la que elegimos los caracteres es un poco más grande que el mapa (la lista es @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: un número aleatorio $v
de #
(inferior al tamaño del mapa) y size of the map - $v
espacios en blanco).