Perl, 293 Bytes
-9 Bytes dank @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
Fügen Sie ein -E
Flag hinzu, um es auszuführen:
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'
Die Ausführung dauert jedoch sehr lange. Ich empfehle daher, stattdessen diese Version zu verwenden:
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'
Probieren Sie es online aus!
Erläuterung
{ # einen Block eingeben (der als Schleife verwendet wird) { $ == 7 + rand 30 ; # wähle zufällig die Breite der Karte -2 # (-2, da wir die Ränder noch nicht einschließen) @r = $ "= (); # setze @r zurück und setze $" auf undef @a = ( # create eine Liste der Charaktere, die auf dem Brett sein können ( C ) x4 , # 4 Münzen 'C' ( E ) x3 , # 3 Feinde 'E' ( "#" ) x1369 , # 37 * 37 '#' (
"" ) X1369 ); # 37 * 37 Räume für $ i ( 0..7 + rand 30 ) # Erstellen Sie die 2D - Karte (7 + rand 30 ist die Höhe, die gerade erzeugt wird) für $ _ ( 0 . $ = - 1 ) {
$ r [ $ i ] [ $ _ ] = # index [$ i] [$ _] empfängt ...
splice @ a , rand @ a , 1 # .. ein zufälliges Zeichen aus der zuvor generierten Liste # (das Zeichen ist dann dank 'splice' von der Liste entfernt) } }
$ r [
0 ] [ $ =] = F ; # füge die Zielzelle hinzu
$ r [- 1 ] [ 0 ] = P ; # füge die Startzelle hinzu
$ _ = $ r = # hier generieren wir eine String-Darstellung des Map-
Joins $ /, # verbinde die folgenden Elemente mit Zeilenumbrüchen
$ v = "#" x ( $ = + = 3 ), # a first Nur Zeile # ( Map "# @ $ _ #" , @r ), # Fügen Sie am Anfang und am Ende jeder Zeile ein # hinzu
$ v ; # die letzte Zeile von #
1 während # der folgende reguläre Ausdruck jede zugängliche Zelle durch ein F
$ r = ~ s / F (. { $ =}) Ersetzt ? [^ # F ] / F $ 1F / s # eine Zelle rechts oder unten in a F-Zelle wird ersetzt || # oder
$ r = ~ s / [^ # F ] (. { $ =})? F / F $ 1F / s ; # Eine Zelle links oder oben in einer F-Zelle wird durch
$ r ! ~ / [CEP] / # ersetzt, wenn auf der Karte kein C, E oder P vorhanden ist (was bedeutet, dass alle zugänglich waren) &&
/C.*C/ s # und es gibt mindestens 2 Münzen && / E / ? # und 1 Feind zuletzt : # Wenn die Karte gültig ist, verlassen wir die Schleife, wiederholen # sonst, beginnen von vorne }
sagen # und drucken das Brett
Das Ausführen dauert lange, da die Liste, aus der wir zufällig die Zeichen auswählen, die auf das Brett gelegt werden sollen ( @a
), 1369 Leerzeichen und #
und nur 4 Münzen und 3 Feinde enthält. Wenn also die Größe der Breite und Höhe klein ist, gibt es viele Leerzeichen und im #
Vergleich zur Münze und den Feinden ist es sehr wahrscheinlich, dass eine zufällige Karte nicht gültig ist. Deshalb ist die "optimierte" Version schneller: Die Liste, aus der wir die Zeichen auswählen, ist nur ein wenig größer als die Karte (die Liste ist @a=((C)x4,(E)x3,("#")x($v=rand $=*$%),($")x($=*$%-$v))
: eine Zufallszahl $v
von #
(schlechter als die Größe der Karte) und size of the map - $v
Leerzeichen).