Generazione di labirinti


20

Sfida

Scrivi un programma / funzione che accetta una "immagine" e genera un labirinto di immagini formato da quella immagine.

Ingresso

Il tuo programma dovrebbe accettare due argomenti:

  • Io, l'immagine per formare il labirinto da
  • S, un valore booleano che specifica se visualizzare o meno la soluzione nel labirinto

Mi viene dato nella forma seguente:

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

dove #sono le celle da includere nel percorso della soluzione e .sono le celle da escludere. Puoi scambiare .', #' e newline con qualsiasi personaggio di tua scelta purché differiscano l'uno dall'altro. In alternativa, è possibile accettare una bitmap effettiva dell'immagine di input.

Produzione

Il labirinto risultante dovrebbe essere nella seguente forma:

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

dove #denotano muri, .denotano porzioni del percorso che fanno parte della soluzione e gli spazi sono percorsi esclusi dalla soluzione. L .'può essere sostituito da spazi se S è falso. Ancora una volta, i personaggi possono essere scambiati con altri personaggi di tua scelta o potresti generare una bitmap effettiva del labirinto con la soluzione evidenziata.

dettagli aggiuntivi

  • I percorsi devono essere larghi di una cella (non può essere il pool gigante di spazio vuoto il percorso)
  • Il labirinto non deve contenere anelli
  • Il labirinto deve essere completamente collegato (tutte le celle devono essere raggiungibili dall'ingresso / uscita)
  • Il labirinto deve essere circondato da muri (a meno che non sia un ingresso / uscita)
  • Il percorso della soluzione non deve includere vicoli ciechi
  • Devono esserci esattamente 1 entrata e 1 uscita per il labirinto
  • L'ingresso e l'uscita devono essere allineati al bordo della griglia e adiacenti a una cella inclusa nel percorso della soluzione
  • Puoi scegliere dove posizionare l'ingresso e l'uscita
  • Si può presumere che dall'immagine di input fornita possa essere formato un percorso valido

(Aggiunto per chiarimenti) Il diagramma seguente mostra come il percorso della soluzione è correlato all'immagine di input:

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

Casi test

Esempio di annaffiatoio da Wikipedia :

Ingresso:

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

Uscita (S = falso):

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

Uscita (S = vero):

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

Esempio di bitmap (stesso labirinto di cui sopra):

Input: Inserisci bitmapOutput (S = false): Soluzione bitmap di output non evidenziataOutput (S = true):Soluzione bitmap di output evidenziata


4
Potrei essere solo io, ma non vedo l'immagine di input nel labirinto di output.
Mike Bufardeci,

@ mike-bufardeci Aggiunto un diagramma che mostra l'immagine di input nel labirinto di output. Spero possa aiutare!
Dendrobium,

2
Non sembra esserci una regola che richiede che il labirinto sia collegato. Questa sarebbe una soluzione valida? Inoltre, non sembra esserci una regola secondo cui la griglia deve essere circondata da muri (a meno che ogni non muro sia considerato un ingresso o un'uscita). Questa sarebbe una soluzione valida?
Martin Ender,

1
Inoltre, aggiungi altri casi di test.
flawr

@ MartinBüttner Il labirinto dovrebbe essere completamente collegato e circondato da muri, modificato la domanda che chiarisce questi punti.
Dendrobium,

Risposte:


10

Python 3, 1599 byte

Ho trovato questo un progetto divertente e molto interessante (e piuttosto lungo). Quando l'ho visto, mi è venuta in mente l'estate in cui ho trascorso esclusivamente la scrittura e il miglioramento di un algoritmo di generazione del labirinto e ho immediatamente lavorato su questo.

Dopo un po ', ho avuto una bozza iniziale di circa 6000 byte e ho trascorso le ore successive a condensarla nel seguente programma:

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]

Che è quasi non sensato da guardare come un labirinto di arte ascii è ...

Vale la pena notare che, poiché la funzione casuale non viene utilizzata fino a quando non viene trovato il percorso corretto, indipendentemente da quante volte viene fornito lo stesso input, il percorso dall'inizio alla fine sarà lo stesso e, mentre questo programma lo fa lavorare per gli esempi di cui sopra, a volte non sarà in grado di trovare una soluzione se "si guida da solo in un muro" per così dire.

Quando si eseguono gli esempi precedenti, si ottiene questo:

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

Questo:

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

e questo:

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

Per chiunque desideri provare a eseguire questo programma da solo, usa il comando M(Image, Show solution). Consiglierei di usare le virgolette triple per inserire l'immagine poiché altrimenti ci saranno molte barre o caratteri di nuova riga coinvolti.


1
Soprannome preciso: p
Fatalizza il

1
Bel lavoro! Alcuni consigli: Usa 0invece di pass, l.append(a);l.append(b)-> l+=a,b, l.append(a)-> l+=[a], potrebbe valere la pena assegnarlo '#'a una variabile e def E(G,y,z):\n c=[]->def E(G,y,z,c=[]):
Loovjo

1
Inoltre, 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)e (penso, non l'ho ancora testato) G=[s]-> *G=s.
Loovjo,

@Loovjo Grazie per il consiglio, il except:0, l+=a,be s=[0]*(1+L(I[0])*2)davvero aiutato. Sfortunatamente, per qualsiasi motivo, l'assegnazione di c nella chiamata di funzione non la reimposta su più chiamate, il che significa che ha smesso di funzionare, G [r] [c] può essere una stringa, quindi non posso usare <o> su di essa e il * G = s mi ha dato un errore di sintassi. Comunque, un ottimo consiglio.
Anonymous No Lifer,

1
@AnonymousNoLifer Nessun problema. Inoltre, se G[r][c]può essere una stringa, G[r][c]in[1,2]dovrebbe funzionare.
Loovjo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.