Advertisement
Guest User

Untitled

a guest
May 29th, 2017
546
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.87 KB | None | 0 0
  1. # Python versione: 3.***
  2. # Laura GIROMETTI
  3. # 0000791806
  4. # Iscritto: 1 anno di Matematica
  5. # email: laura.girometti@studio.unibo.it
  6. import random
  7. def stack():
  8. return []
  9. def push(a,p):
  10. p.append(a)
  11. return p
  12. def pop(p):
  13. if not(is_empty(p)):
  14. a=p[-1]
  15. del p[-1]
  16. return a
  17. return None
  18. def is_empty(p):
  19. return len(p)==0
  20. def top(p):
  21. if not(is_empty(p)):
  22. return p[-1]
  23. return None
  24. def importafile(file):
  25. try: #provo ad aprire il file
  26. F=open(file,'r')
  27. except:
  28. print('Importazione non riuscita')
  29. return
  30. linee=[]
  31. for line in F: #elimino il ritorno a carrello
  32. linee.append(line.strip('\n'))
  33. maze=dict()
  34. for i in range(1,len(linee),2): #costruisco un diz. che ad ogni cella fa corrispondere un diz. con presenza di muri e stato
  35. for j in range(1,len(linee[i]),2):
  36. maze[i-(i+1)//2,j-(j+1)//2]={'N':linee[i-1][j]=='*','E':linee[i][j+1]=='*','S':linee[i+1][j]=='*','O':linee[i][j-1]=='*','Stato':''}
  37. if not(benformato(maze)):
  38. print('Il labirinto non è ben formato')
  39. return None
  40. return maze
  41. def benformato(L):
  42. if len(L)==0:
  43. return False
  44. r,c=righe_colonne(L)
  45. #controllo che L sia una matrice r*c
  46. if len(L)!=r*c:
  47. return False
  48. #controllo che siano presenti tutte le celle
  49. for i in range(r):
  50. for j in range(c):
  51. if (i,j) not in L:
  52. return False
  53. #controllo che siano definiti i muri e lo stato della cella
  54. for key in L:
  55. if len(L[key])!=5 or type(L[key]['Stato'])!=str:
  56. return False
  57. for p in 'NSEO':
  58. if type(L[key][p])!= bool:
  59. return False
  60. #controllo la coerenza dei muri tra celle adiacenti
  61. for i in range(1,r):
  62. for j in range(c-1):
  63. if not(L[i,j]['E']==L[i,j+1]['O']): #controllo muri orizzontali
  64. return False
  65. if not(L[i,j]['N']==L[i-1,j]['S']): #controllo muri verticali
  66. return False
  67. for i in range(1,r-1): #controllo muri verticali ultima colonna
  68. if not(L[i,j]['N']==L[i-1,j]['S']):
  69. return False
  70. return True
  71. def righe_colonne(L): #restituisce una tupla con il numero di righe e colonne
  72. if L=={}:
  73. return 0,0
  74. else:
  75. r,c=max(L.keys())
  76. return r+1,c+1
  77. def muri(L,c): #se possibile,restituisce un dizionario con la presenza/assenza dei muri
  78. if c not in L:
  79. print('La cella non è presente nel labirinto')
  80. return dict()
  81. return dict(zip('NESO',(L[c]['N'],L[c]['E'],L[c]['S'],L[c]['O'])))
  82. def uscite(L): #restituisce una lista con le uscite
  83. r,c=righe_colonne(L)
  84. l_uscite=[]
  85. for j in range(c):
  86. if not(L[0,j]['N']): #aggiungo le uscite nord
  87. l_uscite.append((0,j))
  88. if not(L[r-1,j]['S']): #aggiungo le uscite sud
  89. l_uscite.append((r-1,j))
  90. for i in range(r):
  91. if not(L[i,0]['O']) and (i,0) not in l_uscite: #aggiungo le uscite ovest
  92. l_uscite.append((i,0))
  93. if not(L[i,c-1]['E']) and (i,c-1) not in l_uscite: #aggiungo le uscite est
  94. l_uscite.append((i,c-1))
  95. return l_uscite
  96. def get_stato(L,c): #restituisce, se possibile, lo stato
  97. if c not in L:
  98. print('Cella non presente')
  99. return
  100. if type(L[c]['Stato'])==str:
  101. return L[c]['Stato']
  102. else:
  103. print('La cella non ha stato')
  104. return
  105. def set_stato(L,c,s): #modifica,se possibile lo stato
  106. if c not in L:
  107. print('Cella non presente')
  108. return
  109. L[c]['Stato']=s
  110. def stampa(L):
  111. if L=={}:
  112. print('Il labirinto è vuoto')
  113. return
  114. k=risolvi_alla_cieca(L,(0,0))
  115. r,c=righe_colonne(L)
  116. for i in range(r):
  117. for j in range(c): #stampo la riga con gli eventuali muri a nord
  118. print('+',end='')
  119. if L[(i,j)]['N']:
  120. print('---',end='')
  121. else:
  122. print(' ',end='')
  123. print('+')
  124. for j in range(c): #stampo la riga con gli eventuali muri a ovest
  125. if L[(i,j)]['O']:
  126. print('|',end='')
  127. else:
  128. print(' ',end='')
  129. if (i,j) in k: #stampo P sulle celle percorso da (0,0) all'uscita
  130. print(' P ',end='')
  131. else:
  132. print(' ',end='')
  133. if L[(i,c-1)]['E']: #stampo l'eventuale muro a est dell'ultima colonna
  134. print('|')
  135. else:
  136. print()
  137. for j in range(c): #stampo l'ultima riga mancante
  138. print('+',end='')
  139. if L[(r-1,j)]['S']:
  140. print('---',end='')
  141. else:
  142. print(' ',end='')
  143. print('+')
  144. def collegate(L,c1,c2): #verifica che c1 e c2 siano collegate
  145. if c1 not in L or c2 not in L:
  146. print('Celle non presenti')
  147. return False
  148. if c2[0]==c1[0]:
  149. if c1[1]==c2[1]-1: #controllo adiacenza orizzontale
  150. return not(L[c1]['E'])
  151. if c1[1]==c2[1]+1:
  152. return not(L[c1]['O'])
  153. if c2[1]==c1[1]:
  154. if c1[0]==c2[0]-1: #controllo adiacenza verticale
  155. return not(L[c1]['S'])
  156. if c1[0]==c2[0]+1:
  157. return not(L[c1]['N'])
  158. print('Celle non adiacenti')
  159. return False
  160. def adiacente(L): #restituisce un dizionario con le celle adiacenti ad ogni cella
  161. adiacenti=dict()
  162. for i,j in L:
  163. if not(L[i,j]['N']) and (i-1,j) in L: #se possibile,controlla l'adiacenza a nord
  164. adiacenti[i,j]=[(i-1,j)]
  165. if not(L[i,j]['E']) and (i,j+1) in L: #se possibile controlla l'adiacenza a est
  166. adiacenti[i,j]=adiacenti.get((i,j),[]) + [(i,j+1)]
  167. if not(L[i,j]['S']) and (i+1,j) in L: #se possibile, controlla l'adiacenza a sud
  168. adiacenti[i,j]=adiacenti.get((i,j),[])+[(i+1,j)]
  169. if not(L[i,j]['O']) and (i,j-1) in L: #se possibile, controlla l'adiacenza a ovest
  170. adiacenti[i,j]=adiacenti.get((i,j),[])+[(i,j-1)]
  171. if (i,j) not in adiacenti: #non ci sono celle adiacenti
  172. adiacenti[i,j]=[]
  173. return adiacenti
  174.  
  175. def perfetto(L): #verifica che il labirinto sia connesso e non contenga cicli
  176. if L=={}:
  177. return False
  178. S=push((0,0),stack()) #mettiamo sulla pila la prima cella
  179. adiacenti=adiacente(L)
  180. while not(is_empty(S)):
  181. x=pop(S)
  182. if L[x]['Stato']!='Visitato': #visita la cella x
  183. L[x]['Stato']='Visitato'
  184. for w in adiacenti[x]: #mette le celle adiacenti non visitate sulla pila
  185. if L[w]['Stato']!='Visitato':
  186. push(w,S)
  187. else: #una cella già visitata è sulla pila(c'è un ciclo)
  188. return False
  189. for k in L: #verifico che tutte le celle siano state visitate(è connesso)
  190. if L[k]['Stato']!='Visitato':
  191. return False
  192. return True
  193.  
  194. def risolvi_alla_cieca(L,partenza): #restituisce il percorso dalla partenza all'uscita
  195. l_uscite=uscite(L) #come lista di celle
  196. adiacenti=adiacente(L)
  197. percorso=[]
  198. S=stack()
  199. if partenza not in L:
  200. print('La cella non è presente')
  201. return
  202. push(partenza,S) #metto la partenza sulla pila
  203. while not(is_empty(S)):
  204. x=pop(S)
  205. if get_stato(L,x)!='Visitato': #visito la cella x
  206. set_stato(L,x,'Visitato')
  207. percorso.append(x) #la metto nel percorso
  208. if x in l_uscite: #ho trovato l'uscita
  209. i=1
  210. while i<len(percorso): #tolgo le celle non adiacenti nel percorso
  211. while percorso[i-1] not in adiacenti[percorso[i]]:
  212. del percorso[i-1]
  213. i=i-1
  214. i+=1
  215. return percorso
  216. for cella in adiacenti[x]: #metto sulla pila le celle adiacenti non visitate
  217. if L[cella]['Stato']!='Visitato':
  218. push(cella,S)
  219. #da partenza non si raggiunge l'uscita
  220. return []
  221.  
  222. def aggiungi_uscita(L): #aggiunge un'uscita, se possibile
  223. r,c=righe_colonne(L)
  224. celle_bordo=[]
  225. l_uscite=uscite(L)
  226. for j in range(c):
  227. if L[0,j]['N'] and (0,j) not in l_uscite: #aggiungo le celle del bordo con muro a nord
  228. celle_bordo.append([(0,j),'N'])
  229. if L[r-1,j]['S'] and (r-1,j) not in l_uscite: #aggiungo le celle del bordo con muro a sud
  230. celle_bordo.append([(r-1,j),'S'])
  231. for i in range(r):
  232. if L[i,0]['O'] and (i,0) not in l_uscite: #aggiungo le celle del bordo con muro a ovest
  233. celle_bordo.append([(i,0),'O'])
  234. if L[i,c-1]['E'] and (i,c-1) not in l_uscite: #aggiungo le celle del bordo con muro a est
  235. celle_bordo.append([(i,c-1),'E'])
  236. #scelgo la cella e il muro da abbattere
  237. if celle_bordo!=[]:
  238. scelta=random.choice(celle_bordo)
  239. L[scelta[0]][scelta[1]]=False
  240. else:
  241. print('Non è possibile aggiungere uscite')
  242. def trova_percorso(L,c1,c2):
  243. adiacenti=adiacente(L)
  244. percorso=[]
  245. S=stack()
  246. if c1 not in L or c2 not in L:
  247. print('Una delle celle non è presente')
  248. return
  249. push(c1,S) #metto la partenza sulla pila
  250. while not(is_empty(S)):
  251. x=pop(S)
  252. if get_stato(L,x)!='Visitato': #visito la cella x
  253. set_stato(L,x,'Visitato')
  254. percorso.append(x) #la metto nel percorso
  255. if x==c2: #ho trovato l'uscita
  256. i=1
  257. while i<len(percorso): #tolgo le celle non adiacenti nel percorso
  258. while percorso[i-1] not in adiacenti[percorso[i]]:
  259. del percorso[i-1]
  260. i=i-1
  261. i+=1
  262. return percorso
  263. for cella in adiacenti[x]: #metto sulla pila le celle adiacenti non visitate
  264. if get_stato(L,cella)!='Visitato':
  265. push(cella,S)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement