Fix Maze extension
This commit is contained in:
parent
b14bf6fff2
commit
8d95d22132
@ -1,13 +1,12 @@
|
|||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
# this extension is under licence CC-by-sa @ Tiemen DUVILLARD 2020
|
# this module is under licence MIT @ Tiemen DUVILLARD 2020
|
||||||
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
||||||
|
|
||||||
import inkex
|
import inkex
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from maze_lib import *
|
from maze_lib import *
|
||||||
|
|
||||||
|
|
||||||
def points_to_svgd(p, close=False):
|
def points_to_svgd(p, close=False):
|
||||||
""" convert list of points (x,y) pairs
|
""" convert list of points (x,y) pairs
|
||||||
into a SVG path list
|
into a SVG path list
|
||||||
@ -42,7 +41,7 @@ class Maze(inkex.EffectExtension):
|
|||||||
X = self.options.verti
|
X = self.options.verti
|
||||||
Y = self.options.horiz
|
Y = self.options.horiz
|
||||||
|
|
||||||
L = Maze(X,Y,self.options.algo)
|
L = MazeLib(X,Y,self.options.algo)
|
||||||
|
|
||||||
for i,j,door in L.verticalDoors():
|
for i,j,door in L.verticalDoors():
|
||||||
if door:
|
if door:
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#! /usr/bin/env python3
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
# this module is under licence CC-by-sa @ Tiemen DUVILLARD 2020
|
# this module is under licence MIT @ Tiemen DUVILLARD 2020
|
||||||
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
||||||
|
|
||||||
|
|
||||||
from random import choice, randrange
|
from random import choice, randrange
|
||||||
|
|
||||||
@ -168,6 +167,46 @@ def recursive_backtrack(x, y):
|
|||||||
|
|
||||||
return verti, horiz
|
return verti, horiz
|
||||||
|
|
||||||
|
|
||||||
|
def recursive_chamber(x, y):
|
||||||
|
# Initialisation of my variables
|
||||||
|
def recursive_chamber_recu(VERTI,HORIZ,xA,yA,xB,yB):
|
||||||
|
if (xB - xA <= 1):
|
||||||
|
return
|
||||||
|
elif (yB - yA <= 1):
|
||||||
|
return
|
||||||
|
else :
|
||||||
|
dx = xB-xA
|
||||||
|
dy = yB-yA
|
||||||
|
v = randrange(0,dx+dy)
|
||||||
|
if v < dx :
|
||||||
|
x = randrange(xA,xB-1)
|
||||||
|
y = randrange(yA,yB)
|
||||||
|
for i in range(yA,yB):
|
||||||
|
if i != y:
|
||||||
|
VERTI[i][x] = 1
|
||||||
|
recursive_chamber_recu(VERTI,HORIZ,xA,yA,x+1,yB)
|
||||||
|
recursive_chamber_recu(VERTI,HORIZ,x+1,yA,xB,yB)
|
||||||
|
else:
|
||||||
|
x = randrange(xA,xB)
|
||||||
|
y = randrange(yA,yB-1)
|
||||||
|
for i in range(xA,xB):
|
||||||
|
if i != x:
|
||||||
|
HORIZ[y][i] = 1
|
||||||
|
recursive_chamber_recu(VERTI,HORIZ,xA,yA,xB,y+1)
|
||||||
|
recursive_chamber_recu(VERTI,HORIZ,xA,y+1,xB,yB)
|
||||||
|
|
||||||
|
|
||||||
|
horiz = []
|
||||||
|
for i in range(y-1): horiz.append([0] * x)
|
||||||
|
verti = []
|
||||||
|
for i in range(y): verti.append([0] * (x-1))
|
||||||
|
|
||||||
|
# appel recursif
|
||||||
|
recursive_chamber_recu(verti,horiz,0,0,x,y)
|
||||||
|
|
||||||
|
return verti, horiz
|
||||||
|
|
||||||
# a empty maze
|
# a empty maze
|
||||||
def empty(x, y):
|
def empty(x, y):
|
||||||
verti = []
|
verti = []
|
||||||
@ -192,7 +231,7 @@ def full(x, y):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Maze:
|
class MazeLib:
|
||||||
"""This Class define a Maze object"""
|
"""This Class define a Maze object"""
|
||||||
def __init__(self, X=5, Y=5, algorithm="empty"):
|
def __init__(self, X=5, Y=5, algorithm="empty"):
|
||||||
"""Use : m = Maze(X:int,Y:int, algorithm:string)"""
|
"""Use : m = Maze(X:int,Y:int, algorithm:string)"""
|
||||||
@ -200,32 +239,38 @@ class Maze:
|
|||||||
self.Y = Y # height
|
self.Y = Y # height
|
||||||
self.verti = [] # table of vertical doors
|
self.verti = [] # table of vertical doors
|
||||||
self.horiz = [] # table of horizontal doors
|
self.horiz = [] # table of horizontal doors
|
||||||
|
algorithm = algorithm.lower()
|
||||||
|
|
||||||
if algorithm in ("kruskal","K") :
|
if algorithm in ("kruskal","k") :
|
||||||
self.verti, self.horiz = kruskal(self.X,self.Y)
|
self.verti, self.horiz = kruskal(self.X,self.Y)
|
||||||
self.doors = self.nbDoors()
|
self.doors = self.nbDoors()
|
||||||
self.algorithm = "kruskal"
|
self.algorithm = "kruskal"
|
||||||
self.perfect = True
|
self.perfect = True
|
||||||
|
|
||||||
elif algorithm in ("recursive_backtrack","RB") :
|
elif algorithm in ("recursive_backtrack","rb") :
|
||||||
self.verti, self.horiz = recursive_backtrack(self.X,self.Y)
|
self.verti, self.horiz = recursive_backtrack(self.X,self.Y)
|
||||||
self.doors = self.nbDoors()
|
self.doors = self.nbDoors()
|
||||||
self.algorithm = "recursive_backtrack"
|
self.algorithm = "recursive_backtrack"
|
||||||
self.perfect = True
|
self.perfect = True
|
||||||
|
|
||||||
elif algorithm in ("empty","E") :
|
elif algorithm in ("empty","e") :
|
||||||
self.verti, self.horiz = empty(self.X,self.Y)
|
self.verti, self.horiz = empty(self.X,self.Y)
|
||||||
self.doors = self.nbDoors()
|
self.doors = self.nbDoors()
|
||||||
self.algorithm = "empty"
|
self.algorithm = "empty"
|
||||||
self.perfect = False
|
self.perfect = False
|
||||||
|
|
||||||
elif algorithm in ("full","F") :
|
elif algorithm in ("full","f") :
|
||||||
self.verti, self.horiz = full(self.X,self.Y)
|
self.verti, self.horiz = full(self.X,self.Y)
|
||||||
self.doors = self.nbDoors()
|
self.doors = self.nbDoors()
|
||||||
self.algorithm = "full"
|
self.algorithm = "full"
|
||||||
self.perfect = False
|
self.perfect = False
|
||||||
|
|
||||||
|
elif algorithm in ("recursive_chamber","rc") :
|
||||||
|
self.verti, self.horiz = recursive_chamber(self.X,self.Y)
|
||||||
|
self.doors = self.nbDoors()
|
||||||
|
self.algorithm = "recursive_chamber"
|
||||||
|
self.perfect = False
|
||||||
|
|
||||||
else :
|
else :
|
||||||
raise("Algorithm not recognized. Algorithm must be in ['kruskal','recursive_backtrack','empty','full']")
|
raise("Algorithm not recognized. Algorithm must be in ['kruskal','recursive_backtrack','empty','full']")
|
||||||
|
|
||||||
@ -282,6 +327,14 @@ class Maze:
|
|||||||
return x+1,y
|
return x+1,y
|
||||||
return x,y
|
return x,y
|
||||||
|
|
||||||
|
def liberty(self, x, y):
|
||||||
|
"""return all cases accessible from (x,y)"""
|
||||||
|
r = []
|
||||||
|
for d in ["down","up","left","right"]:
|
||||||
|
if self.canMove(x,y,d):
|
||||||
|
r.append(d)
|
||||||
|
return d
|
||||||
|
|
||||||
def toSquare(self):
|
def toSquare(self):
|
||||||
"""return another representation of maze, a List of List of case in {0,1} """
|
"""return another representation of maze, a List of List of case in {0,1} """
|
||||||
RET = []
|
RET = []
|
||||||
@ -310,29 +363,27 @@ class Maze:
|
|||||||
for i in range(self.Y):
|
for i in range(self.Y):
|
||||||
laby.append(['new'] * self.X)
|
laby.append(['new'] * self.X)
|
||||||
|
|
||||||
while Pile[-1] != (xb,yb) and len(Pile) != 0:
|
while len(Pile) != 0 and Pile[-1] != (xb,yb):
|
||||||
pos = Pile[-1]
|
pos = Pile[-1]
|
||||||
x,y = pos[0],pos[1]
|
x,y = pos[0],pos[1]
|
||||||
if laby[y][x] == 'new':
|
if laby[y][x] == 'new':
|
||||||
possibilite = []
|
possibilite = []
|
||||||
for d in ['down',"up","left","right"]:
|
for d in ['down',"left","up","right"]:
|
||||||
if self.canMove(pos[0],pos[1],d) :
|
if self.canMove(pos[0],pos[1],d) :
|
||||||
nx,ny = self.move(pos[0],pos[1],d)
|
nx,ny = self.move(pos[0],pos[1],d)
|
||||||
if laby[ny][nx] == 'new' :
|
if laby[ny][nx] == 'new' :
|
||||||
possibilite.append(d)
|
possibilite.append(d)
|
||||||
|
|
||||||
if len(possibilite) == 0:
|
laby[y][x] = possibilite
|
||||||
laby[y][x] = "old"
|
|
||||||
else :
|
|
||||||
laby[y][x] = possibilite
|
|
||||||
elif laby[y][x] == "old":
|
elif laby[y][x] == "old":
|
||||||
del Pile[-1]
|
del Pile[-1]
|
||||||
del Sol[-1]
|
if len(Sol) != 0:
|
||||||
|
del Sol[-1]
|
||||||
elif type(laby[y][x]) == list:
|
elif type(laby[y][x]) == list:
|
||||||
if len(laby[y][x]) == 0:
|
if len(laby[y][x]) == 0:
|
||||||
laby[y][x] = "old"
|
laby[y][x] = "old"
|
||||||
else:
|
else:
|
||||||
ichoix = randrange(len(laby[y][x]))
|
ichoix = -1#randrange(len(laby[y][x]))
|
||||||
choix = laby[y][x][ichoix]
|
choix = laby[y][x][ichoix]
|
||||||
Pile.append(self.move(x,y,choix))
|
Pile.append(self.move(x,y,choix))
|
||||||
Sol.append(choix)
|
Sol.append(choix)
|
||||||
@ -340,6 +391,60 @@ class Maze:
|
|||||||
|
|
||||||
return Sol
|
return Sol
|
||||||
|
|
||||||
|
def furthestBox(self, xa, ya):
|
||||||
|
"""return the case furtest of the case (xa,ya)"""
|
||||||
|
Sol = []
|
||||||
|
dmax = len(Sol)
|
||||||
|
pmax = Sol.copy()
|
||||||
|
cmax = (xa,ya)
|
||||||
|
|
||||||
|
Pile = [(xa,ya)]
|
||||||
|
laby = []
|
||||||
|
for i in range(self.Y):
|
||||||
|
laby.append(['new'] * self.X)
|
||||||
|
|
||||||
|
while len(Pile) != 0:
|
||||||
|
pos = Pile[-1]
|
||||||
|
x,y = pos[0],pos[1]
|
||||||
|
if laby[y][x] == 'new':
|
||||||
|
possibilite = []
|
||||||
|
for d in ['down',"left","up","right"]:
|
||||||
|
if self.canMove(pos[0],pos[1],d) :
|
||||||
|
nx,ny = self.move(pos[0],pos[1],d)
|
||||||
|
if laby[ny][nx] == 'new' :
|
||||||
|
possibilite.append(d)
|
||||||
|
|
||||||
|
laby[y][x] = possibilite
|
||||||
|
elif laby[y][x] == "old":
|
||||||
|
if len(Sol) > dmax:
|
||||||
|
dmax = len(Sol)
|
||||||
|
pmax = Sol.copy()
|
||||||
|
cmax = (x,y)
|
||||||
|
del Pile[-1]
|
||||||
|
if len(Sol) != 0:
|
||||||
|
del Sol[-1]
|
||||||
|
elif type(laby[y][x]) == list:
|
||||||
|
if len(laby[y][x]) == 0:
|
||||||
|
laby[y][x] = "old"
|
||||||
|
else:
|
||||||
|
ichoix = -1#randrange(len(laby[y][x]))
|
||||||
|
choix = laby[y][x][ichoix]
|
||||||
|
Pile.append(self.move(x,y,choix))
|
||||||
|
Sol.append(choix)
|
||||||
|
del laby[y][x][ichoix]
|
||||||
|
|
||||||
|
return pmax, cmax
|
||||||
|
|
||||||
|
def longestWay(self):
|
||||||
|
Xa = randrange(self.X)
|
||||||
|
Ya = randrange(self.Y)
|
||||||
|
p,B = self.furthestBox(Xa,Ya)
|
||||||
|
path,C = self.furthestBox(B[0],B[1])
|
||||||
|
return B,path,C
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""Return a string contain's all information. it can be save in file, print, etc.."""
|
"""Return a string contain's all information. it can be save in file, print, etc.."""
|
||||||
s = "{};{};{};{};{};{};{}".format(self.X, self.Y, self.doors, self.algorithm, self.perfect, self.verti, self.horiz)
|
s = "{};{};{};{};{};{};{}".format(self.X, self.Y, self.doors, self.algorithm, self.perfect, self.verti, self.horiz)
|
||||||
@ -533,4 +638,4 @@ class Maze:
|
|||||||
r += "────"
|
r += "────"
|
||||||
r += "───┘"
|
r += "───┘"
|
||||||
R += r
|
R += r
|
||||||
return R
|
return R
|
Reference in New Issue
Block a user