BuildFun और SolveFun
खैर, इसमें काफी समय लगा और मुझे पूरी तरह से यकीन नहीं है कि सॉल्वर धोखा दे रहा है या नहीं। जबकि इसकी हर समय पूरी भूलभुलैया तक पहुँच होती है, यह केवल उस कक्ष को देखता है, जिसके चारों ओर की दीवारें हैं, और यदि उनके बीच कोई दीवार नहीं है, तो इससे सटे हुए कक्ष। अगर यह नियमों के खिलाफ है तो कृपया मुझे बताएं और मैं इसे बदलने की कोशिश करूंगा।
वैसे भी, यहाँ कोड है:
#Architect function
def BuildFun(size,seed):
#Initialise grid and ensure inputs are valid
if size<15:size=15
if size>50:size=50
if seed<4:seed=4
if seed>size:seed=size
grid=[]
for x in range(size):
gridbuilder=[]
for y in range(size):gridbuilder.append([0,1,1])
grid.append(gridbuilder)
coords=[0,0]
grid[0][0][0]=1
#Generate maze
while 1:
#Choose a preffered direction based on location in grid and seed
pref=((((coords[0]+coords[1]+2)*int(size/2))%seed)+(seed%(abs(coords[0]-coords[1])+1)))%4
#Find legal moves
opt=[]
if coords[0]>0:opt+=[0] if grid[coords[0]-1][coords[1]][0]==0 else []
if coords[1]<size-1:opt+=[1] if grid[coords[0]][coords[1]+1][0]==0 else []
if coords[0]<size-1:opt+=[2] if grid[coords[0]+1][coords[1]][0]==0 else []
if coords[1]>0:opt+=[3] if grid[coords[0]][coords[1]-1][0]==0 else []
#There are legal moves
if len(opt)>0:
moved=False
while not moved:
#Try to move in preffered direction
if pref in opt:
if pref==0:
coords[0]-=1
grid[coords[0]][coords[1]][0]=1
grid[coords[0]][coords[1]][2]=0
elif pref==1:
grid[coords[0]][coords[1]][1]=0
coords[1]+=1
grid[coords[0]][coords[1]][0]=1
elif pref==2:
grid[coords[0]][coords[1]][2]=0
coords[0]+=1
grid[coords[0]][coords[1]][0]=1
else:
coords[1]-=1
grid[coords[0]][coords[1]][0]=1
grid[coords[0]][coords[1]][1]=0
moved=True
#Change preferred direction if unable to move
else:
pref+=1
if pref==4:pref=0
#There aren't legal moves
else:
moved=False
#Return to a previously visited location
if not moved:
try:
if grid[coords[0]-1][coords[1]][0]==1 and grid[coords[0]-1][coords[1]][2]==0:
grid[coords[0]][coords[1]][0]=2
coords[0]-=1
moved=True
except:pass
if not moved:
try:
if grid[coords[0]][coords[1]+1][0]==1 and grid[coords[0]][coords[1]][1]==0:
grid[coords[0]][coords[1]][0]=2
coords[1]+=1
moved=True
except:pass
if not moved:
try:
if grid[coords[0]+1][coords[1]][0]==1 and grid[coords[0]][coords[1]][2]==0:
grid[coords[0]][coords[1]][0]=2
coords[0]+=1
moved=True
except:pass
if not moved:
try:
if grid[coords[0]][coords[1]-1][0]==1 and grid[coords[0]][coords[1]-1][1]==0:
grid[coords[0]][coords[1]][0]=2
coords[1]-=1
moved=True
except:pass
#Check if finished
fin=True
for x in grid:
for y in x:
if y[0]==0:
fin=False
break
if not fin:break
if fin:break
for x in grid:
for y in x:
y[0]=0
#Find positions for start and finish such that the route between them is as long as possible
lsf=[[0,0],[0,0],0]
for y in range(size):
for x in range(size):
#Check all start positions
lengths=[]
coords=[[y,x,4,0]]
while len(coords)>0:
#Spread tracers out from start to the rest of the maze
for coord in coords:
opt=[]
if coord[0]>0:opt+=[0] if grid[coord[0]-1][coord[1]][2]==0 else []
opt+=[1] if grid[coord[0]][coord[1]][1]==0 else []
opt+=[2] if grid[coord[0]][coord[1]][2]==0 else []
if coord[1]>0:opt+=[3] if grid[coord[0]][coord[1]-1][1]==0 else []
try:opt.remove(coord[2])
except:pass
#Dead end, tracer dies and possible end point is recorded along with length
if len(opt)==0:
lengths.append([coord[0],coord[1],coord[3]])
coords.remove(coord)
else:
#Create more tracers at branch points
while len(opt)>1:
if opt[0]==0:coords.append([coord[0]-1,coord[1],2,coord[3]+1])
elif opt[0]==1:coords.append([coord[0],coord[1]+1,3,coord[3]+1])
elif opt[0]==2:coords.append([coord[0]+1,coord[1],0,coord[3]+1])
else:coords.append([coord[0],coord[1]-1,1,coord[3]+1])
del opt[0]
if opt[0]==0:
coord[0]-=1
coord[2]=2
coord[3]+=1
elif opt[0]==1:
coord[1]+=1
coord[2]=3
coord[3]+=1
elif opt[0]==2:
coord[0]+=1
coord[2]=0
coord[3]+=1
else:
coord[1]-=1
coord[2]=1
coord[3]+=1
#Find furthest distance and, if it's longer than the previous one, the start/end positions get updated
lengths=sorted(lengths,key=lambda x:x[2],reverse=True)
if lengths[0][2]>lsf[2]:lsf=[[y,x],[lengths[0][0],lengths[0][1]],lengths[0][2]]
#Find number of walls and output maze
w=draw(grid,size,lsf[0],lsf[1])
#Output maze information
print('Start = '+str(lsf[0]))
print('End = '+str(lsf[1]))
print('Distance = '+str(lsf[2]))
print('Walls = '+str(w))
print('Score = '+str(float(lsf[2])/float(w))[:5])
#Convert array grid to binary strings horizontal and vertical
horizontal=vertical=''
for y in range(size):
for x in range(size-1):vertical+=str(grid[y][x][1])
for y in range(size-1):
for x in range(size):horizontal+=str(grid[y][x][2])
#Save maze information to text file for use with SolveFun
save=open('Maze.txt','w')
save.write(str(size)+'\n'+str(lsf[0][0])+' '+str(lsf[0][1])+'\n'+str(lsf[1][0])+' '+str(lsf[1][1])+'\n'+horizontal+'\n'+vertical)
save.close()
#Solver function
def SolveFun():
try:
#Get maze information from text file
save=open('Maze.txt','r')
data=save.readlines()
save.close()
size=int(data[0])
s=data[1].rsplit(' ')
start=[int(s[0]),int(s[1])]
e=data[2].rsplit(' ')
end=[int(e[0]),int(e[1])]
horizontal=data[3].rstrip('\n')
vertical=data[4]
#Build maze from information
grid=[]
for y in range(size):
grid.append([])
for x in range(size):
grid[y].append([0,1,1])
for y in range(size):
for x in range(size-1):
grid[y][x][1]=int(vertical[y*(size-1)+x])
for y in range(size-1):
for x in range(size):
grid[y][x][2]=int(horizontal[y*size+x])
path=''
cpath=''
bs=0
pos=start[:]
grid[pos[0]][pos[1]][0]=1
while pos!=end:
#Want to move in direction of finish
if end[0]<pos[0] and pos[0]-end[0]>=abs(pos[1]-end[1]):pref=0
elif end[1]>pos[1] and end[1]-pos[1]>=abs(pos[0]-end[0]):pref=1
elif end[0]>pos[0] and end[0]-pos[0]>=abs(pos[1]-end[1]):pref=2
else:pref=3
#Find legal moves
opt=[]
if pos[0]>0:
if grid[pos[0]-1][pos[1]][2]==0:opt+=[0]if grid[pos[0]-1][pos[1]][0]==0 else[]
if pos[1]>0:
if grid[pos[0]][pos[1]-1][1]==0:opt+=[3]if grid[pos[0]][pos[1]-1][0]==0 else[]
if grid[pos[0]][pos[1]][2]==0:opt+=[2]if grid[pos[0]+1][pos[1]][0]==0 else[]
if grid[pos[0]][pos[1]][1]==0:opt+=[1]if grid[pos[0]][pos[1]+1][0]==0 else[]
if len(opt)>0:
moved=False
while not moved:
#Try to move in preferred direction
if pref in opt:
if pref==0:
pos[0]-=1
path+='0'
cpath+='0'
elif pref==1:
pos[1]+=1
path+='1'
cpath+='1'
elif pref==2:
pos[0]+=1
path+='2'
cpath+='2'
else:
pos[1]-=1
path+='3'
cpath+='3'
grid[pos[0]][pos[1]][0]=1
moved=True
#Change preferred direction by 1
else:
pref=(pref+1)%4
#No legal moves, backtrack
else:
bs+=1
grid[pos[0]][pos[1]][0]=2
if int(cpath[len(cpath)-1])==0:
pos[0]+=1
path+='2'
elif int(cpath[len(cpath)-1])==1:
pos[1]-=1
path+='3'
elif int(cpath[len(cpath)-1])==2:
pos[0]-=1
path+='0'
else:
pos[1]+=1
path+='1'
cpath=cpath[:len(cpath)-1]
#Output maze with solution as well as total steps and wasted steps
draw(grid,size,start,end)
print('\nPath taken:')
print(str(len(path))+' steps')
print(str(bs)+' backsteps')
print(str(bs*2)+' wasted steps')
except:print('Could not find maze')
def draw(grid,size,start,end):
#Build output in string d
d=' '
for x in range(size):d+=' '+str(x)[0]
d+='\n '
for x in range(size):d+=' ' if len(str(x))==1 else ' '+str(x)[1]
d+='\n '+'_'*(size*2-1)
w=0
for y in range(size):
d+='\n'+str(y)+' |' if len(str(y))==1 else '\n'+str(y)+' |'
for x in range(size):
if grid[y][x][2]:
if start==[y,x]:d+=UL.S+'S'+UL.E
elif end==[y,x]:d+=UL.S+'F'+UL.E
elif grid[y][x][0]==1:d+=UL.S+'*'+UL.E
else:d+='_'
w+=1
else:
if start==[y,x]:d+='S'
elif end==[y,x]:d+='F'
elif grid[y][x][0]==1:d+='*'
else:d+=' '
if grid[y][x][1]:
d+='|'
w+=1
else:d+=' '
#Output maze and return number of walls
print(d)
w-=size*2
return w
#Underlines text
class UL:
S = '\033[4m'
E = '\033[0m'
मुझे पता है कि यह हास्यास्पद रूप से लंबा है और विशेष रूप से पढ़ने में आसान नहीं है, लेकिन मैं आलसी हूं इसलिए यह कैसे रह रहा है।
BuildFun
वास्तुकार, बिल्डफुन, एक काफी सरल भूलभुलैया पैदा करने वाला कार्यक्रम है जो हमेशा एक 'परफेक्ट' भूलभुलैया बनाता है (कोई लूप नहीं है और जहां किसी भी दो बिंदुओं के बीच हमेशा एक ही रास्ता होगा)। यह बीज इनपुट के अपने तर्क को आधार बनाता है जिसका अर्थ है कि उत्पन्न हुए छद्म यादृच्छिक हैं जो अक्सर पैटर्न दोहराते हुए दिखाई देते हैं और, एक ही बीज और आकार के साथ, एक ही भूलभुलैया बनाया जाएगा।
एक बार भूलभुलैया उत्पन्न होने के बाद, प्रोग्राम स्टार्ट पॉइंट और अंत बिंदु की खोज करके भूलभुलैया के स्कोर को अधिकतम करने का प्रयास करेगा, जिसके परिणामस्वरूप उनके बीच सबसे लंबा रास्ता तय होगा। ऐसा करने के लिए, यह हर शुरुआत बिंदु से गुजरता है, इससे अंत बिंदु को दूर करने के लिए ट्रेसर को फैलाता है, और सबसे लंबे पथ के साथ संयोजन चुनता है।
इसके बाद, यह भूलभुलैया खींचता है, दीवारों को गिनता है और भूलभुलैया की जानकारी को आउटपुट करता है। यह प्रारंभ बिंदु, अंत बिंदु, उनके बीच की दूरी, दीवारों की संख्या और स्कोर है। यह आकार, प्रारंभ और अंत, क्षैतिज दीवारों और ऊर्ध्वाधर दीवारों के लिए ऊपर वर्णित शैली में भी इस जानकारी को प्रारूपित करता है और इसे बाद में उपयोग के लिए भूलभुलैया.टैक्स नामक एक पाठ फ़ाइल में सहेजता है।
SolveFun
Solver, SolveFun, इनपुट के रूप में पाठ फ़ाइल Maze.txt का उपयोग करता है और आर्किटेक्ट के समान तरीके से काम करता है। हर चाल के लिए, यह एक दिशा का चयन करेगा कि यह अंत तक अपनी सापेक्ष स्थिति के आधार पर जाना चाहता है और फिर यह आसपास की दीवारों को देखेगा। यदि एक दीवार नहीं है, तो यह देखने के लिए जांच करेगा कि क्या यह उसके बगल में सेल में है और यदि नहीं, तो इसे संभव विकल्प के रूप में जोड़ा जाएगा। यह तब अपनी पसंदीदा दिशा के सबसे निकट होगा, बशर्ते उसके पास विकल्प हों। यदि इसके पास विकल्प नहीं हैं, तो यह तब तक पीछे हट जाएगा, जब तक यह ऐसा नहीं करता। यह तब तक जारी रहता है जब तक यह अंत तक नहीं पहुंच जाता है।
जैसा कि यह चलता है, यह चर पथ में ले जाने वाले पथ को रिकॉर्ड करता है जिसका उपयोग चरणों की कुल संख्या को आउटपुट करने के लिए अंत में किया जाता है। यह अंत में व्यर्थ चरणों की गणना करने के लिए उपयोग किए जाने वाले बैकट्रैक की मात्रा को भी रिकॉर्ड करता है। जब यह अंत तक पहुंचता है, तो यह शुरुआत से अंत तक सबसे छोटे रास्ते के साथ भूलभुलैया का उत्पादन करेगा *
।
कैसे चलाना है
भूलभुलैया के उत्पादन की विधि के कारण (जिसमें कुछ वर्णों को रेखांकित करना शामिल है), इसे प्रपत्र में एक कमांड लाइन से चलाया जाना है
python -c 'import filename;filename.BuildFun(Size, Seed)'
तथा
python -c 'import filename;filename.SolveFun()'
जहां आकार 15 और 50 (समावेशी) के बीच एक पूर्णांक है और बीज 4 और आकार (समावेशी) के बीच एक पूर्णांक है।