Perl, 293 byte
-9 byte nhờ @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
Thêm -E
cờ để chạy nó:
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'
Tuy nhiên, phải mất một thời gian dài để chạy, vì vậy tôi khuyên bạn nên sử dụng phiên bản này thay thế:
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'
Hãy thử trực tuyến!
Giải trình
{ # nhập một khối (được sử dụng như một vòng lặp) { $ == 7 + rand 30 ; # chọn ngẫu nhiên độ rộng của bản đồ -2 # (-2 vì chúng tôi chưa bao gồm các đường viền) @r = $ "= (); # reset @r và đặt $" thành undef @a = ( # tạo một danh sách các nhân vật có thể ở trên bảng ( C ) x4 , # 4 xu 'C' ( E ) x3 , # 3 kẻ thù 'E' ( "#" ) x1369 , # 37 * 37 '#' (
"" ) x1369 ); # 37 * 37 khoảng trắng cho $ i ( 0..7 + rand 30 ) # tạo bản đồ 2D (7 + rand 30 là chiều cao, được tạo ngay bây giờ) với $ _ ( 0 .. $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # index [$ i] [$ _] nhận ...
splice @ a , rand @ a , 1 # .. một ký tự ngẫu nhiên từ danh sách được tạo trước đó # (ký tự là sau đó xóa khỏi danh sách nhờ vào 'splice') } }
$ r [
0 ] [ $ =] = F ; # thêm ô kết thúc
$ r [- 1 ] [ 0 ] = P ; # thêm ô bắt đầu
$ _ = $ r = # ở đây chúng tôi tạo một chuỗi đại diện cho bản đồ
tham gia $ /, # tham gia các phần tử sau với dòng mới
$ v = "#" x ( $ = + = 3 ), # a trước dòng # only ( bản đồ "# @ $ _ #" , @r ), # thêm # vào đầu và cuối của mỗi dòng
$ v ; # dòng cuối cùng của #
1 trong khi # regex sau sẽ thay thế mọi ô có thể truy cập bằng F
$ r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # một ô ở bên phải hoặc dưới cùng của một Ô F được thay thế | | # hoặc
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # một ô ở bên trái hoặc trên cùng của một ô F được thay thế
$ r ! ~ / [CEP] / # nếu không có C, E hoặc P trên bản đồ (có nghĩa là tất cả chúng đều có thể truy cập được) &&
/C.*C/ s # và có ít nhất 2 xu && / E / ? # và 1 kẻ thù cuối cùng : # bản đồ hợp lệ, chúng tôi thoát khỏi vòng lặp làm lại # khác, bắt đầu lại }
nói # và in bảng
Phải mất một thời gian dài để chạy, bởi vì danh sách mà chúng tôi chọn ngẫu nhiên các ký tự để đặt lên bảng ( @a
) chứa 1369 khoảng trắng #
và chỉ có 4 đồng xu và 3 kẻ thù. Vì vậy, nếu kích thước của chiều rộng và chiều cao nhỏ, có rất nhiều khoảng trống và #
so với đồng xu và kẻ thù, thì rất có khả năng một bản đồ ngẫu nhiên sẽ không hợp lệ. Đó là lý do tại sao phiên bản "tối ưu hóa" là nhanh hơn: danh sách từ đó chúng ta chọn các nhân vật chỉ là lớn hơn một chút so với bản đồ (danh sách là @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: một số ngẫu nhiên $v
của #
(kém hơn so với kích thước của bản đồ), và size of the map - $v
khoảng trắng).