Generieren von Picture Mazes

20

Herausforderung

Schreiben Sie ein Programm / eine Funktion, die ein "Bild" akzeptiert und ein aus diesem Bild gebildetes Bildlabyrinth ausgibt .

Eingang

Ihr Programm sollte zwei Argumente akzeptieren:

  • Ich, das Bild, aus dem sich das Labyrinth zusammensetzt
  • S, ein Boolescher Wert, der angibt, ob die Lösung für das Labyrinth angezeigt werden soll oder nicht

Ich werde in der folgenden Form gegeben:

.......
.#####.
.#####.
#######
.#####.
.#####.
.......

Dabei handelt #es sich um Zellen, die in den Lösungspfad aufgenommen werden sollen, und .um Zellen, die ausgeschlossen werden sollen. Sie können die Swap .‚s, #‘ s und neue Zeilen mit jedem Charakter Ihrer solange sie voneinander unterscheiden zu wählen. Alternativ können Sie eine tatsächliche Bitmap des Eingabebildes akzeptieren.

Ausgabe

Das resultierende Labyrinth sollte die folgende Form haben:

###############
#             #
# ### ####### #
# #.........# #
# #.#######.# #
# #.#.......# #
###.#.#########
....#.#........
#####.#.#######
#  ...#.....  #
# #.#######.# #
# #.........# #
# ####### ### #
#   #       # #
###############

wo #‚s bezeichnen die Wände, .‘ s bezeichnen die Abschnitte des Weges, der ein Teil der Lösung sind, und Zwischenräume sind Pfade von der Lösung ausgeschlossen. Die .'s können durch Leerzeichen ersetzt werden, wenn S falsch ist. Auch hier können Zeichen mit anderen Zeichen Ihrer Wahl ausgetauscht werden, oder Sie können eine tatsächliche Bitmap des Labyrinths mit der hervorgehobenen Lösung ausgeben.

Zusätzliche Details

  • Die Pfade müssen eine Zelle breit sein (der Pfad darf kein riesiger Pool von leeren Räumen sein)
  • Das Labyrinth darf keine Schleifen enthalten
  • Das Labyrinth muss vollständig verbunden sein (alle Zellen müssen vom Eingang / Ausgang aus erreichbar sein)
  • Das Labyrinth muss von Mauern umgeben sein (es sei denn, es ist ein Eingang / Ausgang)
  • Der Lösungspfad darf keine Sackgassen enthalten
  • Es muss genau 1 Eingang und 1 Ausgang für das Labyrinth geben
  • Der Eingang und der Ausgang müssen am Rand des Gitters und neben einer im Lösungspfad enthaltenen Zelle ausgerichtet sein
  • Sie können wählen, wo der Eingang und der Ausgang platziert werden
  • Sie können davon ausgehen, dass aus dem angegebenen Eingabebild ein gültiger Pfad gebildet werden kann

(Zur Verdeutlichung hinzugefügt) Das folgende Diagramm zeigt, wie der Lösungspfad mit dem Eingabebild korreliert:

Input (I): |    Output:            |    Corresponding Cells: 
           |                       |    (@'s denote #'s from I)
           |                       |
.......    |    ###############    |    ###############
.#####.    |    #             #    |    #             #
.#####.    |    # ### ####### #    |    # ### ####### #
#######    |    # #.........# #    |    # #@.@.@.@.@# #
.#####.    |    # #.#######.# #    |    # #.#######.# #
.#####.    |    # #.#.......# #    |    # #@#@.@.@.@# #
.......    |    ###.#.#########    |    ###.#.#########
           |    ....#.#........    |    .@.@#@#@.@.@.@.
           |    #####.#.#######    |    #####.#.#######
           |    #  ...#.....  #    |    #  @.@#@.@.@  #
           |    # #.#######.# #    |    # #.#######.# #
           |    # #.........# #    |    # #@.@.@.@.@# #
           |    # ####### ### #    |    # ####### ### #
           |    #   #       # #    |    #   #       # #
           |    ###############    |    ###############
           |                       |

Testfälle

Gießkanne zB aus Wikipedia :

Eingang:

..................
..................
.......####.......
......##..##......
.....##....##....#
.....#......#...##
.#############.##.
##..############..
#...###########...
#...##########....
#...##########....
#...##########....
#...##########....
....##########....
....##########....
....##########....
..................
..................

Ausgabe (S = falsch):

#####################################
#   #     #   #   #     #           #
# ### ### ### # # ##### ### ### ### #
#     # #   # # #         # #   # # #
# ### # ##### # ########### # ### # #
# # #         #           # # #   # #
# # # ### ##### # ### ### # ### ### #
#   # # #   #   # # #   # #   # #   #
# ### # ##### ##### ### ##### # # ###
# #   #       #   #   #       # # #  
### ####### ### ### # ### ##### ### #
#   #     # #   #   #   # #   # #   #
# ### ##### # ### ####### # # # # # #
# #       #             #   # #   # #
# # ##### ############# ### ### ### #
#   #   #       #     #   # #   # # #
# ### # ####### # ### ### # # ### # #
# # # #         #   # #   #   #     #
# # # ### ######### # # ##### # #####
# #   # # #       # #   #   # # #   #
# ##### # # ##### # ##### # # ### # #
#       # #   #   # #     # #   # # #
# ### ### ### # ### # ##### ####### #
#   # # #     # #   # #       #     #
# # # # ####### # ### # ##### # ### #
  # # # #   #   #     #     # #   # #
### # # # # # ############# # ### # #
#   # # # #   #         #   # #   # #
##### # # ##### ####### # ### ##### #
#     # # #   #       # #   #       #
##### # # # # ####### # ### #########
#     #     #         #       #     #
# ### ######### ############# # #####
# # #   #     # #       #     #     #
# # ######### # ####### ####### ### #
#             #                 #   #
#####################################

Ausgabe (S = wahr):

#####################################
#   #     #   #   #     #           #
# ### ### ### # # ##### ### ### ### #
#     # #   # # #         # #   # # #
# ### # ##### # ########### # ### # #
# # #         #.......    # # #   # #
# # # ### #####.# ###.### # ### ### #
#   # # #   #...# # #...# #   # #   #
# ### # #####.##### ###.##### # # ###
# #   #    ...#   #   #...    # # #..
### #######.### ### # ###.##### ###.#
#   #     #.#   #   #   #.#   # #...#
# ### #####.# ### #######.# # # #.# #
# #.......#.............#...# #...# #
# #.#####.#############.###.###.### #
#...#   #.......#.....#...#.#...# # #
#.### # #######.#.###.###.#.#.### # #
#.# # #  .......#...#.#...#...#     #
#.# # ###.#########.#.#.##### # #####
#.#   # #.#.......#.#...#...# # #   #
#.##### #.#.#####.#.#####.#.# ### # #
#.      #.#...#...#.#.....#.#   # # #
#.### ###.###.#.###.#.#####.####### #
#.  # # #.....#.#...#.#.....  #     #
#.# # # #######.#.###.#.##### # ### #
..# # # #...#...#.....#.....# #   # #
### # # #.#.#.#############.# ### # #
#   # # #.#...#.........#...# #   # #
##### # #.#####.#######.#.### ##### #
#     # #.#...#.......#.#...#       #
##### # #.#.#.#######.#.###.#########
#     #  ...#.........#.....  #     #
# ### ######### ############# # #####
# # #   #     # #       #     #     #
# # ######### # ####### ####### ### #
#             #                 #   #
#####################################

Bitmap-Beispiel (dasselbe Labyrinth wie oben):

Eingabe: Bitmap eingebenAusgabe (S = falsch): Die Ausgabe-Bitmap-Lösung ist nicht hervorgehobenAusgabe (S = wahr):Ausgabe-Bitmap-Lösung hervorgehoben

Dendrobium
quelle
4
Es könnte nur ich sein, aber ich sehe das Eingabebild nicht im Ausgabelabyrinth.
Mike Bufardeci
@ mike-bufardeci Ein Diagramm wurde hinzugefügt, das das Eingabebild im Ausgabelabyrinth zeigt. Hoffentlich hilft das!
Dendrobium,
2
Es scheint keine Regel zu geben, nach der das Labyrinth verbunden sein muss. Wäre das eine gültige Lösung? Es scheint auch keine Regel zu geben, dass das Gitter von Wänden umgeben sein muss (es sei denn, jede Nicht-Wand wird als Eingang oder Ausgang betrachtet). Wäre das eine gültige Lösung?
Martin Ender
1
Bitte fügen Sie auch einige weitere Testfälle hinzu.
Fehler
@ Martinbüttner Das Labyrinth soll voll vernetzt und von Mauern umgeben sein, die die Fragestellung zur Klärung dieser Punkte bearbeiten.
Dendrobium

Antworten:

10

Python 3, 1599 Bytes

Ich fand das ein lustiges Projekt und sehr interessant (und etwas langwierig). Als ich das sah, erinnerte ich mich an den Sommer, in dem ich ausschließlich einen Algorithmus zur Erzeugung von Labyrinthen geschrieben und verbessert hatte, und musste sofort daran arbeiten.

Nach einer Weile hatte ich einen ersten Entwurf mit einer Länge von ca. 6000 Byte und verbrachte die nächsten Stunden damit, ihn in das folgende Programm umzuwandeln:

import math,random;R=range;L=len;T=sorted;P=print;N=random.randint
def M(I,S):
 I=I.rsplit('\n');s=[0]*(1+L(I[0])*2);G=[s]
 for i in R(L(I)):
  r=[0]
  for x in I[i]:r+=x,0
  G+=[r];s=[0]*(1+L(I[0])*2);G+=[s]
 c=E(G,L(G[0])-2,-2);G[c][L(G[0])-1]=1;e=[c,L(G[0])-2];c=E(G,1,2);G[c][0]=1;G[c][1]=1;s=[c,1]
 while s!=e:
  o=[];Q(G,s,e,-2,0,o,0);Q(G,s,e,0,2,o,1);Q(G,s,e,2,0,o,2);Q(G,s,e,0,-2,o,3);o=T(o,key=lambda x:(x[2],-x[1]))[0][0]
  if o==0:G[s[0]-1][s[1]]=1;s[0]-=2
  elif o==1:G[s[0]][s[1]+1]=1;s[1]+=2
  elif o==2:G[s[0]+1][s[1]]=1;s[0]+=2
  else:G[s[0]][s[1]-1]=1;s[1]-=2
  G[s[0]][s[1]]=1
 s=0
 while not s:
  r=N(1,(L(G)-1)/2)*2-1;c=N(1,(L(G[0])-1)/2)*2-1
  if G[r][c]in[1,2]:
   o=[];F(G,r-2,c,o,0);F(G,r,c+2,o,1);F(G,r+2,c,o,2);F(G,r,c-2,o,3)
   try:
    if o[0]==0:G[r-1][c]=2;G[r-2][c]=2
    elif o[0]==1:G[r][c+1]=2;G[r][c+2]=2
    elif o[0]==2:G[r+1][c]=2;G[r+2][c]=2
    else:G[r][c-1]=2;G[r][c-2]=2
   except:0
  s=1
  for x in G:
   if'.'in x:s=0;break
 *s,='#  '
 if S:s[1]='.'
 for x in G:
  for y in x:P(s[y],end='')
  P()
def Q(G,s,e,x,y,o,a,n=0):
 c=lambda x,y:G[s[0]+x][s[1]+y]is'#'
 try:
  if c(x,y):
   try:n+=c(2*x,2*y)
   except:0
   try:n+=c(x+abs(x)-2,y+abs(y)-2)
   except:0
   try:n+=c(x-abs(x)+2,y-abs(y)+2)
   except:0
   o+=[[a,math.sqrt((s[0]+x-e[0])**2+(s[1]+y-e[1])**2),n]]
 except:0
def F(G,r,c,o,a):
 try:
  if G[r][c] is'.':o+=[a]
 except:0
def E(G,y,z,d='#'):
 c=[]
 for x in R(1,L(G)-1,2):
  n=0
  try:n+=G[x-2][y]==d
  except:0
  try:n+=G[x+2][y]==d
  except:0
  n+=G[x][y+z]==d
  if G[x][y]==d:c+=[[x,n]]
 if L(c)>1:c=T(c,key=lambda x:x[1])
 return c[0][0]

Was ungefähr so ​​unsinnig anzusehen ist, wie ein Ascii-Art-Labyrinth ...

Es ist erwähnenswert, dass, da die Zufallsfunktion erst verwendet wird, nachdem der richtige Pfad gefunden wurde, unabhängig davon, wie oft dieselbe Eingabe erfolgt, die Route vom Anfang bis zum Ende dieselbe ist und während dies bei diesem Programm der Fall ist Arbeiten Sie für die obigen Beispiele, wird es manchmal nicht möglich sein, eine Lösung zu finden, wenn es sich sozusagen selbst in eine Wand stößt.

Wenn Sie die obigen Beispiele ausführen, erhalten Sie Folgendes:

>>> M('''.......
.#####.
.#####.
#######
.#####.
.#####.
.......''',True)
###############
# # #   # #   #
# # # ### # # #
# #...#.....# #
# #.#.#.###.###
#  .#.#.#...# #
###.#.#.#.### #
....#.#.#.#....
# ###.#.#.#.###
# #...#.#.#.  #
# #.###.#.#.# #
# #.....#...# #
### ####### # #
#         # # #
###############
>>> 

Dies:

>>> M('''..................
..................
.......####.......
......##..##......
.....##....##....#
.....#......#...##
.#############.##.
##..############..
#...###########...
#...##########....
#...##########....
#...##########....
#...##########....
....##########....
....##########....
....##########....
..................
..................''',False)
#####################################
# #     #   # # #   # #   # # # # # #
# ### ##### # # # ### # ### # # # # #
#   # # #   #   # # # #   # # #   # #
### # # ### # ### # # # ### # ### # #
# #     #   # #         # # # # # # #
# ### ##### # # ##### ### # # # # # #
# # #   #   #     # #   # # # # # # #
# # # ##### # ##### ### # # # # # # #
# # # #         # # #         #      
# # # # # # ##### # ### # ######### #
# #   # # # #   # # # # # # # # #   #
# # ####### # ### # # ### # # # # # #
#         # #           #   #     # #
### ##### # # ######### ### ### ### #
#     #   # # #   #   #     #   # # #
# ### ### # # # # # # ####### ### # #
#   # #   # # # # # # #   #       # #
# ##### # # # # # # # # # # # ##### #
#   #   # # # # # # # # #   #     # #
# ####### # # # # # # # #############
#   #     # # # # # # #         #   #
# ####### # # # # # # ##### ##### # #
#   #     # # # # # #           # # #
# ### ### # # # # # ######### ### ###
    # #   # # # # #         #   #   #
# ### # # # # # # ######### ##### ###
#   # # # # # # #                 # #
# # # ### # # # ################### #
# # # # # # # #               #     #
# ### # # # # ############# ### ### #
# # # #     #                     # #
# # ##### # # # ##### # # ##### ### #
# # #     # # #     # # #     #   # #
### ##### # ### # # # ##### # ### # #
#         #   # # # #     # #   # # #
#####################################
>>> 

und das:

>>> M('''..................
..................
.......####.......
......##..##......
.....##....##....#
.....#......#...##
.#############.##.
##..############..
#...###########...
#...##########....
#...##########....
#...##########....
#...##########....
....##########....
....##########....
....##########....
..................
..................''',True)
#####################################
#     #     # #   # # # # # # #     #
##### # # ### ### # # # # # # ### # #
# # # # # # # #     # # # # # # # # #
# # # ### # # ##### # # # # # # # ###
#   # #   # # #.......# #     #   # #
### # ### # # #.#####.# # ####### # #
#   # #   # #...#   #...#   # #   # #
### # ### # #.# # ### #.# ### ### # #
# # # # # #...# #   # #...  # #   #..
# # # # # #.# ### #######.### ### #.#
# #     #  .# #   # # #  .    # #...#
# # #######.##### # # ###.##### #.# #
#  .......#.#...........#...# #...# #
###.# ###.#.#.#########.###.# #.### #
#...# #  .#.#.#...#...#.....#...  # #
#.#######.#.#.#.#.#.#.#######.#######
#.    #  .#.#.#.#.#.#.#...#...#     #
#.#######.#.#.#.#.#.#.#.#.#.### #####
#.    #  .#.#.#.#.#.#.#.#...        #
#.#######.#.#.#.#.#.#.#.#############
#.    # #.#.#.#.#.#.#.#.....        #
#.##### #.#.#.#.#.#.#.#####.#########
#.  #    .#.#.#.#.#.#.......  # #   #
#.# # ###.#.#.#.#.#.########### # ###
..# # #  .#.#.#.#.#.........#   # # #
# # #####.#.#.#.#.#########.# ### # #
# # #    .#.#.#.#...........        #
#########.#.#.#.############### #####
#   #    .#.#.#.............# #     #
### # ###.#.#.#############.# ##### #
#     #  ...#...............      # #
##### # # ### # # # # ### # # ##### #
#     # #   # # # # #   # # #   #   #
####### # ### # # # ##### # ####### #
#       # #   # # #     # #       # #
#####################################
>>> 

Verwenden Sie den Befehl, wenn Sie versuchen möchten, dieses Programm selbst auszuführen M(Image, Show solution). Ich würde empfehlen, die dreifachen Anführungszeichen zu verwenden, um das Bild einzugeben, da es sonst viele Back-Slashes oder Newline-Zeichen gibt.

Anonym No Lifer
quelle
1
Genaue Spitzname: p
Fatalize
1
Gute Arbeit! Einige Tipps: Verwenden Sie 0statt pass, l.append(a);l.append(b)-> l+=a,b, l.append(a)-> l+=[a], könnte es sich lohnen, die Zuordnung '#'zu einer Variablen, und def E(G,y,z):\n c=[]->def E(G,y,z,c=[]):
Loovjo
1
Also, if G[r][c]==1 or G[r][c]==2:-> if 0<G[r][c]<3:, s=[0]\n for x in R(L(I[0])*2):s+=[0]-> s=[0]*(1+L(I[0])*2)und (ich glaube, ich habe es nicht getestet) G=[s]-> *G=s.
Loovjo
@ Loovjo Danke für den Rat, der except:0, l+=a,bund s=[0]*(1+L(I[0])*2)wirklich geholfen hat. Aus irgendeinem Grund führt die Zuweisung von c im Funktionsaufruf nicht dazu, dass es bei mehreren Aufrufen zurückgesetzt wird, was bedeutet, dass es nicht mehr funktioniert * G = s hat mir einen Syntaxfehler gegeben. Trotzdem toller Rat.
Anonym No Lifer
1
@AnonymousNoLifer Keine Probleme. Auch wenn es G[r][c]sich um eine Zeichenfolge handeln kann, G[r][c]in[1,2]sollte dies funktionieren.
Loovjo