用户:
红石小蝈查看:0 回复:2 评论:0 创建时间:2019-06-05T21:59:09
【作品展示】

【作品介绍】
maze generatorv1.0.0
迷宫生成器
由于海龟制图的原因,迷宫生成较慢
注释见代码
【作品源代码】
import random
import turtle
from time import sleep
# constants
BG_COLOR = '#66ccff'
EX_COLOR = '#ee0000'
ED_COLOR = '#000000'
SIZE = 32
WIDTH = 0.00625*SIZE
LENTH = 0.055*SIZE
WI2 = 0.01*SIZE
UP = 1j
DN = -1j
RT = 1
LT = -1
##
turtle.bgcolor(BG_COLOR)
class Line(turtle.Turtle): # main classes
'''a line class based on turtle.Turtle
sides of blocks'''
def __init__(self, x, y, is_ver, expected):
self.p = False
self.is_ver = is_ver
self.expected = expected
turtle.Turtle.__init__(self, shape='喵', visible=False)
self.pu()
self.speed(0)
self.position = (x, y)
self.shapesize(WIDTH, LENTH, WI2)
self.ORIGINAL_STATE = expected
if expected:
self.color(EX_COLOR)
if self.is_ver:
self.goto(x*SIZE, y*SIZE-SIZE/2)
else:
self.goto(x*SIZE-SIZE/2, y*SIZE)
self.rt(90)
self.st()
def pass_(self):
'''make the line passable'''
self.p = True
self.ht()
self.expected = False
def erase(self):
'''do this when delete the line from the list'''
self.expected = False
self.color(ED_COLOR)
def reset(self):
'''reset the line'''
self.expected = self.ORIGINAL_STATE
self.st()
if self.expected:
self.color(EX_COLOR)
else:
self.color(ED_COLOR)
def __bool__(self):
return self.p
def __repr__(self):
return 'Line({},{},{})'.format(self.position, self.p, self.expected)
class Block:
'''a block class, have 4 lines as sides
'''
def __init__(self, u_bound, l_bound, r_bound, d_bound, x, y):
self.up = u_bound
self.lt = l_bound
self.rt = r_bound
self.dn = d_bound
self.l_setup()
self.called = False
self.d = {UP: self.up,
LT: self.lt,
RT: self.rt,
DN: self.dn}
self.x = x
self.y = y
def open_from(self, way):
'''open the block from the way'''
self.d[-way].pass_()
self.called = True
if way in self.l:
self.l.remove(way)
def open_to(self, way):
'''open the block to the way'''
if way in self.l:
self.l.remove(way)
def unable_side(self, way):
'''delete the side'''
self.d[way].erase()
self.l.remove(way)
def reset(self):
'''reset all the sides and the block'''
for _x in self.d.values():
_x.reset()
self.l_setup()
self.called = False
def l_setup(self):
'''setup the list'''
self.l = []
if self.up.expected:
self.l.append(UP)
if self.lt.expected:
self.l.append(LT)
if self.rt.expected:
self.l.append(RT)
if self.dn.expected:
self.l.append(DN)
def __repr__(self):
return 'Block({},{},{})'.format(self.x, self.y, self.d)
class Grid:
''' a grid class,
lenth 2*x+1
width 2*y+1
'''
def __init__(self, x, y):
self.l = []
self.ver = 2*x+1
self.hor = 2*y+1
for _x in range(-x, x+1):
self.l.append([])
for _y in range(-y, y+1):
if _x == -x:
lt = Line(_x, _y, False, False)
else:
lt = self.l[-2][_y+y].rt
##
if _y == -y:
dn = Line(_x, _y, True, False)
else:
dn = self.l[-1][-1].up
##
up = (Line(_x, _y+1, True, _y != y))
rt = (Line(_x+1, _y, False, _x != x))
self.l[-1].append(Block(up, lt, rt, dn,
len(self.l)-1, len(self.l[-1])))
self._0 = self.l[0][0]
'''
self._0.lt.pass_()
self._0.dn.pass_()
'''
def open_from_to(self, x, y, way):
'''open from (x,y) to the ...'''
# print(way)
b0 = self.l[x][y]
try:
if way == UP:
b1 = self.l[x][y+1]
elif way == LT:
b1 = self.l[x-1][y]
elif way == RT:
b1 = self.l[x+1][y]
else:
b1 = self.l[x][y-1]
# print(b1)
except IndexError:
raise IndexError('u r opening from a side block to outside')
else:
if not (-1 <= b1.x-b0.x <= 1 and -1 <= b1.x-b0.x <= 1):
raise IndexError('u r opening from a side block to outside')
if b1.called:
b0.unable_side(way)
else:
b0.open_to(way)
b1.open_from(way)
return b1
def maze1(self):
'''make a maze using BFS'''
recent_call = [self._0]
while len(recent_call) > 0:
_x = random.choice(recent_call)
# print(_x)
try:
new_call = self.open_from_to(_x.x, _x.y,
random.choice(_x.l))
if not new_call is None:
recent_call.append(new_call)
except IndexError:
# print(_x)
recent_call.remove(_x)
'''
self.l[-1][-1].up.pass_()
self.l[-1][-1].rt.pass_()
'''
return 'Done!'
def maze2(self):
'''make a maze using DFS'''
recent_call = [self._0]
while len(recent_call) > 0:
_x = random.choice(recent_call)
while True:
# print(_x)
try:
new_call = self.open_from_to(_x.x, _x.y,
random.choice(_x.l))
if not new_call is None:
recent_call.append(new_call)
_x = new_call
else:
break # continue
except IndexError:
# print(_x)
recent_call.remove(_x)
break
# self.l[-1][-1].dn.pass_()
# self.l[-1][-1].rt.pass_()
return 'Done!'
def reset(self):
for _x in self.l:
for _y in _x:
_y.reset()
class AI_Player(turtle.Turtle):
def __init__(self, maze):
turtle.Turtle.__init__(self, 'turtle', visible=False)
self.maze = maze
self.track = []
self.position = complex()
self.pu()
self.speed(0)
self.block = maze._0
p = self.block.up.pos()
self.goto(p[0], p[1]-SIZE/2)
self.facing = 1+0j
self.st()
self.pd()
'''
def wall_on_left(self):
self.maze.l[int(self.position.real)]\
[int(self.position.imag)].d[self.facing*1j]
'''
def main(self):
# while self.pos!=complex(self.maze.ver-1,self.maze.hor-1):
for _x in range(20):
while True:
if self.maze.l[int(self.position.real)][int(self.position.imag)].d[self.facing]:
print('break1')
break
else:
self.facing *= -1j
self.lt(90)
sleep(1)
self.position += self.facing
self.fd(SIZE)
if self.position in self.track:
while self.track[-1] != self.position:
self.track.pop()
self.facing *= 1j
else:
self.track.append(self.position)
if __name__ == '__main__':
g = Grid(4, 4)
msg = g.maze2()
print(msg)
# p=AI_Player(g)
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn