Perl, 293 bajtów
-9 bajtów dzięki @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
Dodaj -E
flagę, aby go uruchomić:
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'
Jednak uruchomienie zajmuje dużo czasu, więc zamiast tego zalecamy użycie tej wersji:
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'
Wypróbuj online!
Wyjaśnienie
{ # wprowadź blok (który jest używany jako pętla) { $ == 7 + rand 30 ; # losowo wybierz szerokość mapy -2 # (-2, ponieważ nie uwzględniamy jeszcze granic) @r = $ "= (); # reset @r i ustaw $" na undef @a = ( # create lista postaci, które mogą znajdować się na planszy ( C ) x4 , # 4 monety „C” ( E ) x3 , # 3 wrogów „E” ( „#” ) x1369 , # 37 * 37 '#' (
„” ) x1369 ); # 37 * 37 spacji dla $ i ( 0..7 + rand 30 ) # utwórz mapę 2D (7 + rand 30 to wysokość, która jest właśnie generowana) dla $ _ ( 0 .. $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # index [$ i] [$ _] otrzymuje ...
splice @ a , rand @ a , 1 # .. losowy znak z wcześniej wygenerowanej listy # (znak jest następnie usunięty z listy dzięki „splice”) } }
$ r [
0 ] [ $ =] = F ; # dodaj komórkę końcową
$ r [- 1 ] [ 0 ] = P ; # dodaj komórkę początkową
$ _ = $ r = # tutaj generujemy ciąg reprezentujący mapę
dołącz $ /, # połącz poniższe elementy z znakami nowej linii
$ v = "#" x ( $ = + = 3 ), # pierwszy linia tylko # ( mapa "# @ $ _ #" , @r ), # dodaj # na początku i na końcu każdej linii
$ v ; # ostatnia linia z #
1 podczas gdy następujący wyrażenie regularne zamieni każdą dostępną komórkę na F
$ r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # komórka po prawej lub na dole Komórka F zostaje zastąpiona || # lub
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # komórka po lewej lub na górze komórki F jest zastępowana
$ r ! ~ / [CEP] / # jeśli na mapie nie ma C, E lub P (co oznacza, że wszystkie były dostępne) &&
/C.*C/ s # i istnieje co najmniej 2 monety && / E / ? # i 1 ostatni wróg : # mapa jest ważna, wychodzimy z pętli przerób # innego, zaczynamy od nowa }
powiedz # i wydrukuj planszę
Uruchomienie zajmuje dużo czasu, ponieważ lista, z której losowo wybieramy postacie do umieszczenia na planszy ( @a
), zawiera 1369 białych znaków #
i tylko 4 monety i 3 wrogów. Więc jeśli rozmiar szerokości i wysokości jest niewielki, istnieje wiele miejsc w #
porównaniu z monetą i wrogami, więc jest całkiem prawdopodobne, że losowa mapa nie będzie ważna. Dlatego „zoptymalizowane” wersja jest szybsza: lista, z której możemy odebrać znaków jest tylko trochę większa niż mapie (lista jest @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: liczba losowa $v
z #
(gorszy od wielkości mapy) i size of the map - $v
spacji).