from draw2d import Viewer, Text, Line, Rectangle, Frame, Point, Circle import math, time, random viewer = Viewer(600, 600) W = 1.0 F = viewer.frame(0., W, 0., W) F.add( Text("North", anchor_x="center", anchor_y="top", color=(0.2, 0.2, 1.0)).move_to(0.5, 0.9)) F.add( Text("South", anchor_x="center", anchor_y="bottom", color=(1.0, 1.0, 0.1)).move_to(0.5, 0.1)) F.add( Text("East", anchor_x="right", anchor_y="center", color=(0.2, 1.0, 1.0)).move_to(0.9, 0.5)) F.add( Text("West", anchor_x="left", anchor_y="center", color=(1.0, 0.2, 0.1)).move_to(0.1, 0.5)) fly = Frame() fly.add(Circle(radius=0.01).color(1, 1, 1)) label = Text("").move_to(0.01, 0.01) vlabel = Text("", rotation=0.0, anchor_x="left", anchor_y="center").move_to(0.02, 0.0) fly.add(label) fly.add(vlabel) F.add(fly, "fly") x, y = random.random(), random.random()
from draw2d import Viewer, Rectangle, Frame, Circle, Line import math, time viewer = Viewer(800, 800, clear_color=(1, 1, 1, 1)) frame = viewer.frame(-1.1, 1.1, -1.1, 1.1) for i in range(12): a = math.pi / 2 - i * 2 * math.pi / 12.0 if i % 3 == 0: m = Rectangle(-0.015, 0.015, -0.1, 0.05).color(0, 0, 0) else: m = Rectangle(-0.01, 0.01, -0.05, 0.05).color(0, 0, 0) f = Frame() f.add(m, at=(0.0, 1.0)) f.rotate_by(a) frame.add(f) hour_hand = Rectangle(-0.02, 0.02, -0.02, 0.5).color(0, 0, 0) frame.add(hour_hand) minute_hand = Rectangle(-0.01, 0.01, -0.02, 0.75).color(0, 0, 0) frame.add(minute_hand) second_hand = Rectangle(-0.003, 0.003, -0.1, 0.95).color(0, 0, 0) frame.add(second_hand) while True: t = time.localtime() s = t.tm_sec m = t.tm_min h = t.tm_hour % 12
import time from draw2d import Viewer, Marker, Circle, Text v = Viewer(600,600) f = v.frame(-200, 200, -200, 200) m1 = Marker(Circle(3, filled=False).color(1,1,0.5)) #f.add(m1, at=(0,0)) m1 = Marker(Circle(4).color(0.2,1,0.5)) m2 = Marker(Circle(4).color(0.2,1,0.5)) m3 = Marker(Circle(4).color(0.2,1,0.5)) f.add(m1, at=(1,3)) f.add(m2, at=(101,103)) f.add(m3, at=(197,198)) t = Text("hello") #f.add(t, at=(-50,50)) v.render() time.sleep(100)
class _HunterEnv(object): SIZE = 15 # 20x20 field VR = 2 # visible range: [x-2, x-1, x, x+1, x+2] SCAN_SIZE = (VR * 2 + 1)**2 + 4 SPAWN_MIN = 2 SPAWN_MAX = 10 SPAWN_ATTEMPTS = 3 MOVES = [(0, 0), (-1, 0), (1, 0), (0, -1), (0, 1)] ZERO_ACTION = 0 HISTORY_SIZE = 1 def __init__(self): self.Field = np.zeros( (self.SIZE + self.VR * 2, self.SIZE + self.VR * 2), dtype=np.float) self.NextSpawn = random.random() * (self.SPAWN_MAX - self.SPAWN_MIN) + self.SPAWN_MIN self.Hunter = None self.Actions = np.arange(5) self.Fuel = 100.0 self.Viewer = None # # scan, last_scan, borders, last_action self.ObservationDim = (self.SCAN_SIZE + 1) * self.HISTORY_SIZE high = np.array([np.inf] * self.ObservationDim) self.observation_space = spaces.Box(-high, high) self.action_space = spaces.Discrete(5) self.LastAction = self.ZERO_ACTION self.History = np.zeros((self.HISTORY_SIZE, self.SCAN_SIZE + 1)) def scan(self, x, y): out = np.empty((self.SCAN_SIZE, )) out[0] = -1.0 if x <= 0 else (1.0 if x >= self.SIZE - 1 else 0.0) out[1] = -1.0 if y <= 0 else (1.0 if y >= self.SIZE - 1 else 0.0) out[2] = float(x) / float(self.SIZE) out[3] = float(y) / float(self.SIZE) frame = self.Field[x + self.VR - self.VR:x + self.VR + self.VR + 1, y + self.VR - self.VR:y + self.VR + self.VR + 1].reshape((-1, )) assert len(frame) + 4 == self.SCAN_SIZE out[4:] = frame return out def observation(self, roll=False): if roll: x, y = self.Hunter self.History = np.roll(self.History, 1, axis=0) self.History[0, 0:self.SCAN_SIZE] = self.scan(x, y) #self.History[0,self.SCAN_SIZE] = self.LastAction return self.History.reshape((-1, )) def free_cell(self, n_attempts=None): i = 0 while n_attempts is None or i < n_attempts: x = random.randint(0, self.SIZE - 1) y = random.randint(0, self.SIZE - 1) if self.Field[x + self.VR, y + self.VR] == 0: return x, y i += 1 else: return None def spawn(self): location = self.free_cell(self.SPAWN_ATTEMPTS) if location is not None: x, y = location v = random.randint(self.SPAWN_MIN, self.SPAWN_MAX) if random.random() < 0.4: v = -v self.Field[x + self.VR, y + self.VR] = v def reset(self): self.LastAction = self.ZERO_ACTION self.History[...] = 0.0 self.History[:, self.SCAN_SIZE] = self.ZERO_ACTION self.Field[self.VR:self.SIZE + self.VR, self.VR:self.SIZE + self.VR] = 0.0 self.spawn() self.NextSpawn = random.randint(self.SPAWN_MIN, self.SPAWN_MAX) self.Hunter = self.free_cell() self.Fuel = 100.0 return self.observation(roll=False) def step(self, action): if 0.03 > random.random(): self.spawn() x, y = self.Hunter self.LastAction = action dx, dy = self.MOVES[action] x1, y1 = x + dx, y + dy reward = 0.0 if x1 < 0 or x1 > self.SIZE - 1 or y1 < 0 or y1 > self.SIZE - 1: reward -= 0.1 x1, y1 = x, y if self.Field[x + self.VR, y + self.VR] > 0.0: # and action != self.ZERO_ACTION: reward += 1.0 self.Fuel += 10.0 self.Field[x + self.VR, y + self.VR] -= 1.0 elif self.Field[x + self.VR, y + self.VR] < 0.0: reward -= 1.0 self.Field[x + self.VR, y + self.VR] += 1.0 self.Fuel -= 0.1 self.Hunter = x1, y1 done = False if self.Fuel <= 0.0: done = True reward -= 10.0 return self.observation(roll=True), reward, done, {} def render(self): if self.Viewer is None: self.Viewer = Viewer(800, 800) self.Frame = self.Viewer.frame(-0.5, self.SIZE - 0.5, -0.5, self.SIZE - 0.5) self.Frame.remove_all() self.Frame.add( Rectangle(-0.5, self.SIZE + 0.5, -0.5, self.SIZE + 0.5).color(0, 0, 0)) for x in range(self.SIZE): for y in range(self.SIZE): if self.Field[self.VR + x, self.VR + y] != 0: r = self.Field[self.VR + x, self.VR + y] / self.SPAWN_MAX * 0.45 o = Circle(radius=r) if self.Field[self.VR + x, self.VR + y] > 0: o.color(0.1, 1.0, 0.1) else: o.color(1.0, 0.1, 0.1) self.Frame.add(o, at=(x, y)) h = Circle(radius=0.5, filled=False).color(1.0, 1.0, 0.0) self.Frame.add(h, at=self.Hunter) s = Rectangle(-self.VR - 0.5, self.VR + 0.5, -self.VR - 0.5, self.VR + 0.5, filled=False).color(0.2, 0.4, 0.4) self.Frame.add(s, at=self.Hunter) time.sleep(0.03) self.Viewer.render()
class _Elevator(object): NFloors = 8 Capacity = 10 ArrivalRate = 0.2 def __init__(self): self.ObservationDim = self.NFloors * 4 high = np.array([np.inf] * self.ObservationDim) self.observation_space = spaces.Box(-high, high) self.action_space = spaces.Discrete(3) self.Viewer = None def init_rendering(self): self.FloorColors = gen_colors(self.NFloors, (0.1, 0.1, 0.9), (0.1, 0.9, 0.1), (1.0, 1.0, 0.1)) self.Viewer = Viewer(600, 600) self.Frame = self.Viewer.frame(0., 20., 0., self.NFloors) elevator_well = Frame() self.Frame.add(elevator_well, at=(3.0, 0.0)) self.ElevatorFrame = Frame() self.ElevatorFrame.add(Rectangle(0.0, self.Capacity, 0.0, 1.0, filled=False).color(0.8, 0.8, 0.8), at=(0, 0)) elevator_well.add(self.ElevatorFrame, at=(0.0, 0)) self.FloorFrames = [] self.QueueFrames = [] for f in range(self.NFloors): frame = Frame() self.Frame.add(frame, at=(0.0, f)) self.FloorFrames.append(frame) frame.add(Rectangle(0.0, 2.0, 0.0, 1.0).color(*self.FloorColors[f]), at=(0, 0)) qf = Frame() frame.add(qf, at=(3.0 + self.Capacity, 0.0)) self.QueueFrames.append(qf) def reset(self): self.Floor = 0 self.Load = np.zeros((self.NFloors, )) self.Queues = [[] for _ in range(self.NFloors)] return self.observation() def exchange(self): # # unload # unloaded = self.Load[self.Floor] self.Load[self.Floor] = 0 q = self.Queues[self.Floor] n = max(0, self.Capacity - int(sum(self.Load))) n = min(n, len(q)) #print (type(n), n) for i in q[:n]: self.Load[i] += 1 self.Queues[self.Floor] = q[n:] return unloaded * 10.0 def observation(self): # # one-hot floor number # load # up buttons # down buttons # up_buttons = np.zeros((self.NFloors, )) down_buttons = np.zeros((self.NFloors, )) for f, q in enumerate(self.Queues): up = down = 0 for d in q: if d > f: up = 1 elif d < f: down = 1 up_buttons[f] = up down_buttons[f] = down floor = np.zeros((self.NFloors, ), dtype=np.float) floor[self.Floor] = 1 v = np.concatenate([floor, self.Load, up_buttons, down_buttons]) return np.array(v, dtype=np.float) def step(self, action): reward = -0.1 * (sum(len(q) for q in self.Queues) + sum(self.Load)) if action == 0: reward += self.exchange() elif action == 1: if self.Floor > 0: self.Floor -= 1 else: reward -= 10.0 reward -= 0.01 elif action == 2: if self.Floor < self.NFloors - 1: self.Floor += 1 else: reward -= 10.0 reward -= 0.01 if self.ArrivalRate > random.random(): i = random.randint(0, self.NFloors - 1) if len(self.Queues[i]) < self.Capacity: j = random.randint(0, self.NFloors - 1) while j == i: j = random.randint(0, self.NFloors - 1) self.Queues[i].append(j) return self.observation(), reward, False, {} PersonUp = [(0.0, 0.1), (0.9, 0.1), (0.45, 0.4)] PersonDown = [(0.0, 0.4), (0.9, 0.4), (0.45, 0.1)] PersonSide = [(0.0, 0.1), (0.0, 0.4), (0.9, 0.25)] def render(self): if self.Viewer is None: self.init_rendering() self.ElevatorFrame.remove_all() self.ElevatorFrame.move_to(0.0, self.Floor) self.ElevatorFrame.add(Rectangle(0.0, self.Capacity, 0.0, 1.0, filled=False).color(0.5, 0.5, 0.5), at=(0, 0)) x = 0 for f, n in enumerate(self.Load): n = int(n) for _ in range(n): p = self.PersonUp if f > self.Floor else ( self.PersonDown if f < self.Floor else self.PersonSide) p = Polygon(p).color(*self.FloorColors[f]) self.ElevatorFrame.add(p, at=(x, 0)) x += 1 for f, q in enumerate(self.Queues): qf = self.QueueFrames[f] qf.remove_all() x = 0 for df in q: p = self.PersonUp if df > f else ( self.PersonDown if df < f else self.PersonSide) p = Polygon(p).color(*self.FloorColors[df]) qf.add(p, at=(x, 0)) x += 1 self.Viewer.render() time.sleep(0.1)
from draw2d import Viewer, Circle, Polygon, Rectangle, Text, Marker import time viewer = Viewer(800, 800) frame = viewer.frame(-1.0, 1.0, -1.0, 1.0) circle = Circle(0.2).color(1,1,1) square = Rectangle(0, 0.1, 0, 0.1).color(0,1,0) text = Text("Hello world", color=(0.5,0.5,1.0), anchor_x="center", anchor_y="center") marker = Marker(Polygon([(-5,0), (5,0), (0,10)]).color(1,0.5,0.5)) frame.add(circle, at=(0,0)) frame.add(square, at=(0.4,0.1)) frame.add(text, at=(-0.5,-0.3)) frame.add(marker, at=(-0.5, 0.3)) viewer.render() while True: time.sleep(1.0)
class _TanksEnv(object): FireRange = 0.4 Speed = 0.05 RotSpeed = math.pi * 2 / 50 Width = 0.03 X0 = 0.0 X1 = 1.0 Y0 = 0.0 Y1 = 1.0 IDLE = 0 FIRE = 1 FWD = 2 #BACK = 3 LEFT = 3 RIGHT = 4 NumActions = 5 def __init__(self, ntanks): self.Viewer = None self.NPLAYERS = ntanks self.ObservationShape = (self.NPLAYERS, self.NPLAYERS * 3) self.ActionShape = (self.NPLAYERS, ) def reset(self): self.Pos = np.random.random((self.NPLAYERS, 2)) self.Angle = np.random.random((self.NPLAYERS, )) * 2 * math.pi self.Hit = np.zeros((self.NPLAYERS, )) # for rendering only self.Fire = np.zeros((self.NPLAYERS, )) return self.observation() def round_angle(self, a): while a >= math.pi: a -= math.pi * 2 while a < -math.pi: a += math.pi * 2 return a def dist(self, i, j): return math.sqrt(np.sum(np.square(self.Pos[j] - self.Pos[i]))) def bearing(self, i, j): d = self.Pos[j] - self.Pos[i] return math.atan2(d[1], d[0]) def observation(self): obs = np.empty((self.NPLAYERS, self.NPLAYERS, 3)) for i in range(self.NPLAYERS): obs[i, 0, :2] = self.Pos[i] obs[i, 0, 2] = self.Angle[i] others = [] for j in range(self.NPLAYERS): if j != i: others.append( (self.dist(i, j), self.bearing(i, j), self.Angle[j])) others = sorted(others) obs[i, 1:, :] = others return obs.reshape((self.NPLAYERS, -1)) def step(self, actions): rewards = np.zeros((self.NPLAYERS, )) dones = np.zeros((self.NPLAYERS, )) self.Hit[:] = 0 self.Fire[:] = 0 # # move first, fire second # for i, a in enumerate(actions): if a != self.FIRE: pos = self.Pos[i] angle = self.Angle[i] if a == self.LEFT: angle += self.RotSpeed elif a == self.RIGHT: angle -= self.RotSpeed elif a in (self.FWD, self.FWD): delta = self.Speed if a == self.FWD else -self.Speed * 0.6 x0, y0 = pos dx, dy = delta * math.cos(angle), delta * math.sin(angle) x1, y1 = x0 + dx, y0 + dy if x1 > self.X1 or x1 < self.X0 or y1 > self.Y1 or y1 < self.Y0: x1, y1 = x0, y0 rewards[i] -= 1.0 pos = (x1, y1) self.Pos[i, :] = pos self.Angle[i] = self.round_angle(angle) for i, a in enumerate(actions): if a == self.FIRE: rewards[i] -= 0.1 self.Fire[i] = 1 posi = self.Pos[i] for j in range(self.NPLAYERS): if j != i: posj = self.Pos[j] dist = self.dist(i, j) if dist > 0.0 and dist < self.FireRange: b = self.bearing(i, j) da = abs(b - self.Angle[i]) if da < math.pi / 4: s = math.sin(da) * dist if abs(s) < self.Width: self.Hit[j] = 1 #print("hit:",i,j) rewards[j] -= 10.0 rewards[i] = 10.0 return self.observation(), rewards, dones, {} def init_rendering(self): from draw2d import Viewer, Rectangle, Frame, Circle, Line, Polygon self.Viewer = Viewer(800, 800) self.Frame = self.Viewer.frame(self.X0, self.X1, self.Y0, self.Y1) class Tank(object): def __init__(self, parent): self.Frame = Frame(hidden=True) self.Body = Polygon([(-0.01, -0.01), (0.01, -0.005), (0.01, 0.005), (-0.01, 0.01)], filled=True) self.Frame.add(self.Body) self.FireLine = Line( (0.005, 0.0), (_TanksEnv.FireRange, 0.0)).color(1.0, 0.8, 0.1) self.FireLine.hidden = True self.Frame.add(self.FireLine) def show(self, pos, angle, fire, hit): self.Frame.hidden = False self.Frame.move_to(*pos) self.Frame.rotate_to(angle) self.FireLine.hidden = fire == 0 #print (self.FireLine.hidden) if hit: self.Body.color(1, 0, 0) else: self.Body.color(0, 1, 1) self.Tanks = [Tank(self.Frame) for _ in range(self.NPLAYERS)] for t in self.Tanks: self.Frame.add(t.Frame) def render(self): if self.Viewer is None: self.init_rendering() any_hit = False for tank, pos, angle, fire, hit in zip(self.Tanks, self.Pos, self.Angle, self.Fire, self.Hit): tank.show(pos, angle, fire, hit) if hit: any_hit = True self.Viewer.render() if any_hit: time.sleep(0.1)