বিল্ডফুন এবং সলভফুন
ঠিক আছে, এটি বেশ খানিকটা সময় নিয়েছে এবং সল্ভারটি প্রতারণা করছে কিনা তা আমি পুরোপুরি নিশ্চিত নই। যদিও এটি পুরো সময় অবিচ্ছিন্নভাবে অ্যাক্সেস পেয়েছে তবে এটি কেবল তার ঘরের মধ্যে থাকা ঘরের দিকে, তার চারপাশের দেয়ালগুলি এবং যদি তাদের মধ্যে প্রাচীর না থাকে তবে এটি সংলগ্ন কোষগুলিকেই দেখায়। এটি যদি নিয়মের বিরুদ্ধে হয় তবে দয়া করে আমাকে জানান এবং আমি এটি পরিবর্তন করার চেষ্টা করব।
যাইহোক, কোড এখানে:
#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
সলভার, সলভফান, ইনপুট হিসাবে Maze.txt পাঠ্য ফাইলটি ব্যবহার করে এবং স্থপতিটির সাথে খুব অনুরূপভাবে কাজ করে। প্রতিটি পদক্ষেপের জন্য, এটি এমন দিক বেছে নেবে যা এটি শেষের দিকে আপেক্ষিক অবস্থানের উপর ভিত্তি করে যেতে চায় এবং তারপরে এটি তার চারপাশের দেয়ালের দিকে নজর দেবে। যদি কোনও দেয়াল না থাকে, এটি এটি সংলগ্ন কক্ষে রয়েছে কিনা তা পরীক্ষা করে দেখবে এবং যদি তা না হয় তবে এটি সম্ভাব্য বিকল্প হিসাবে যুক্ত করা হবে। এটি তার পছন্দমতো দিকের সবচেয়ে কাছাকাছি দিকে চলে যাবে তবে শর্ত থাকে যে এর বিকল্প রয়েছে। যদি এর বিকল্প না থাকে তবে এটি না করা পর্যন্ত এটি ব্যাকট্র্যাক করবে। এটি শেষ অবধি পৌঁছা পর্যন্ত অব্যাহত থাকে।
এটি চলার সাথে সাথে এটি চলক পথে যে পথটি নিচ্ছে তা রেকর্ড করে যা মোট ধাপের আউটপুট দেওয়ার শেষে ব্যবহৃত হয়। এটি নষ্ট পদক্ষেপগুলি শেষে গণনা করতে ব্যাকট্র্যাক করতে কত সময় ব্যয় করেছিল তাও রেকর্ড করে। এটি যখন প্রান্তে পৌঁছে যায়, এটি শুরু থেকে শেষের দিকে সংক্ষিপ্ত পথে এসকে চিহ্নিত করে আড়ালকে আউটপুট দেয় *
।
কীভাবে চালাবেন
গোলকধাঁটি আউটপুট করার পদ্ধতির কারণে (যার মধ্যে কিছু নির্দিষ্ট অক্ষর অন্তর্ভুক্ত রয়েছে) এটি ফর্মের একটি কমান্ড লাইন থেকে চালাতে হবে
python -c 'import filename;filename.BuildFun(Size, Seed)'
এবং
python -c 'import filename;filename.SolveFun()'
যেখানে আকার 15 এবং 50 (সমেত) এর মধ্যে একটি পূর্ণসংখ্যা এবং বীজ 4 এবং আকারের (সমেত) মধ্যে একটি পূর্ণসংখ্যা হয়।