Perl, 293 байти
-9 байт завдяки @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
Додати -E
прапор для запуску:
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'
Однак для запуску потрібно багато часу, тому рекомендую замість цього використовувати цю версію:
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'
Спробуйте в Інтернеті!
Пояснення
{ # введіть блок (який використовується як цикл) { $ == 7 + rand 30 ; # Випадковим чином вибрати ширину карти -2 # (-2 , тому що ми не включаємо кордону поки) @r = $ «= (); # скидання @R, і безліч $» на невизначений значення @a = ( # створити список символів, які можуть бути на дошці ( C ) x4 , №4 монети 'C' ( E ) x3 , №3 ворогів 'E' ( "#" ) x1369 , # 37 * 37 '#' (
"" ) x1369 ); # 37 * 37 простору для $ я ( 0..7 + ранд 30 ) # створити 2D карту (7 + 30 рандів висота, яка формується тільки зараз) за $ _ ( 0 . $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # індекс [$ i] [$ _] отримує ...
зрощення @ a , rand @ a , 1 # .. випадковий символ зі списку, сформованого раніше # (символ є потім вилучено зі списку завдяки "зрощенню") } }
$ r [
0 ] [ $ =] = F ; # додати обробну комірку
$ r [- 1 ] [ 0 ] = P ; # додайте початкову клітинку
$ _ = $ r = # тут ми створюємо рядкове представлення карти
join $ /, # приєднуємо наступні елементи з новими рядками
$ v = "#" x ( $ = + = 3 ), # a рядок # тільки ( карта "# @ $ _ #" , @r ), # додайте # на початок і в кінець кожного рядка
$ v ; # останній рядок з #
Тим часом # наступний регулярний вимір замінить кожну доступну клітинку на F
- r = ~ s / F (. { $ =})? [^ # F ] / F $ 1F / s # комірка праворуч або внизу F комірка замінюється || # або
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # клітинка зліва або вгорі клітинки F замінюється
$ r ! ~ / [CEP] / #, якщо на карті немає C, E або P (тобто всі вони були доступні) &&
/C.*C/ s # і є щонайменше 2 монети && / E / ? # і 1 ворог останній : # карта дійсна, ми виходимо з циклу повторення # else, починаємо спочатку }
скажімо # і друкуємо дошку
Бігати потрібно багато часу, тому що список, з якого ми випадково вибираємо символів, які слід поставити на дошку ( @a
), містить 1369 пробілів і #
, і лише 4 монети та 3 вороги. Отже, якщо розміри ширини та висоти невеликі, місця є дуже багато, і #
порівняно з монетою та ворогами, тому цілком ймовірно, що випадкова карта не буде дійсною. Ось чому «оптимізовані» версія швидше: список , з якого ми вибираємо символи просто трохи більше , ніж карта (список @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: випадкове число $v
з #
(нижче розміру карти), і size of the map - $v
пробіли).