def get_poligon(vertices, density, center_x, center_y, radius, angle=None): """ Returns coordinates of star poligon: (x1, y1), (x1, y2), ... """ v = Vector(0, radius) if angle: v = v.rotate(angle) for i in xrange(vertices+1): v = v.rotate(-float(360)/vertices * density) yield v.x + center_x, v.y + center_y
def update(self, nab): # list of 2D shapes, starting with regular ones h = Vector(self.movx, self.movy) self.movx, self.movy = h.rotate(0.05) if self.use_mouse: self.player.pos[0] = Window.mouse_pos[0] - self.player.height / 2 self.player.pos[1] = Window.mouse_pos[1] - self.player.height / 2 self.tiempo += 1 if self.tiempo % 10 == 0 and self.score / 10 <= 21: print(len(self.otros)) if randint(1, 10) == 3: self.createOther(self.otros, (1, 1, 1)) self.createOther(self.otros) for shape in self.otros: shape.move((self.movx, self.movy)) if not ((-100 < shape.x < self.width + 55) or (-100 < shape.y < self.height + 55)): pos = self.NewPosicion() shape.pos = pos shape.circulo.pos = pos for com in self.otros: x = (self.player.center_x - com.center_x)**2 y = (self.player.center_y - com.center_y)**2 if sqrt(x + y) <= (self.player.height + com.height) / 2: # dispatch a custom event if the objects collide self.dispatch('on_collision', com) # move shapes to some random position if self.tiempo % 10 == 0: self.score += 1 if self.vida < 0: self.offGame() self.vida -= 1
def count_ray_error(layer, car, max_distance=40, angle_delta=20): cx, cy = car.center cw, ch = car.size lh, lw = layer.shape err = 0 min_d = round( math.sqrt((cw / 2)**2 + (ch / 2)**2)) # dystans od którego będzie sprawdzany sv = Vector(0, -1).rotate(car.angle) points_x = [] points_y = [] for angle in range(0, 181, angle_delta): # shift center outside a car sx = cx + sv.x * min_d sy = cy + sv.y * min_d dis = max_distance found = False for d in range(0, max_distance): py = int(sy + sv.y * d) px = int(sx + sv.x * d) if px >= lw or px < 0 or lh - py <= 0 or lh - py >= lh: points_x.append(px) points_y.append(py) found = True dis = d break if layer[lh - py][px] > 0: # ray found nearest point points_x.append(px) points_y.append(py) found = True dis = d break if not found: points_x.append(sx + sv.x * max_distance) points_y.append(sy + sv.y * max_distance) sv = sv.rotate(angle_delta) if angle < 90: err += (dis - max_distance)**2 else: err -= (dis - max_distance)**2 return err, list(zip(points_x, points_y))
def load(self, fling_board): num_points = 24 r = 250 center_x = fling_board.width / 2. center_y = fling_board.height / 2. black_hole = BlackHole(pos=(center_x, center_y)) fling_board.add_black_hole(black_hole) v = Vector(r, 0) rotation_angle = 360. / num_points for i in range(num_points): goal_point = GoalPoint(pos=(center_x + v.x, center_y + v.y)) fling_board.add_goal_point(goal_point) v = v.rotate(rotation_angle)
def on_collision(self, pair, *args): '''Dispatched when objects collide, gives back colliding objects as a "pair" argument holding their instances. ''' if pair.color == (1, 1, 1): self.vida += 50 self.score += 150 pos = self.NewPosicion() pair.pos = pos pair.circulo.pos = pos self.movx, self.movy = Vector( self.movx, self.movy) * (1.05 - .05 * self.movx / 20) h = Vector(self.movx, self.movy) self.movx, self.movy = h.rotate(-10) else: self.vida -= 10
def tick(self, dt): #self.p_direction = tuple(i+2 for i in self.p_direction) normal = Vector(1, 0) gravity = Vector(*self.pos) - Vector(0, 50) # location of gravity center g = 100 """if self.ellapsed < 70: g -= 5 elif self.ellapsed < 130: g += 12.5 else: self.ellapsed = self.ellapsed % 60 + 10""" for idx, p in enumerate(self.particles): if p[0] >= self.lifetime: del self.particles[idx] # gravity g_magnitude = g / (Vector(*gravity).distance(p[3]) ** 2) g_vector = (Vector(*gravity) - Vector(*p[3])) * g_magnitude # position speed_vec = normal.rotate(p[4]) * p[5] total_vec = speed_vec + g_vector p[4] = degrees(atan2(total_vec[1], total_vec[0])) p[3] = Vector(*p[3]) + total_vec # speed p[5] += 0 # direction #p[4] += 5 # size p[2] += 0 # time p[0] += 1 for idx, p in enumerate(self.particles2): if p[0] >= self.lifetime2: del self.particles2[idx] p[0] += 1 if self.ellapsed < 10: self.spawn() self.spawn2() self.draw() self.ellapsed += 1
class PlainPhisics(BasePhisics): """Phisics model with linear gravity vector""" def __init__(self, *args, gravity=(0, 0), **kwargs): """PlainPisics constructor :param gravity: gravity vector :param gravity: kivy.Vector """ super(PlainPhisics, self). __init__(*args, **kwargs) self.gravity = Vector(gravity) def _get_acceleration(self, world_object): """Returns object's acceleration change :param world_object: object which acceleration will be changed :type world_object: parabox.base_object.BaseObject :return: acceleration change :rtype: Vector """ return self.gravity.rotate(self.angle)
def test_rotate(self): v = Vector(100, 0) v = v.rotate(45) self.assertEqual(v.x, 70.710678118654755) self.assertEqual(v.y, 70.710678118654741)
def collide_wall(self, wall): # don't collide with this wall if we just did so; this # eliminates a huge class of weird behaviors if self.last_bounced_wall == wall and self.last_bounced_ticks < 5: return deflect_edge = None velocity_v = Vector(self.velocity) pos_v = Vector(self.pos) edge_points = zip(wall.quad_points[0::2], wall.quad_points[1::2]) edges = [ (edge_points[0], edge_points[1]), (edge_points[1], edge_points[2]), (edge_points[2], edge_points[3]), (edge_points[3], edge_points[0]), ] closest_point = None for point in edge_points: if (pos_v - Vector(point)).length() < self.r: if not closest_point or \ (pos_v - Vector(point)).length() < (Vector(closest_point) - Vector(point)).length(): closest_point = point if closest_point: # take the deflection edge to be the normal of here to the corner deflect_edge = (pos_v - Vector(point)).rotate(90) else: for edge in edges: e0 = Vector(edge[0]) e1 = Vector(edge[1]) ortho_v = (e0 - e1).rotate(90).normalize() dist_v = Vector.line_intersection(self.pos, pos_v + ortho_v, edge[0], edge[1]) # dist_v will be None if we happen to be parallel if not dist_v: continue dist_from_edge = (pos_v - dist_v).length() # if the shot touches the wall here if min(e0[0], e1[0]) <= dist_v[0] <= max(e0[0], e1[0]) and \ min(e0[1], e1[1]) <= dist_v[1] <= max(e0[1], e1[1]) and \ dist_from_edge < self.r + (wall.thickness / 2.): if not deflect_edge: deflect_edge = e0 - e1 dist_from_deflect_edge = dist_from_edge elif dist_from_edge < dist_from_deflect_edge: deflect_edge = e0 - e1 dist_from_deflect_edge = dist_from_edge if deflect_edge: self.velocity = velocity_v.rotate(-2 * velocity_v.angle(deflect_edge)) self.last_bounced_wall = wall self.last_bounced_ticks = 0
def collide_wall(self, wall): # don't collide with this wall if we just did so; this # eliminates a huge class of weird behaviors if self.last_bounced_wall == wall and self.last_bounced_ticks < 5: return deflect_edge = None velocity_v = Vector(self.velocity) pos_v = Vector(self.pos) edge_points = zip(wall.quad_points[0::2], wall.quad_points[1::2]) edges = [ (edge_points[0], edge_points[1]), (edge_points[1], edge_points[2]), (edge_points[2], edge_points[3]), (edge_points[3], edge_points[0]), ] closest_point = None for point in edge_points: if (pos_v - Vector(point)).length() < self.r: if ( not closest_point or (pos_v - Vector(point)).length() < (Vector(closest_point) - Vector(point)).length() ): closest_point = point if closest_point: # take the deflection edge to be the normal of here to the corner deflect_edge = (pos_v - Vector(point)).rotate(90) else: for edge in edges: e0 = Vector(edge[0]) e1 = Vector(edge[1]) ortho_v = (e0 - e1).rotate(90).normalize() dist_v = Vector.line_intersection(self.pos, pos_v + ortho_v, edge[0], edge[1]) # dist_v will be None if we happen to be parallel if not dist_v: continue dist_from_edge = (pos_v - dist_v).length() # if the shot touches the wall here if ( min(e0[0], e1[0]) <= dist_v[0] <= max(e0[0], e1[0]) and min(e0[1], e1[1]) <= dist_v[1] <= max(e0[1], e1[1]) and dist_from_edge < self.r + (wall.thickness / 2.0) ): if not deflect_edge: deflect_edge = e0 - e1 dist_from_deflect_edge = dist_from_edge elif dist_from_edge < dist_from_deflect_edge: deflect_edge = e0 - e1 dist_from_deflect_edge = dist_from_edge if deflect_edge: self.velocity = velocity_v.rotate(-2 * velocity_v.angle(deflect_edge)) self.last_bounced_wall = wall self.last_bounced_ticks = 0
class Car(RelativeLayout): _ROTATIONS = (0, 20, -20) def __init__(self, car_idx, initial_destination, args): self.pos = (100, 100) self._idx = car_idx self._sand_speed = _PADDING / 5.0 self._full_speed = _PADDING / 4.0 self._velocity = self._full_speed self._last_action = 0 # index of _ROTATIONS self._direction = Vector(-1, 0) self._scores = [] self._orientation = 0.0 self._distance = 0.0 self._current_destination = initial_destination self._write_status_file = args.write_status_file if self._write_status_file: self._status_file = open("car{}_status".format(car_idx), "w") RelativeLayout.__init__(self) with self.canvas.before: PushMatrix() self._rotation = Rotate() with self.canvas.after: PopMatrix() self._center = Center() self._body = Body(Vector(-5, -5), _IDX_TO_COLOR[self._idx][0]) self._mid_sensor = Sensor(Vector(-30, -5), RGBAColor.RED, self._rotation) self._right_sensor = Sensor(Vector(-20, 10), RGBAColor.GREEN, self._rotation) self._left_sensor = Sensor(Vector(-20, -20), RGBAColor.BLUE, self._rotation) if args.use_pytorch: from torch_ai import Brain else: from simple_ai import Brain self._brain = Brain(len(self._state), len(self._ROTATIONS), args) def build(self): self.add_widget(self._body) self.add_widget(self._mid_sensor) self.add_widget(self._right_sensor) self.add_widget(self._left_sensor) self.add_widget(self._center) @property def _state(self): return ( self._left_sensor.signal, self._mid_sensor.signal, self._right_sensor.signal, self._orientation, -self._orientation, ) @property def position(self): return Vector(*self.pos) + self._center.position def _rotate(self, angle_of_rotation): self._rotation.angle += angle_of_rotation self._direction = self._direction.rotate(angle_of_rotation) def _write_status(self, reward): self._status_file.seek(0) self._status_file.write("Car color : {}\n".format( _IDX_TO_COLOR[self._idx][1])) self._status_file.write("Destination : {}, ({:>4d}, {:>4d})\n".format( self._current_destination, self._current_destination.position.x, self._current_destination.position.y, )) self._status_file.write("Distance : {:>9.4f}\n".format( self._distance)) self._status_file.write("Orientation : {:>9.4f}\n".format( self._orientation)) self._status_file.write("Reward : {: >9.4f}\n".format(reward)) self._status_file.write( "Middle sensor: {: 2.4f}, ({:>9.4f}, {:>9.4f})\n".format( self._mid_sensor.signal, self._mid_sensor.abs_pos.x, self._mid_sensor.abs_pos.y, )) self._status_file.write( "Right sensor : {: 2.4f}, ({:>9.4f}, {:>9.4f})\n".format( self._right_sensor.signal, self._right_sensor.abs_pos.x, self._right_sensor.abs_pos.y, )) self._status_file.write( "Left sensor : {: 2.4f}, ({:>9.4f}, {:>9.4f})\n".format( self._left_sensor.signal, self._left_sensor.abs_pos.x, self._left_sensor.abs_pos.y, )) def _set_collision_signal_value(self, sensor): if (sensor.abs_pos.x >= self.parent.width - _PADDING or sensor.abs_pos.x <= _PADDING or sensor.abs_pos.y >= self.parent.height - _PADDING or sensor.abs_pos.y <= _PADDING): sensor.signal = 1. def _get_reward(self, approached_destination): reward = 0.0 if self.position.x < _PADDING: self.pos = (_PADDING, self.pos[1]) reward = -1.0 if self.position.x > self.parent.width - _PADDING: self.pos = (self.parent.width - _PADDING, self.pos[1]) reward = -1.0 if self.position.y < _PADDING: self.pos = (self.pos[0], _PADDING) reward = -1.0 if self.position.y > self.parent.height - _PADDING: self.pos = (self.pos[0], self.parent.height - _PADDING) reward = -1.0 if reward < 0.0: if approached_destination: if self.parent.sand[int(self.position.x), int(self.position.y)] > 0: self._velocity = self._sand_speed reward += 0.1 else: self._velocity = self._full_speed reward += 0.3 else: if approached_destination: if self.parent.sand[int(self.position.x), int(self.position.y)] > 0: self._velocity = self._sand_speed reward -= 0.2 else: self._velocity = self._full_speed reward += 0.6 return reward def move(self): self._rotate(self._ROTATIONS[self._last_action]) self.pos = self._direction * self._velocity + self.pos new_distance = self.position.distance( self._current_destination.position) self._orientation = self._direction.angle( self._current_destination.position - self.position) / 180. self._left_sensor.signal = numpy.sum( self.parent.sand[int(self._left_sensor.abs_pos.x) - _SIGNAL_RADIUS:int(self._left_sensor.abs_pos.x) + _SIGNAL_RADIUS, int(self._left_sensor.abs_pos.y) - _SIGNAL_RADIUS:int(self._left_sensor.abs_pos.y) + _SIGNAL_RADIUS, ]) / 400. self._mid_sensor.signal = numpy.sum( self.parent.sand[int(self._mid_sensor.abs_pos.x) - _SIGNAL_RADIUS:int(self._mid_sensor.abs_pos.x) + _SIGNAL_RADIUS, int(self._mid_sensor.abs_pos.y) - _SIGNAL_RADIUS:int(self._mid_sensor.abs_pos.y) + _SIGNAL_RADIUS, ]) / 400. self._right_sensor.signal = numpy.sum( self.parent.sand[int(self._right_sensor.abs_pos.x) - _SIGNAL_RADIUS:int(self._right_sensor.abs_pos.x) + _SIGNAL_RADIUS, int(self._right_sensor.abs_pos.y) - _SIGNAL_RADIUS:int(self._right_sensor.abs_pos.y) + _SIGNAL_RADIUS, ]) / 400. self._set_collision_signal_value(self._left_sensor) self._set_collision_signal_value(self._right_sensor) self._set_collision_signal_value(self._mid_sensor) reward = self._get_reward(new_distance < self._distance) self._last_action = self._brain.update( reward, self._state, ) self._distance = new_distance if self._distance < _PADDING * 2: if isinstance(self._current_destination, Airport): self._current_destination = self.parent.downtown else: self._current_destination = self.parent.airport self._scores.append(self._brain.score) if len(self._scores) > 1000: del self._scores[0] if self._write_status_file: self._write_status(reward) def save_brain(self): self._brain.save("car{}_brain".format(self._idx)) def load_brain(self): self._brain.load("car{}_brain".format(self._idx)) @property def scores(self): return self._scores @property def body_color(self): return self._body.color
def serve_ball(self, v=(4,0)): self.ball.center_x = self.player.center_x self.ball.y = self.y + 100 self.ball.center=self.ball.center_x, self.ball.y v=Vector(v) self.ball.velocity = v.rotate(randint(50, 130))