def test_turning(): ''' Asserting if a car object turns left and updates its state correctly >>> car = Car(Point(5,8), Tiles.car_left) >>> car.turn_left() >>> car.state <Tiles.car_down: 6> ''' car = Car(Point(5, 8), Tiles.car_left) car.turn_left() assert car.dx == 0 assert car.dy == 1 assert car.state == Tiles.car_down assert car.pos == Point(5, 8) car.turn_right() assert car.dx == -1 assert car.dy == 0 assert car.state == Tiles.car_left assert car.pos == Point(5, 8) car.turn_right() assert car.dx == 0 assert car.dy == -1 assert car.state == Tiles.car_up assert car.pos == Point(5, 8) car.turn_left() car.turn_left() car.turn_left() assert car.dx == 1 assert car.dy == 0 assert car.state == Tiles.car_right assert car.pos == Point(5, 8)
def test_car_creation(): car = Car(Point(5, 7), Tiles.car_left) assert car.master is None assert car.dx == -1 assert car.dy == 0 assert car.color == "yellow" assert car.dest == None car1 = Car(Point(5, 8), Tiles.car_left, dest=Point(7, 8), body="green") assert car1.master is None assert car1.dx == -1 assert car1.dy == 0 assert car1.color == "green" #TODO figure out how to change color assert car1.dest == Point(7, 8)
def add_car(self, car): self._Map__open_spots.remove(car.dest) self.city.create_arc(car.dest.x * 30 + 1, car.dest.y * 30 + 40, car.dest.x * 30 + 20, car.dest.y * 30, start=0, extent=180, fill=car.color) self.city.create_text((car.dest.x * 30 + 12, car.dest.y * 30 + 11), text="A", fill="white") self.__cars.add(car) if Point(car.dx, car.dy) in self._Map__open_spots: self._Map__open_spots.remove(Point(car.x, car.y))
def load_raw_data(data: List[List[int]]): Map.__raw_map = data Map.__open_spots = \ {Point(x, y) for y, row in enumerate(Map.__raw_map) for x, spot in enumerate(row) if (spot == Tiles.road or spot == Tiles.intersection)}
def test_update_state(): car = Car(Point(5, 8), Tiles.car_left) car.state = Tiles.car_right car.update_speed() # car.update_state() assert car.state == Tiles.car_right assert car.dx == 1 assert car.dy == 0
def set_new_post(self, new_set, original_set): for car in new_set.keys(): x, y = new_set[car] new_x, new_y = x.get(), y.get() old_x, old_y = original_set[car] if new_x != old_x or new_y != old_y: car.x, car.y = new_x, new_y car.pos = Point(x, y)
def repaint(self): self.car_colors = deepcopy(colors) self.clear() self.city.delete('all') self.city.data = self._Map__raw_map self._Map__open_spots = \ {Point(x, y) for y, row in enumerate(self._Map__raw_map) for x, spot in enumerate(row) if (spot == Tiles.road or spot == Tiles.intersection)} self.paint() self.car_w_path = self.calculate_optimal_path()
def create_widgets(self): if not len(self._Map__raw_map): self._Map__raw_map = raw_data[ 'City 1 - Complete Simulation (Small)'] self._Map__open_spots = \ {Point(x, y) for y, row in enumerate(self._Map__raw_map) for x, spot in enumerate(row) if (spot == Tiles.road or spot == Tiles.intersection)} self.city = Canvas(self, width=900, height=480) self.city.pack() self.city.data = self._Map__raw_map self.paint() self.car_w_path = self.calculate_optimal_path()
def optimal_path(self, car: Car): # -> Optional[List[Point]] # If destination is not specified if car.dest is None: return None # Occupied spaces, or visited vertex stop_signs = { Point(x, y) for y, row in enumerate(self._Map__raw_map) for x, spot in enumerate(row) if spot == Tiles.stop_sign } off_limits = (self._Map__walls | {t.pos for t in self._Map__traffic_lights} | \ {c.pos for c in self._Map__cars} | stop_signs | self._Map__sensor_lights) if car.pos in off_limits: off_limits.remove(car.pos) if car.dest in off_limits: return None result = [] best = None queue = [(0, [car.pos])] # Start with car starting position while queue: distance, path = heapq.heappop(queue) if best and len(path) > best: return result[0] node = path[-1] # -> pop off last element of path if node == car.dest: result.append(path) best = len(path) if node in off_limits: continue off_limits.add(node) for neig in node.neighbors(): if neig in off_limits: continue heapq.heappush(queue, (distance + 1, path + [neig])) return result[0]
def paint(self): # self.self._Map__raw_map = fromCSV('./data/Map01.csv') for y in range(len(self._Map__raw_map)): for x in range(len(self._Map__raw_map[y])): if self._Map__raw_map[y][x] == Tiles.wall: self.city.create_rectangle(x * 30, y * 30, 20 + x * 30, 20 + y * 30, outline="black", fill=random.choice( self.sprites)) self._Map__walls.add(Point(x, y)) elif self._Map__raw_map[y][x] == Tiles.car_left or self._Map__raw_map[y][x] == Tiles.car_down \ or self._Map__raw_map[y][x] == Tiles.car_right or self._Map__raw_map[y][x] == Tiles.car_up: color = random.choice(self.car_colors) self.car_colors.remove(color) car_dest = random.sample(self._Map__open_spots, 1)[0] car = Car(Point(x, y), self._Map__raw_map[y][x], master=self.city, dest=car_dest, body=color) self.add_car(car) elif self._Map__raw_map[y][x] == Tiles.stop_sign: MapTiles(Point(x, y), self._Map__raw_map[y][x], self.city) elif self._Map__raw_map[y][x] == Tiles.traffic_lights: tl = MapTiles(Point(x, y), self._Map__raw_map[y][x], self.city) if (self._Map__raw_map[y][x + 1] == Tiles.road and self._Map__raw_map[y + 1][x] == Tiles.road) \ or (self._Map__raw_map[y - 1][x] == Tiles.road and self._Map__raw_map[y][x - 1] == Tiles.road): tl.redOn() else: tl.greenOn() self.__traffic_lights.add(tl) elif self._Map__raw_map[y][x] == Tiles.sensor_light: sl = MapTiles(Point(x, y), self._Map__raw_map[y][x], self.city) self._Map__sensor_lights.add(sl) elif self._Map__raw_map[y][x] == Tiles.intersection: self._Map__intersections.add(Point(x, y))
fill="black")) def turn_left(self): self.dx, self.dy = self.dy, -self.dx self.update_state() def turn_right(self): self.dx, self.dy = -self.dy, self.dx self.update_state() def stop(self): self.dx, self.dy = 0, 0 def stop_for_three_step(self) -> bool: if self.count == 2: self.count = 0 return False else: self.count += 1 self.dx, self.dy = 0, 0 return True if __name__ == "__main__": from tkinter import Tk root = Tk() c = Canvas(master=root) c.pack() sl = Car(Point(1, 1), Tiles.car_right, master=c) root.mainloop()
def test_short_path(): m = Map() car = Car(Point(5, 8), Tiles.car_left, master=m.city, dest=Point(8, 8)) expected_path1 = [Point(5, 8), Point(6, 8), Point(7, 8), Point(8, 8)] m.optimal_path(car) assert expected_path1 == m.optimal_path(car) car.pos = Point(6, 8) car.dest = Point(4, 6) expected_path2 = None assert expected_path2 is None car.pos = Point(5, 8) car.dest = Point(3, 6) car.state = Tiles.car_left expected_path3 = [ Point(5, 8), Point(4, 8), Point(3, 8), Point(3, 7), Point(3, 6) ] m.optimal_path(car) assert expected_path3 == m.optimal_path(car)
def create_widgets(self): self.command = Controller(self) self.traffic_map = Map(self) for car, path in self.traffic_map.car_w_path.items(): car.dx, car.dy = path[1].x - path[0].x, path[1].y - path[0].y car.update_state() counter = 0 reset = 1 while True: while self.command._running is not True: self.command.update() self.update() if self.command._reset is True: self.traffic_map.repaint() self.command._reset = False reset = 1 while self.command._running is True: if self.command._reset is True: self.traffic_map.repaint() self.command._reset = False reset = 1 if self.command._ispause is not True and reset == 1: if counter % 90 == 0: for tl in self.traffic_map.get_traffic_lights(): tl.blink() for sl in self.traffic_map.get_sensor_lights(): sl.sl_blink() if counter % 30 == 0: for sl in self.traffic_map.get_sensor_lights(): found_car = False for car in self.traffic_map.car_w_path.keys(): if car.pos in sl.pos.around(): found_car = True if found_car: sl.sl_greenOn() sl.sl_redOff() else: sl.sl_greenOff() sl.sl_redOn() for car, path in self.traffic_map.car_w_path.items(): if Tiles.stop_sign in car.neighbors(): if car.stop_for_three_step(): continue update = True for tl in self.traffic_map.get_traffic_lights(): if tl.pos in car.pos.neighbors(): if tl.light == LightT.red: # LightT.red car.dx, car.dy = 0, 0 update = False break if not update: continue if len(path) > 1: car.dx, car.dy = path[1].x - path[0].x, path[ 1].y - path[0].y car.update_state() path.pop(0) else: car.stop() for car in self.traffic_map.car_w_path.keys(): for comp in car.get_component(): self.traffic_map.city.move(comp, car.dx, car.dy) if counter % 30 == 0: car.x += car.dx car.y += car.dy car.pos = Point(car.x, car.y) counter += 1 sleep(0.01) self.command.update() self.traffic_map.update() self.update() while self.command._running is not True: reset = 0 self.command.update() self.update() if self.command._reset is True: self.traffic_map.repaint() self.command._reset = False reset = 1
self.sl_light = LightT.green def sl_greenOff(self): self.master.create_oval(self.x * 30 + 5, self.y * 30 + 13, self.x * 30 + 17, self.y * 30 + 25, fill="grey") if __name__ == "__main__": from tkinter import Tk root = Tk() c = Canvas(master=root) c.pack() sl = MapTiles(Point(1, 1), Tiles.sensor_light, master=c) # sl.draw_traffic_lights() counter = 0 while True: if counter % 1000 == 0: sl.sl_greenOn() sl.sl_redOff() else: sl.sl_greenOn() sl.sl_redOff() counter += 1 c.update() root.update() root.mainloop()