# 问题 6: # 模拟机器人的可视化代码. # # 见问题说明怎样使用此代码. import math import time from Tkinter import * import ps6 class RobotVisualization: def __init__(self, num_robots, width, height, delay = 0.2): "用特定的参数初始可视化." # 每幅画面间停顿的秒数 self.delay = delay self.max_dim = max(width, height) self.width = width self.height = height self.num_robots = num_robots # 初始化绘画表面 self.master = Tk() self.w = Canvas(self.master, width=500, height=500) self.w.pack() self.master.update() # 画坐标轴 x1, y1 = self._map_coords(0, 0) x2, y2 = self._map_coords(width, height) self.w.create_rectangle(x1, y1, x2, y2, fill = "white") # 画灰色方框来表示脏的地板 self.tiles = {} for i in range(width): for j in range(height): x1, y1 = self._map_coords(i, j) x2, y2 = self._map_coords(i + 1, j + 1) self.tiles[(i, j)] = self.w.create_rectangle(x1, y1, x2, y2, fill = "gray") # 画网格线 for i in range(width + 1): x1, y1 = self._map_coords(i, 0) x2, y2 = self._map_coords(i, height) self.w.create_line(x1, y1, x2, y2) for i in range(height + 1): x1, y1 = self._map_coords(0, i) x2, y2 = self._map_coords(width, i) self.w.create_line(x1, y1, x2, y2) # 画一些状态说明 self.robots = None self.text = self.w.create_text(25, 0, anchor=NW, text=self._status_string(0, 0)) self.time = 0 self.master.update() def _status_string(self, time, num_clean_tiles): "显示恰当的状态说明." percent_clean = 100 * num_clean_tiles / (self.width * self.height) return "Time: %04d; %d tiles (%d%%) cleaned" % \ (time, num_clean_tiles, percent_clean) def _map_coords(self, x, y): "映射格子位置到窗口位置 (用像素表示)." return (250 + 450 * ((x - self.width / 2.0) / self.max_dim), 250 + 450 * ((self.height / 2.0 - y) / self.max_dim)) def _draw_robot(self, position, direction): "用特定的参数返回过变形来表示机器人." x, y = position d1 = direction + 165 d2 = direction - 165 x1, y1 = self._map_coords(x, y) x2, y2 = self._map_coords(x + 0.6 * math.sin(math.radians(d1)), y + 0.6 * math.cos(math.radians(d1))) x3, y3 = self._map_coords(x + 0.6 * math.sin(math.radians(d2)), y + 0.6 * math.cos(math.radians(d2))) return self.w.create_polygon([x1, y1, x2, y2, x3, y3], fill="red") def update(self, room, robots): "用特定的房间和机器人状态,重绘图像." # 移除灰色方块表示地砖已被清理. for i in range(self.width): for j in range(self.height): if ps6.is_tile_cleaned(room, i, j): self.w.delete(self.tiles[(i, j)]) # 删除所有仍在的机器人. if self.robots: for robot in self.robots: self.w.delete(robot) self.master.update_idletasks() # 画新的机器人 self.robots = [] for i in range(self.num_robots): x, y = ps6.get_robot_position(robots, i) x1, y1 = self._map_coords(x - 0.08, y - 0.08) x2, y2 = self._map_coords(x + 0.08, y + 0.08) self.robots.append(self.w.create_oval(x1, y1, x2, y2, fill = "black")) self.robots.append( self._draw_robot(ps6.get_robot_position(robots, i), ps6.get_robot_direction(robots, i))) # 更新说明 self.w.delete(self.text) self.time += 1 self.text = self.w.create_text( 25, 0, anchor=NW, text=self._status_string(self.time, ps6.get_num_cleaned_tiles(room))) self.master.update() time.sleep(self.delay)