Added "Maze" extension
This commit is contained in:
parent
58d97bdca4
commit
4042ceb405
27
extensions/fablabchemnitz/maze/laby.inx
Normal file
27
extensions/fablabchemnitz/maze/laby.inx
Normal file
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>Maze</name>
|
||||
<id>fablabchemnitz.de.maze</id>
|
||||
<param name="verti" type="int" min="2" max="1000" gui-text="Height">20</param>
|
||||
<param name="horiz" type="int" min="2" max="1000" gui-text="Length">20</param>
|
||||
<param name="size" type="float" max="100.0" gui-text="Cell Size">10.0</param>
|
||||
<param name="width" type="float" gui-text="Line Width">1.0</param>
|
||||
<param name="algo" type="optiongroup" appearance="minimal" gui-text="Algorithm">
|
||||
<option value="kruskal">Kruskal</option>
|
||||
<option value="recursive_backtrack">Recursive Backtrack</option>
|
||||
<option value="empty">Empty</option>
|
||||
<option value="full">Full</option>
|
||||
</param>
|
||||
<param name="use2" type="description" xml:space="preserve">This script will generate a maze according to a certain algorithm.</param>
|
||||
<effect>
|
||||
<object-type>path</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="FabLab Chemnitz">
|
||||
<submenu name="Shape/Pattern from Generator" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
<command reldir="inx" interpreter="python">laby.py</command>
|
||||
</script>
|
||||
</inkscape-extension>
|
70
extensions/fablabchemnitz/maze/laby.py
Normal file
70
extensions/fablabchemnitz/maze/laby.py
Normal file
@ -0,0 +1,70 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# this extension is under licence CC-by-sa @ Tiemen DUVILLARD 2020
|
||||
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
||||
|
||||
import inkex
|
||||
from lxml import etree
|
||||
|
||||
# my maze module
|
||||
from maze import *
|
||||
|
||||
|
||||
def points_to_svgd(p, close=False):
|
||||
""" convert list of points (x,y) pairs
|
||||
into a SVG path list
|
||||
"""
|
||||
f = p[0]
|
||||
p = p[1:]
|
||||
svgd = 'M%.4f,%.4f' % f
|
||||
for x in p:
|
||||
svgd += 'L%.4f,%.4f' % x
|
||||
if close:
|
||||
svgd += 'z'
|
||||
return svgd
|
||||
|
||||
|
||||
class Recursive(inkex.Effect):
|
||||
|
||||
def __init__(self):
|
||||
" define how the options are mapped from the inx file "
|
||||
inkex.Effect.__init__(self) # initialize the super class
|
||||
|
||||
self.arg_parser.add_argument("--verti", type=int, default=20, help="Height")
|
||||
self.arg_parser.add_argument("--horiz", type=int, default=20, help="Length")
|
||||
self.arg_parser.add_argument("--size", type=float, default=10.0, help="Cell Size")
|
||||
self.arg_parser.add_argument("--algo", default=1, help="Algorithm")
|
||||
self.arg_parser.add_argument("--width", type=float, default=10.0, help="Line width")
|
||||
|
||||
def effect(self):
|
||||
# basic style
|
||||
style = { 'stroke': "black", "fill":"none", 'stroke-width': self.options.width }
|
||||
# my group of paths
|
||||
topgroup = etree.SubElement(self.svg.get_current_layer(), 'g' )
|
||||
|
||||
lc = self.options.size
|
||||
X = self.options.verti
|
||||
Y = self.options.horiz
|
||||
|
||||
L = Maze(X,Y,self.options.algo)
|
||||
|
||||
for i,j,door in L.verticalDoors():
|
||||
if door:
|
||||
path = points_to_svgd([(lc*(j+1), lc*(i)), (lc*(j+1), lc*(i+1))])
|
||||
mypath_attribs = { 'style': str(inkex.Style(style)), 'd': path }
|
||||
squiggle = etree.SubElement(topgroup, inkex.addNS('path','svg'), mypath_attribs )
|
||||
|
||||
for i,j,door in L.horizontalDoors():
|
||||
if door:
|
||||
path = points_to_svgd([(lc*(j), lc*(i+1)), (lc*(j+1), lc*(i+1))])
|
||||
mypath_attribs = { 'style': str(inkex.Style(style)), 'd': path }
|
||||
squiggle = etree.SubElement(topgroup, inkex.addNS('path','svg'), mypath_attribs )
|
||||
|
||||
|
||||
path = points_to_svgd([(0,0),(0,lc*Y),(lc*X,lc*Y),(lc*X,0)], True)
|
||||
mypath_attribs = { 'style': str(inkex.Style(style)), 'd': path }
|
||||
squiggle = etree.SubElement(topgroup, inkex.addNS('path','svg'), mypath_attribs )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Recursive().run()
|
537
extensions/fablabchemnitz/maze/maze.py
Normal file
537
extensions/fablabchemnitz/maze/maze.py
Normal file
@ -0,0 +1,537 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# this module is under licence CC-by-sa @ Tiemen DUVILLARD 2020
|
||||
# for all questions, comments, bugs: duvillard.tiemen@gmail.com
|
||||
|
||||
|
||||
from random import choice, randrange
|
||||
|
||||
# Representation of maze :
|
||||
# A labyrinth is a set of 2 door panels.
|
||||
# For a maze 5*5 :
|
||||
# Theory : ## Example :
|
||||
# L = [[[a, b, c, d], # vertical doors ## L = [[[1, 1, 1, 1], # vertical doors
|
||||
# [e, f, g, h], ## [1, 0, 1, 0],
|
||||
# [i, j, k, l], ## [0, 1, 0, 1],
|
||||
# [m, n, o, p], ## [0, 0, 0, 0],
|
||||
# [q, r, s, t]], ## [0, 1, 0, 0]],
|
||||
# [[A, B, C, D, E], # horizontal doors ## [[0, 0, 0, 0, 0], # horizontal doors
|
||||
# [F, G, H, I, J], ## [0, 0, 0, 0, 1],
|
||||
# [K, L, M, N, O], ## [0, 1, 1, 1, 0],
|
||||
# [P, Q, R, S, T]]] ## [0, 1, 0, 1, 1]]]
|
||||
# ##
|
||||
# ==>> ## ==>>
|
||||
# X 0 1 2 3 4 ## X 0 1 2 3 4
|
||||
# Y ┌───┬───┬───┬───┬───┐ ## Y ┌───┬───┬───┬───┬───┐
|
||||
# 0 │ ∙ a ∙ b ∙ c ∙ d ∙ │ ## 0 │ ∙ │ ∙ │ ∙ │ ∙ │ ∙ │
|
||||
# ├─A─┼─B─┼─C─┼─D─┼─E─┤ ## │ │ │ │ │ │
|
||||
# 1 │ ∙ e ∙ f ∙ g ∙ h ∙ │ ## 1 │ ∙ │ ∙ ∙ │ ∙ ∙ │
|
||||
# ├─F─┼─G─┼─H─┼─I─┼─J─┤ ## │ │ │ │ ┌───┤
|
||||
# 2 │ ∙ i ∙ j ∙ k ∙ l ∙ │ ## 2 │ ∙ ∙ │ ∙ ∙ │ ∙ │
|
||||
# ├─K─┼─L─┼─M─┼─N─┼─O─┤ ## │ ╶───┴───────┘ │
|
||||
# 3 │ ∙ m ∙ n ∙ o ∙ p ∙ │ ## 3 │ ∙ ∙ ∙ ∙ ∙ │
|
||||
# ├─P─┼─Q─┼─R─┼─S─┼─T─┤ ## │ ╶───┐ ╶───────│
|
||||
# 4 │ ∙ q ∙ r ∙ s ∙ t ∙ │ ## 4 │ ∙ ∙ │ ∙ ∙ ∙ │
|
||||
# └───┴───┴───┴───┴───┘ ## └───────┴───────────┘
|
||||
|
||||
def kruskal(x, y):
|
||||
global ID
|
||||
ID = 0
|
||||
|
||||
class case:
|
||||
"""Little class for union-find"""
|
||||
def __init__(self,x,y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.is_repr = True
|
||||
self.repr = None
|
||||
global ID
|
||||
self.ID = ID
|
||||
ID += 1
|
||||
|
||||
def represent(self):
|
||||
if self.is_repr:
|
||||
return self
|
||||
else:
|
||||
L = [self.repr]
|
||||
while not L[0].is_repr:
|
||||
L[0] = L[0].repr
|
||||
return L[0]
|
||||
|
||||
def __eq__(self,other):
|
||||
return self.represent().ID == other.represent().ID
|
||||
|
||||
def union(self,other):
|
||||
a = self.represent()
|
||||
b = other.represent()
|
||||
if not (a == b):
|
||||
b.is_repr = False
|
||||
b.repr = a
|
||||
|
||||
# set of doors
|
||||
doors = []
|
||||
# verticals doors result
|
||||
verti = []
|
||||
# horizontals doors result
|
||||
horiz = []
|
||||
# set of cases
|
||||
cases = []
|
||||
## initialize vertical doors
|
||||
for j in range(y):
|
||||
l = []
|
||||
for i in range(x-1):
|
||||
l.append(1)
|
||||
doors.append([i,j,'v'])
|
||||
verti.append(l)
|
||||
## initialize horizontal doors
|
||||
for j in range(y-1):
|
||||
l = []
|
||||
for i in range(x):
|
||||
l.append(1)
|
||||
doors.append([i,j,'h'])
|
||||
horiz.append(l)
|
||||
|
||||
## initialize cases
|
||||
for i in range(y):
|
||||
l = []
|
||||
for j in range(x):
|
||||
l.append(case(x,y))
|
||||
cases.append(l)
|
||||
|
||||
cpt = x*y -1 # nb of openings in perfect maze
|
||||
while cpt > 0:
|
||||
# I choose a door
|
||||
idoor = randrange(len(doors))
|
||||
dx, dy, dd = doors[idoor]
|
||||
cx1, cy1 = dx, dy
|
||||
if dd == 'h' : cx2, cy2 = cx1, cy1+1
|
||||
else : cx2, cy2 = cx1+1, cy1
|
||||
|
||||
C1 = cases[cy1][cx1]
|
||||
C2 = cases[cy2][cx2]
|
||||
# if the 2 cases separate by my door are not in same set
|
||||
if not C1 == C2:
|
||||
C1.union(C2)
|
||||
cpt -= 1
|
||||
# i modify my result
|
||||
if dd == "v": verti[dy][dx] = 0
|
||||
else: horiz[dy][dx] = 0
|
||||
# i delete the door
|
||||
del doors[idoor]
|
||||
|
||||
return verti,horiz
|
||||
|
||||
def recursive_backtrack(x, y):
|
||||
# Initialisation of my variables
|
||||
labyrinthe = []
|
||||
for i in range(y): labyrinthe.append([0] * x)
|
||||
horiz = []
|
||||
for i in range(y-1): horiz.append([1] * x)
|
||||
verti = []
|
||||
for i in range(y): verti.append([1] * (x-1))
|
||||
|
||||
# I choose a random start
|
||||
X_pos = randrange(x)
|
||||
Y_pos = randrange(y)
|
||||
labyrinthe[Y_pos][X_pos] = 1
|
||||
historique = [[X_pos,Y_pos]]
|
||||
|
||||
# I explore a tree with deep parcours
|
||||
while len(historique) != 0:
|
||||
X = historique[-1][0]
|
||||
Y = historique[-1][1]
|
||||
|
||||
possibilite = []
|
||||
if (Y-1 >= 0) and (labyrinthe[Y-1][X] == 0): possibilite.append(0)
|
||||
if (X+1 < x) and (labyrinthe[Y][X+1] == 0): possibilite.append(1)
|
||||
if (Y+1 < y) and (labyrinthe[Y+1][X] == 0): possibilite.append(2)
|
||||
if (X-1 >= 0) and (labyrinthe[Y][X-1] == 0): possibilite.append(3)
|
||||
|
||||
if len(possibilite) == 0:
|
||||
del historique[-1]
|
||||
else:
|
||||
d = choice(possibilite)
|
||||
if d == 0:
|
||||
X1,Y1 = X, Y-1
|
||||
horiz[Y-1][X] = 0
|
||||
if d == 1:
|
||||
X1,Y1 = X+1, Y
|
||||
verti[Y][X] = 0
|
||||
if d == 2:
|
||||
X1,Y1 = X, Y+1
|
||||
horiz[Y][X] = 0
|
||||
if d == 3:
|
||||
X1,Y1 = X-1, Y
|
||||
verti[Y][X-1] = 0
|
||||
labyrinthe[Y1][X1] = 1
|
||||
historique.append([X1,Y1])
|
||||
|
||||
return verti, horiz
|
||||
|
||||
# a empty maze
|
||||
def empty(x, y):
|
||||
verti = []
|
||||
for i in range(y):
|
||||
verti.append([0] * (x-1))
|
||||
|
||||
horiz = []
|
||||
for i in range(y-1):
|
||||
horiz.append([0] * x)
|
||||
return verti, horiz
|
||||
|
||||
# a full maze
|
||||
def full(x, y):
|
||||
verti = []
|
||||
for i in range(y):
|
||||
verti.append([1] * (x-1))
|
||||
|
||||
horiz = []
|
||||
for i in range(y-1):
|
||||
horiz.append([1] * x)
|
||||
return verti, horiz
|
||||
|
||||
|
||||
|
||||
class Maze:
|
||||
"""This Class define a Maze object"""
|
||||
def __init__(self, X=5, Y=5, algorithm="empty"):
|
||||
"""Use : m = Maze(X:int,Y:int, algorithm:string)"""
|
||||
self.X = X # width
|
||||
self.Y = Y # height
|
||||
self.verti = [] # table of vertical doors
|
||||
self.horiz = [] # table of horizontal doors
|
||||
|
||||
|
||||
if algorithm in ("kruskal","K") :
|
||||
self.verti, self.horiz = kruskal(self.X,self.Y)
|
||||
self.doors = self.nbDoors()
|
||||
self.algorithm = "kruskal"
|
||||
self.perfect = True
|
||||
|
||||
elif algorithm in ("recursive_backtrack","RB") :
|
||||
self.verti, self.horiz = recursive_backtrack(self.X,self.Y)
|
||||
self.doors = self.nbDoors()
|
||||
self.algorithm = "recursive_backtrack"
|
||||
self.perfect = True
|
||||
|
||||
elif algorithm in ("empty","E") :
|
||||
self.verti, self.horiz = empty(self.X,self.Y)
|
||||
self.doors = self.nbDoors()
|
||||
self.algorithm = "empty"
|
||||
self.perfect = False
|
||||
|
||||
elif algorithm in ("full","F") :
|
||||
self.verti, self.horiz = full(self.X,self.Y)
|
||||
self.doors = self.nbDoors()
|
||||
self.algorithm = "full"
|
||||
self.perfect = False
|
||||
|
||||
else :
|
||||
raise("Algorithm not recognized. Algorithm must be in ['kruskal','recursive_backtrack','empty','full']")
|
||||
|
||||
def __str__(self):
|
||||
"""Return information about maze"""
|
||||
s = "Size of maze : {}*{}\nGenerate by : {}\nNb of doors : {}\nPerfect : {}"
|
||||
s = s.format(self.X,self.Y,self.algorithm,self.doors,self.perfect)
|
||||
return s
|
||||
|
||||
def nbDoors(self):
|
||||
"""Return number of doors in my maze. If maze is perfect, it equals to (self.X-1)*(self.Y-1)"""
|
||||
S = 0
|
||||
for k in self.verti: S += sum(k)
|
||||
for k in self.horiz: S += sum(k)
|
||||
return S
|
||||
|
||||
def verticalDoors(self):
|
||||
"""Iterate on vertical doors"""
|
||||
for i in range(len(self.verti)):
|
||||
for j in range(len(self.verti[i])):
|
||||
yield i,j, bool(self.verti[i][j])
|
||||
|
||||
def horizontalDoors(self):
|
||||
"""Iterate on horizontal doors"""
|
||||
for i in range(len(self.horiz)):
|
||||
for j in range(len(self.horiz[i])):
|
||||
yield i,j, bool(self.horiz[i][j])
|
||||
|
||||
def canMove(self, x, y, direction) :
|
||||
"""return if i can move in a direction since (x,y) """
|
||||
if direction in ["down","d",0] : # down
|
||||
if y == self.Y-1 :return False
|
||||
return not self.horiz[y][x]
|
||||
if direction in ["up","u",2] : # up
|
||||
if y == 0 : return False
|
||||
return not self.horiz[y-1][x]
|
||||
if direction in ["left","l",3] : # left
|
||||
if x == 0 : return False
|
||||
return not self.verti[y][x-1]
|
||||
if direction in ["right","r",1] : # right
|
||||
if x == self.X-1 : return False
|
||||
return not self.verti[y][x]
|
||||
return False
|
||||
|
||||
def move(self, x, y, direction) :
|
||||
"""return new cord after one move in direction"""
|
||||
if direction in ["down","d",0] : # down
|
||||
return x,y+1
|
||||
if direction in ["up","u",2] : # up
|
||||
return x,y-1
|
||||
if direction in ["left","l",3] : # left
|
||||
return x-1,y
|
||||
if direction in ["right","r",1] : # right
|
||||
return x+1,y
|
||||
return x,y
|
||||
|
||||
def toSquare(self):
|
||||
"""return another representation of maze, a List of List of case in {0,1} """
|
||||
RET = []
|
||||
for i in range(self.Y*2+1):
|
||||
l = []
|
||||
for j in range(self.X*2+1):
|
||||
if i == 0 or i == self.Y*2 or j == 0 or j == self.X*2 :
|
||||
l.append(1)
|
||||
else :
|
||||
if (i%2==0 and j%2==0) :
|
||||
l.append(1)
|
||||
elif (i%2==1 and j%2==1):
|
||||
l.append(0)
|
||||
elif (i%2==0 and j%2==1):
|
||||
l.append(self.horiz[(i-1)//2][(j-1)//2])
|
||||
elif (i%2==1 and j%2==0):
|
||||
l.append(self.verti[(i-1)//2][(j-1)//2])
|
||||
RET.append(l)
|
||||
return RET
|
||||
|
||||
def solve(self, xa, ya, xb, yb):
|
||||
"""return a list of direction for link (xa,ya) -> (xb,yb). Null"""
|
||||
Sol = []
|
||||
Pile = [(xa,ya)]
|
||||
laby = []
|
||||
for i in range(self.Y):
|
||||
laby.append(['new'] * self.X)
|
||||
|
||||
while Pile[-1] != (xb,yb) and len(Pile) != 0:
|
||||
pos = Pile[-1]
|
||||
x,y = pos[0],pos[1]
|
||||
if laby[y][x] == 'new':
|
||||
possibilite = []
|
||||
for d in ['down',"up","left","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)
|
||||
|
||||
if len(possibilite) == 0:
|
||||
laby[y][x] = "old"
|
||||
else :
|
||||
laby[y][x] = possibilite
|
||||
elif laby[y][x] == "old":
|
||||
del Pile[-1]
|
||||
del Sol[-1]
|
||||
elif type(laby[y][x]) == list:
|
||||
if len(laby[y][x]) == 0:
|
||||
laby[y][x] = "old"
|
||||
else:
|
||||
ichoix = 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 Sol
|
||||
|
||||
def save(self):
|
||||
"""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)
|
||||
return s
|
||||
|
||||
def load(self, st):
|
||||
"""Load a Maze since a string of format save"""
|
||||
cont = st.split(";")
|
||||
self.X = int(cont[0])
|
||||
self.Y = int(cont[1])
|
||||
self.doors = int(cont[2])
|
||||
self.algorithm = cont[3]
|
||||
self.perfect = bool(cont[4])
|
||||
self.verti = cont[5].split("], [")
|
||||
for i in range(len(self.verti)):
|
||||
self.verti[i] = self.verti[i].split(',')
|
||||
for j in range(len(self.verti[i])):
|
||||
self.verti[i][j] = self.verti[i][j].replace("[","")
|
||||
self.verti[i][j] = self.verti[i][j].replace("]","")
|
||||
self.verti[i][j] = self.verti[i][j].replace(" ","")
|
||||
self.verti[i][j] = int(self.verti[i][j])
|
||||
|
||||
self.horiz = cont[6].split("], [")
|
||||
for i in range(len(self.horiz)):
|
||||
self.horiz[i] = self.horiz[i].split(',')
|
||||
for j in range(len(self.horiz[i])):
|
||||
self.horiz[i][j] = self.horiz[i][j].replace("[","")
|
||||
self.horiz[i][j] = self.horiz[i][j].replace("]","")
|
||||
self.horiz[i][j] = self.horiz[i][j].replace(" ","")
|
||||
self.horiz[i][j] = int(self.horiz[i][j])
|
||||
|
||||
def toTxt(self, centre=False, coord=False, basic= False):
|
||||
"""return a txt representation of maze in ASCII art"""
|
||||
if type(centre) == bool:
|
||||
if centre : centre = "*"
|
||||
else : centre = " "
|
||||
else:
|
||||
centre = centre[0]
|
||||
|
||||
if basic :
|
||||
if coord:
|
||||
R = " X"
|
||||
for i in range(self.X):
|
||||
R += " {} ".format(i%10)
|
||||
R += "\n"
|
||||
R += "Y +"
|
||||
r = "0 |"
|
||||
else:
|
||||
R = "+"
|
||||
r = "|"
|
||||
for j in range(self.X-1):
|
||||
if self.verti[0][j]:
|
||||
R += "---+"
|
||||
r += " {} |".format(centre)
|
||||
else:
|
||||
R += "----"
|
||||
r += " {} ".format(centre)
|
||||
R += "---+\n"
|
||||
r += " {} |\n".format(centre)
|
||||
R += r
|
||||
for i in range(self.Y-1):
|
||||
if coord:
|
||||
if self.horiz[i][0]:
|
||||
l1 = " +"
|
||||
else:
|
||||
l1 = " |"
|
||||
l2 = "{} |".format((i+1)%10)
|
||||
else:
|
||||
if self.horiz[i][0]:
|
||||
l1 = "+"
|
||||
else:
|
||||
l1 = "|"
|
||||
l2 = "|"
|
||||
for j in range(self.X-1):
|
||||
inter = "+"
|
||||
if self.horiz[i][j] and self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = "-"
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and self.verti[i][j] and self.verti[i+1][j] : inter = "|"
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = " "
|
||||
|
||||
if self.horiz[i][j]:
|
||||
l1 += "---"+inter
|
||||
else:
|
||||
l1 += " "+inter
|
||||
|
||||
if self.verti[i+1][j]:
|
||||
l2 += " {} |".format(centre)
|
||||
else:
|
||||
l2 += " {} ".format(centre)
|
||||
if self.horiz[i][-1]:
|
||||
l1 += "---+"
|
||||
else:
|
||||
l1 += " |"
|
||||
l2 += " {} |".format(centre)
|
||||
|
||||
R += l1 + "\n"
|
||||
R += l2 + "\n"
|
||||
if coord:
|
||||
r = " +"
|
||||
else:
|
||||
r = "+"
|
||||
for j in range(self.X-1):
|
||||
if self.verti[-1][j]:
|
||||
r += "---+"
|
||||
else:
|
||||
r += "----"
|
||||
r += "---+"
|
||||
R += r
|
||||
return R
|
||||
|
||||
else :
|
||||
if coord:
|
||||
R = " X"
|
||||
for i in range(self.X):
|
||||
R += " {} ".format(i%10)
|
||||
R += "\n"
|
||||
R += "Y ┌"
|
||||
r = "0 │"
|
||||
else:
|
||||
R = "┌"
|
||||
r = "│"
|
||||
for j in range(self.X-1):
|
||||
if self.verti[0][j]:
|
||||
R += "───┬"
|
||||
r += " {} │".format(centre)
|
||||
else:
|
||||
R += "────"
|
||||
r += " {} ".format(centre)
|
||||
R += "───┐\n"
|
||||
r += " {} │\n".format(centre)
|
||||
R += r
|
||||
for i in range(self.Y-1):
|
||||
if coord:
|
||||
if self.horiz[i][0]:
|
||||
l1 = " ├"
|
||||
else:
|
||||
l1 = " │"
|
||||
l2 = "{} │".format((i+1)%10)
|
||||
else:
|
||||
if self.horiz[i][0]:
|
||||
l1 = "├"
|
||||
else:
|
||||
l1 = "│"
|
||||
l2 = "│"
|
||||
for j in range(self.X-1):
|
||||
# 4 door
|
||||
if self.horiz[i][j] and self.horiz[i][j+1] and self.verti[i][j] and self.verti[i+1][j] : inter = "┼"
|
||||
# 3 door
|
||||
if self.horiz[i][j] and self.horiz[i][j+1] and self.verti[i][j] and not self.verti[i+1][j] : inter = "┴"
|
||||
if self.horiz[i][j] and self.horiz[i][j+1] and not self.verti[i][j] and self.verti[i+1][j] : inter = "┬"
|
||||
if self.horiz[i][j] and not self.horiz[i][j+1] and self.verti[i][j] and self.verti[i+1][j] : inter = "┤"
|
||||
if not self.horiz[i][j] and self.horiz[i][j+1] and self.verti[i][j] and self.verti[i+1][j] : inter = "├"
|
||||
# 2 door
|
||||
if self.horiz[i][j] and self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = "─"
|
||||
if self.horiz[i][j] and not self.horiz[i][j+1] and self.verti[i][j] and not self.verti[i+1][j] : inter = "┘"
|
||||
if not self.horiz[i][j] and self.horiz[i][j+1] and self.verti[i][j] and not self.verti[i+1][j] : inter = "└"
|
||||
if self.horiz[i][j] and not self.horiz[i][j+1] and not self.verti[i][j] and self.verti[i+1][j] : inter = "┐"
|
||||
if not self.horiz[i][j] and self.horiz[i][j+1] and not self.verti[i][j] and self.verti[i+1][j] : inter = "┌"
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and self.verti[i][j] and self.verti[i+1][j] : inter = "│"
|
||||
# 1 door
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and not self.verti[i][j] and self.verti[i+1][j] : inter = "╷"
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and self.verti[i][j] and not self.verti[i+1][j] : inter = "╵"
|
||||
if not self.horiz[i][j] and self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = "╶"
|
||||
if self.horiz[i][j] and not self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = "╴"
|
||||
# 0 door
|
||||
if not self.horiz[i][j] and not self.horiz[i][j+1] and not self.verti[i][j] and not self.verti[i+1][j] : inter = " "
|
||||
if self.horiz[i][j]:
|
||||
l1 += "───"+inter
|
||||
else:
|
||||
l1 += " "+inter
|
||||
|
||||
if self.verti[i+1][j]:
|
||||
l2 += " {} │".format(centre)
|
||||
else:
|
||||
l2 += " {} ".format(centre)
|
||||
if self.horiz[i][-1]:
|
||||
l1 += "───┤"
|
||||
else:
|
||||
l1 += " │"
|
||||
l2 += " {} │".format(centre)
|
||||
|
||||
R += l1 + "\n"
|
||||
R += l2 + "\n"
|
||||
if coord:
|
||||
r = " └"
|
||||
else:
|
||||
r = "└"
|
||||
for j in range(self.X-1):
|
||||
if self.verti[-1][j]:
|
||||
r += "───┴"
|
||||
else:
|
||||
r += "────"
|
||||
r += "───┘"
|
||||
R += r
|
||||
return R
|
Reference in New Issue
Block a user