Advertisement
Guest User

Untitled

a guest
Feb 13th, 2016
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.11 KB | None | 0 0
  1. import random
  2.  
  3. def Creator(rows=25,columns=25):
  4.     """Generator macierzy rows x columns "#" """
  5.     plane = [['#']*columns for i in range(rows)]            #generacja macierzy 25x25 "#"
  6.     plane[0][int(columns/2)] = 'F'                          #ustawienie mety
  7.     plane[rows-1][int(columns/2)] = 'S'                     #ustawienie startu
  8.     return plane
  9.  
  10. def Input(file = 'lab.txt'):
  11.     plane = []
  12.     file = open(file,'r')
  13.     a = file.readline()
  14.     steps = 0
  15.     while len(a) != 0:
  16.         plane.append([])
  17.         for i in range(len(a)-1):
  18.             plane[steps].append(a[i])
  19.         a = file.readline()
  20.         steps += 1
  21.     return plane
  22.  
  23. def Copy(plane):
  24.     """Funkcja kopiująca macierze"""
  25.     output = []
  26.     for x in range(len(plane)):
  27.         output.append([])
  28.         for y in range(len(plane)):
  29.             output[x].append(plane[x][y])
  30.     return output                  
  31.  
  32. def Viewer(plane):
  33.     """Druk macierzy labiryntu w zwartej formie"""
  34.     for i in plane:
  35.         print(''.join(i))
  36.     print("\n")
  37.  
  38. def Obstacle(plane,lvl):
  39.     """Wstawienie do labiryntu #lvl przeszkód losowo na parzystych polach.
  40.    Wartość lvl najlepiej na poziomie rzędu macierzy."""
  41.     p_range = len(plane)-1
  42.     for i in range(lvl):
  43.         row = random.randint(0,int(p_range/2))*2            #parzyste wartości row i col
  44.         col = random.randint(0,int(p_range/2))*2
  45.         if not ((plane[row][col] == "S") or (plane[row][col] == "F")):
  46.             plane[row][col] = 'X'
  47.     return plane
  48.    
  49. def Walker(plane):
  50.     """Tyczenie labiryntu poprzez losową probę dojścia od (S)tartu do (F)inishu.
  51.    Skok co dwa pola, żeby nie tworzyć pustych przestrzeni."""
  52.     print("###WALKER###")
  53.     p_range = len(plane)-1
  54.     current = [p_range,int(p_range/2)]              #aktualna pozycja walkera
  55.     steps = 0                                       #licznik pętli
  56.     while plane[current[0]][current[1]] != "F":     #pętla dopóki nie znajdzie finisha
  57.         temp = current[:]                           #wartość tymczasowa pozycji żeby sprawdzić prawilność następnego ruchu
  58.         direct = random.randint(0,3)                #losowy kierunek ruchu 0-góra, 1-prawo, 2-dół, 3-lewo
  59.         A = [[-2,0],[0,2],[2,0],[0,-2]]             #wektor przemieszczeń, indeks odpowiada kierunkowi
  60.         temp[0] += A[direct][0]
  61.         temp[1] += A[direct][1]
  62.         if not ((temp[0] < 0) or (temp[1] < 0)) or ((temp[0] > p_range) or (temp[1]> p_range)):         #sprawdzenie czy indeksy nie są ujemne lub poza obszarem    
  63.             try:
  64.                 fwd_1 = plane[int((temp[0]+current[0])/2)][int((temp[1]+current[1])/2)]                 #sprawdzenie pierwszego pola na kierunku ruchu
  65.                 fwd_2 = plane[temp[0]][temp[1]]                                                         #sprawdzenie drugiego pola na kierunku ruchu
  66.             except IndexError:                                                                          #nie powinno wystąpić, zbędny test (chyba)
  67.                 pass
  68.             else:
  69.                 if ((fwd_1 == "#") or (fwd_1 == " ")) and ((fwd_2 == "#") or (fwd_2 == " ")):           #Jeśli pola fwd_1 i fwd_2 są ok:
  70.                     plane[temp[0]][temp[1]] = ' '                                                       #zastąp je pustymi polami,
  71.                     plane[int((temp[0]+current[0])/2)][int((temp[1]+current[1])/2)] = " "
  72.                     current = temp[:]                                                                   #zaktualizuj pozycję
  73.                 elif fwd_2 == "F":                                                                      #Jeśli meta
  74.                     plane[int((temp[0]+current[0])/2)][int((temp[1]+current[1])/2)] = " "
  75.                     current = temp[:]
  76.                     break
  77.         steps += 1
  78.     print(steps)                                                                                        #wypisz liczbę pętli
  79.     return plane
  80.  
  81. def XClearer(plane):
  82.     """Funkcja czyszcząca macierz labiryntu z "X"ów"""
  83.     for i in range(len(plane)):
  84.         for j in range(len(plane)):
  85.             if plane[i][j] == "X":
  86.                 plane[i][j] = "#"
  87.     return plane
  88.  
  89. def Nose(x,y,plane):
  90.     """Funkcja analizuje sąsiednie pola i określa ich zawartość.
  91.    Zwraca True kiedy można wejść na dane pole, "o" kiedy już się było na danym polu, False kiedy nie można wejść.
  92.    Zwraca listę, w której indeksy odpowiadają kierunkom 0-góra, 1-prawo, 2-dół, 3-lewo"""
  93.     nose = [0]*4
  94.     A = [[-1,0],[0,1],[1,0],[0,-1]]                                     #wektor kierunków zgodnie z konwencją
  95.     for i in A:
  96.         try:
  97.             temp = plane[x+i[0]][y+i[1]]                                #dla każdego kierunku test
  98.             if (x+i[0] >= 0) and (y+i[1] >= 0):                         #indexerror nie łapie ujemnych
  99.                 if (temp == " ") or (temp == "F"):
  100.                     nose[A.index(i)] = True
  101.                 elif temp == "o":
  102.                     nose[A.index(i)] = "o"
  103.                 else:
  104.                     nose[A.index(i)] = False
  105.             else:
  106.                 nose[A.index(i)] = False
  107.         except IndexError:
  108.             nose[A.index(i)] = False
  109.     return nose
  110.  
  111. def Solver(plane):
  112.     """Funkcja losowo znajdująca drogę w labiryncie przy pomocji funkcji Nose()"""
  113.     print("###SOLVER###")
  114.     start = []                              
  115.     finish = []
  116.     A = [[-1,0],[0,1],[1,0],[0,-1]]                                     #wektor kierunkowy zgodnie z konwencją
  117.     for i in range(len(plane)):
  118.         for j in range(len(plane)):
  119.             if plane[i][j] == "S":                                      #zlokalizowanie punktu startu i mety
  120.                 start = [i,j]
  121.             if plane[i][j] == "F":
  122.                 finish = [i,j]
  123.     current = start[:]                                                  #ustawienie się na starcie
  124.     steps = 0
  125.     while current != finish:
  126.         temp = Nose(current[0],current[1],plane)                        #odpalamy nos
  127.         ways = temp.count(True)                                         #ile jest możliwych dróg gdzie nie byliśmy
  128.         plane[current[0]][current[1]] = "o"                             #zaznaczenie, że już się było na tym polu
  129.         if ways == 1:                                                   #zawsze najpierw idzie tam gdzie nie był,
  130.             direction = temp.index(True)                                
  131.         elif (ways == 2) or (ways == 3):                                
  132.             junction = [i for i in range(len(temp)) if temp[i] == True] #na skrzyżowaniach wybiera najpierw puste drogi
  133.             direction = random.choice(junction)
  134.         else:
  135.             junction = [i for i in range(len(temp)) if temp[i] == "o"]  #jak już trzeba to wraca po śladach
  136.             direction = random.choice(junction)
  137.         current[0] += A[direction][0]
  138.         current[1] += A[direction][1]
  139.         steps += 1
  140.     plane[start[0]][start[1]] = "S"                                     #ponowne wrzucenie punktów (S) i (F), które Solver zastępuje "o"
  141.     plane[finish[0]][finish[1]] = "F"
  142.     print(steps)
  143.     return plane
  144.  
  145. def ReSolve(plane,init_steps = 10**6):
  146.     steps = 0                                                   #liczba kroków (literek "o") w rozwiązanym labiryncie
  147.     #Viewer(plane)
  148.     for x in range(len(plane)):                                 #tworzenie nowego, zmodyfikowanego labiryntu
  149.         for y in range(len(plane)):
  150.             if plane[x][y] == "o":
  151.                 steps += 1
  152.                 plane[x][y] = " "
  153.             elif (plane[x][y] == " ") or (plane[x][y] == "#"):
  154.                 plane[x][y] = "#"
  155.     Solver(plane)                                               #rozwiązanie zmodyfikowanego labiryntu
  156.     #Viewer(plane)
  157.     if init_steps <= steps:                                     #jeśli nie osiągnięto poprawy kroków zakończenie funkcji
  158.         return plane
  159.     else:
  160.         ReSolve(plane,init_steps = steps)   #rekurencja"""
  161.  
  162. def SolutionCopy(plane,solvedplane):
  163.     """Funkcja nanosząca rozwiązanie na wyjściowy labirynt."""
  164.     for x in range(len(solvedplane)):
  165.         for y in range(len(solvedplane)):
  166.             if solvedplane[x][y] == "o":
  167.                 plane[x][y] = "o"
  168.     return plane
  169.  
  170. def main():
  171.     op = input("Witaj! Chcesz żebym rozwiązał Twój labirynt (1), czy wygenerował losowy (2)?")
  172.     if op == 1:
  173.         plane = Input()
  174.     else:
  175.         rows = int(input("Podaj wysokość labiryntu (liczba nieparzysta)"))
  176.         cols = int(input("Podaj szerokość labiryntu (Liczba nieparzysta)"))
  177.         if rows%2 == 0:
  178.             rows += 1
  179.         if cols%2 == 0:
  180.             cols += 1
  181.         plane = Creator(rows,cols)
  182.         Obstacle(plane, rows)
  183.         Walker(plane)
  184.         XClearer(plane)
  185.     Lab = Copy(plane)
  186.     print("###Oto wygenerowany labirynt:\n")
  187.     Viewer(Lab)
  188.     Solver(Lab)
  189.     for i in range(3):
  190.         ReSolve(Lab)
  191.     print("###A oto rozwiązanie. Nienajlepsze, ale też nienajtańsze!")
  192.     SolutionCopy(plane,Lab)
  193.     Viewer(plane)
  194.  
  195. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement