Python之turtle可视化递归探索迷宫

maze.txt内容

++++++++++++++++++++++
+      ++ ++          
+    +      + ++++++++
+ +  + ++   + +++++ ++
+ +++++ +++   +      +
+          ++++ +  + +
+++++ + +       +  + +
+++++ +++  + +  ++   +
+          + + S+ ++ +
+++++ +  + + +       +
++++++++++++++++++++++

完整代码:

import turtle

# 迷宫类 
class Maze(object):
	# 读取迷宫数据,初始化迷宫内部,并找到海龟初始位置。
	def __init__(self, mazeFileName):
		rowsInMaze = 0							#初始化迷宫行数
		columnsInMaze = 0 						#初始化迷宫列数
		self.mazelist = []						#初始化迷宫列表
		mazeFile = open(mazeFileName, 'r')		#读取迷宫文件
		for line in mazeFile:					#按行读取
			rowList = [] 						#初始化行列表
			col = 0 							#初始化列
			# for ch in line[:-1]:				#这样会丢失最后一列
			for ch in line:						#按列读取
				rowList.append(ch)				#添加到行列表
				if ch == 'S':					#S为乌龟初始位置,即迷宫起点
					self.startRow = rowsInMaze	#乌龟初始行
					self.startCol = col 		#乌龟初始列
				col = col + 1 					#下一列
			rowsInMaze = rowsInMaze + 1 		#下一行
			self.mazelist.append(rowList)		#行列表添加到迷宫列表
			columnsInMaze = len(rowList) 		#获取迷宫总列数
		self.rowsInMaze = rowsInMaze 			#设置迷宫总行数
		self.columnsInMaze = columnsInMaze		#设置迷宫总列数
		self.xTranslate = -columnsInMaze/2 		#设置迷宫左上角的初始x坐标
		self.yTranslate = rowsInMaze/2 			#设置迷宫左上角的初始y坐标
		self.t = turtle.Turtle()				#创建一个海龟对象
		self.t.shape('turtle')					#给当前指示点设置样式(类似鼠标箭头),海龟形状为参数指定的形状名,指定的形状名应存在于TurtleScreen的shape字典中。多边形的形状初始时有以下几种:"arrow", "turtle", "circle", "square", "triangle", "classic"。
		self.wn = turtle.Screen()				#创建一个能在里面作图的窗口
		self.wn.setworldcoordinates(-columnsInMaze/2, -rowsInMaze/2, columnsInMaze/2, rowsInMaze/2)			#设置世界坐标系,原点在迷宫正中心。参数依次为画布左下角x轴坐标、左下角y轴坐标、右上角x轴坐标、右上角y轴坐标

	# 在屏幕上绘制迷宫
	def drawMaze(self):
		self.t.speed(20)						#绘图速度
		for y in range(self.rowsInMaze):		#按单元格依次循环迷宫
			for x in range(self.columnsInMaze):
				if self.mazelist[y][x] == OBSTACLE:	#如果迷宫列表的该位置为障碍物,则画方块
					self.drawCenteredBox(x + self.xTranslate, -y + self.yTranslate, 'orange')

	# 画方块
	def drawCenteredBox(self, x, y, color):
		self.t.up()								#画笔抬起
		self.t.goto(x - 0.5, y - 0.5)			#前往参数位置,此处0.5偏移量的作用是使乌龟的探索路线在单元格的正中心位置
		self.t.color(color)						#方块边框为橙色
		self.t.fillcolor('green')				#方块内填充绿色
		self.t.setheading(90)					#设置海龟的朝向,标准模式:0 - 东,90 - 北,180 - 西,270 - 南。logo模式:0 - 北,90 - 东,180 - 南,270 - 西。
		self.t.down()							#画笔落下
		self.t.begin_fill()						#开始填充
		for i in range(4):						#画方块边框
			self.t.forward(1)					#前进1个单位
			self.t.right(90)					#右转90度
		self.t.end_fill()						#结束填充

	# 移动海龟
	def moveTurtle(self, x, y):
		self.t.up()								#画笔抬起
		self.t.setheading(self.t.towards(x + self.xTranslate, -y + self.yTranslate))	#setheading()设置海龟朝向,towards()从海龟位置到由(x, y),矢量或另一海龟位置连线的夹角。此数值依赖于海龟初始朝向,由"standard"、"world"或"logo" 模式设置所决定。
		self.t.goto(x + self.xTranslate, -y + self.yTranslate)	#前往目标位置

	# 画路径圆点
	def dropBreadcrumb(self, color):
		self.t.dot(color)						#dot(size=None, color)画路径圆点

	# 用以更新迷宫内的状态及在窗口中改变海龟位置,行列参数为乌龟的初始坐标。
	def updatePosition(self, row, col, val):
		self.mazelist[row][col] = val 			#设置该标记状态为当前单元格的值
		self.moveTurtle(col, row)				#移动海龟
		if val == PART_OF_PATH: 				#其中一条成功路径的圆点的颜色
			color = 'green'
		elif val == TRIED:						#尝试用的圆点的颜色
			color = 'black'
		elif val == DEAD_END:					#死胡同用的圆点的颜色
			color = 'red'
		self.dropBreadcrumb(color)				#画路径圆点并上色

	# 用以判断当前位置是否为出口。
	def isExit(self, row, col):
		return (row == 0 or row == self.rowsInMaze - 1 or col == 0 or col == self.columnsInMaze - 1)								#根据海龟位置是否在迷宫的4个边线位置判断

	# 返回键对应的值,影响searchFrom()中maze[startRow][startColumn]值的获取
	def __getitem__(self, key):
		return self.mazelist[key]

# 探索迷宫,注意此函数包括三个参数:一个迷宫对象、起始行、起始列。
def searchFrom(maze, startRow, startColumn):
	# 从初始位置开始尝试四个方向,直到找到出路。
	# 1. 遇到障碍
	if maze[startRow][startColumn] == OBSTACLE:
		return False
	# 2. 发现已经探索过的路径或死胡同
	if maze[startRow][startColumn] == TRIED or maze[startRow][startColumn]== DEAD_END:
		return False
	# 3. 发现出口
	if maze.isExit(startRow, startColumn):
		maze.updatePosition(startRow, startColumn, PART_OF_PATH)#显示出口位置,注释则不显示此点
		return True
	maze.updatePosition(startRow, startColumn, TRIED)#更新迷宫状态、设置海龟初始位置并开始尝试
	# 4. 依次尝试每个方向
	found = searchFrom(maze, startRow - 1, startColumn) or \
            searchFrom(maze, startRow + 1, startColumn) or \
            searchFrom(maze, startRow, startColumn - 1) or \
            searchFrom(maze, startRow, startColumn + 1)
	if found:													#找到出口
		maze.updatePosition(startRow, startColumn, PART_OF_PATH)#返回其中一条正确路径
	else:														#4个方向均是死胡同
		maze.updatePosition(startRow, startColumn, DEAD_END)
	return found

if __name__ == '__main__':
	PART_OF_PATH = 'O'			#部分路径
	TRIED = '.'					#尝试
	OBSTACLE = '+'				#障碍
	DEAD_END = '-'				#死胡同
	myMaze = Maze('maze.txt')	#实例化迷宫类,maze文件是使用“+”字符作为墙壁围出空心正方形空间,并用字母“S”来表示起始位置的迷宫文本文件。
	myMaze.drawMaze()			#在屏幕上绘制迷宫。
	searchFrom(myMaze, myMaze.startRow, myMaze.startCol)	#探索迷宫

结果为:
在这里插入图片描述

  • 24
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
可以使用Python中的turtle库来可视化二叉树的中序遍历。具体实现步骤如下: 1. 首先,导入turtle库和random库,并定义一个Node类表示二叉树的节点。 ```python import turtle import random class Node: def __init__(self, value): self.left = None self.right = None self.value = value ``` 2. 定义一个函数draw_node,用于在窗口上绘制一个二叉树节点。该函数接受四个参数:x、y表示节点的坐标,size表示节点的大小,color表示节点的颜色。 ```python def draw_node(x, y, size, color): turtle.penup() turtle.goto(x, y) turtle.pendown() turtle.fillcolor(color) turtle.begin_fill() turtle.circle(size) turtle.end_fill() turtle.penup() turtle.goto(x, y - size * 1.2) turtle.write(str(value), align="center", font=("Arial", 12, "normal")) ``` 3. 定义一个函数inorder,用于进行二叉树的中序遍历,并在遍历的过程中绘制节点。该函数接受两个参数:root表示二叉树的根节点,x表示根节点的横坐标。 ```python def inorder(root, x): if root is not None: inorder(root.left, x - 50) draw_node(x, 0, 20, "blue") turtle.penup() turtle.goto(x, 50) turtle.pendown() turtle.goto(x, 20) turtle.penup() turtle.goto(x - 20, -20) turtle.write(str(root.value), align="center", font=("Arial", 12, "normal")) inorder(root.right, x + 50) ``` 4. 最后,生成一个随机的二叉树,并调用inorder函数进行中序遍历。设置turtle窗口的大小,并隐藏turtle的箭头。 ```python root = Node(random.randint(0, 100)) for i in range(20): node = Node(random.randint(0, 100)) current = root while True: if node.value < current.value: if current.left is None: current.left = node break else: current = current.left else: if current.right is None: current.right = node break else: current = current.right turtle.setup(width=800, height=600) turtle.hideturtle() inorder(root, 400) ``` 完整代码如下: ```python import turtle import random class Node: def __init__(self, value): self.left = None self.right = None self.value = value def draw_node(x, y, size, color): turtle.penup() turtle.goto(x, y) turtle.pendown() turtle.fillcolor(color) turtle.begin_fill() turtle.circle(size) turtle.end_fill() turtle.penup() turtle.goto(x, y - size * 1.2) turtle.write(str(value), align="center", font=("Arial", 12, "normal")) def inorder(root, x): if root is not None: inorder(root.left, x - 50) draw_node(x, 0, 20, "blue") turtle.penup() turtle.goto(x, 50) turtle.pendown() turtle.goto(x, 20) turtle.penup() turtle.goto(x - 20, -20) turtle.write(str(root.value), align="center", font=("Arial", 12, "normal")) inorder(root.right, x + 50) root = Node(random.randint(0, 100)) for i in range(20): node = Node(random.randint(0, 100)) current = root while True: if node.value < current.value: if current.left is None: current.left = node break else: current = current.left else: if current.right is None: current.right = node break else: current = current.right turtle.setup(width=800, height=600) turtle.hideturtle() inorder(root, 400) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值