Perl, 293 byte
-9 byte terima kasih kepada @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
Tambahkan -E
bendera untuk menjalankannya:
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'
Namun, ini membutuhkan waktu lama untuk dijalankan, jadi saya sarankan menggunakan versi ini sebagai gantinya:
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'
Cobalah online!
Penjelasan
{ # masukkan blok (yang digunakan sebagai loop) { $ == 7 + rand 30 ; # pilih secara acak lebar peta -2 # (-2 karena kita belum memasukkan batas) @r = $ "= (); # reset @r, dan atur $" ke undef @a = ( # create daftar karakter yang ada di papan ( C ) x4 , koin # 4 'C' ( E ) x3 , musuh # 3 'E' ( "#" ) x1369 , ) x1369
# 37 * 37 '#' (
"" [); # 37 * 37 spasi untuk $ i ( 0..7 + rand 30 ) # buat peta 2D (7 + rand 30 adalah tinggi, yang dihasilkan sekarang) untuk $ _ ( 0 .. $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # index [$ i] [$ _] menerima ...
splice @ a , rand @ a , 1 # .. karakter acak dari daftar yang sebelumnya dihasilkan # (karakternya adalah lalu dihapus dari daftar berkat 'splice') } 0 $ =] = F ;
}
$ r ] [ # tambahkan sel selesai
$ r [- 1 ] [ 0 ] = P ; # tambahkan sel awal
$ _ = $ r = # di sini kami menghasilkan representasi string dari peta,
bergabung dengan $ /, # gabungkan elemen-elemen berikut dengan baris baru
$ v = "#" x ( $ = + = 3 ), # a first baris # saja ( peta "# @ $ _ #" , @r
), # tambahkan # ke awal dan akhir setiap baris
$ v ; # baris terakhir #
1 sementara # regex berikut akan mengganti setiap sel yang dapat diakses dengan F
$ r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # sel di sebelah kanan atau bawah sebuah Sel F diganti || # atau
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # sel di sebelah kiri atau atas sel F diganti
$ r ! ~ / [CEP] / # jika tidak ada C, E atau P di peta (artinya semuanya dapat diakses) &&
/C.*C/ # dan cetak papans # dan setidaknya ada 2 koin && / E / ? # dan 1 musuh terakhir : # peta itu valid, kita keluar dari loop ulang # lagi, mulai dari awal }
katakan
Butuh waktu lama untuk dijalankan, karena daftar dari mana kita secara acak memilih karakter untuk diletakkan di papan tulis ( @a
) berisi 1.369 spasi putih dan #
, dan hanya 4 koin dan 3 musuh. Jadi jika ukuran lebar dan tinggi kecil, ada banyak ruang dan #
dibandingkan dengan koin dan musuh, jadi sangat mungkin bahwa peta acak tidak akan valid. Itu sebabnya "dioptimalkan" versi lebih cepat: daftar dari mana kita memilih karakter hanya sedikit lebih besar dari peta (daftar adalah @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: nomor acak $v
dari #
(rendah dengan ukuran peta), dan size of the map - $v
spasi putih).