def _get_average_absolute_velocity(self, calculated_velocity, now): if calculated_velocity is None: return None current_velocity = calculated_velocity if current_velocity.magnitude() < 0.09: return Vector2D(0, 0) if current_velocity.magnitude() < 0.14: return current_velocity * 0.5 avg_magnitude = current_velocity.magnitude() * 1.4 avg_direction_delta = 0 total_weight = 1.4 previous_time = now points_used = 0 for i, velocity_and_time in enumerate(self.velocity_history.list): velocity = velocity_and_time[0] time = velocity_and_time[1] if velocity.magnitude() < 0.05: break weight = max(1.0, (1.4 - (i + 1) * 0.1)) time_delta = previous_time - time projected_velocity: Vector2D = velocity.decayed( BALL_DECAY, now - time) angle_delta = smallest_angle_difference( from_angle=current_velocity.direction(), to_angle=projected_velocity.direction()) speed_delta = projected_velocity.magnitude( ) - current_velocity.magnitude() MAX_ANGLE_DELTA = 8 MAX_SPEED_DELTA = 0.3 MAX_TIME_DELTA = 7 if abs(angle_delta) > MAX_ANGLE_DELTA or abs( speed_delta ) > MAX_SPEED_DELTA or time_delta > MAX_TIME_DELTA: ##print("DELTA TOO BIG. Angle: ", angle_delta, "| Speed:", speed_delta, "time delta", time_delta) break avg_magnitude += projected_velocity.magnitude() * weight avg_direction_delta += angle_delta * weight total_weight += weight points_used += 1 avg_magnitude /= total_weight avg_direction_delta /= total_weight avg_direction = (current_velocity.direction() + avg_direction_delta) % 360 final_projection = Vector2D.velocity_to_xy(velocity=avg_magnitude, degrees=avg_direction) """print("HISTORY (used {0}): ".format(points_used), list(map(lambda v: v[0].world_direction(), self.velocity_history.list))) print("HISTORY (used {0}): ".format(points_used), list(map(lambda v: v[0].magnitude(), self.velocity_history.list))) print("AVERAGE vector:", final_projection, "| angle: ", final_projection.world_direction(), "| speed:", final_projection.magnitude()) """ return final_projection
def test_2d(self): point = Vector2D(1, 1) point += Vector2D(2, 2) self.assertEqual(point, Vector2D(3, 3)) self.assertEqual(point.length(), math.sqrt(18)) point = point.set_length(math.sqrt(2)) self.assertEqual(point, Vector2D(1, 1))
def __init__(self, bot_id, state, params=None): super(TPressureCooker, self).__init__(bot_id, state, params) self.bot_id = bot_id self.ballPos = Vector2D(int(state.ballPos.x), int(state.ballPos.y)) self.botPos = Vector2D(int(state.homePos[self.bot_id].x), int(state.homePos[self.bot_id].y)) self.sParams = skills_union.SParam()
def ball_moving_towards_our_goal(state): ballPos = Vector2D(state.ballPos.x, state.ballPos.y) ballvel = Vector2D(state.ballvel.x, state.ballvel.y) if ballvel.absSq(ballvel) > 0.1: ball_movement = Line(ballPos, ballPos + ballvel) ptA = Vector2D(-HALF_FIELD_MAXX, DBOX_HEIGHT) ptB = Vector2D(-HALF_FIELD_MAXX, -DBOX_HEIGHT) defend_line = Line(point1=ptA,point2=ptB) opponent_aim = Line.intersection_with_line(ball_movement) if opponent_aim.y > -DBOX_HEIGHT and opponent_aim.y < DBOX_HEIGHT: return True return False
def primary_threat(self, state, threat_bot): thresh = 100000.0 threat = -1 away_in_our_side = [] dist_list = [] angle_diff_list = [] angle_diff_list_ball = [] #calculate bot_id of opponent on our goalie side #threat_bot = threat_with_ball(state) ball_dir_in_goal, ball_vel_angle = self.ball_velocity_direction(state) #print("threat" ,threat_bot) #print("ball vle angle", ball_vel_angle) if threat_bot is not -1: threatPos = Vector2D(int(state.awayPos[threat_bot].x), int(state.awayPos[threat_bot].y)) for away_bot in xrange(len(state.awayPos)): #print("chutiya",threat_bot,away_bot) if away_bot is threat_bot: continue #print("chutiya2",threat_bot,away_bot) angle_diff = fabs(state.awayPos[threat_bot].theta - state.awayPos[away_bot].theta) angle_diff_list.append([away_bot, exp(-1.0 * angle_diff / pi)]) dist = threatPos.dist( Vector2D(int(state.awayPos[away_bot].x), int(state.awayPos[away_bot].y))) dist_list.append([away_bot, exp(-1 * dist / HALF_FIELD_MAXY)]) if ball_vel_angle: angle_diff_ball = fabs(ball_vel_angle - state.awayPos[away_bot].theta) else: angle_diff_ball = inf angle_diff_list_ball.append( [away_bot, exp(-1.0 * angle_diff_ball / pi)]) #exp(-1.0*angle_diff_ball/ pi) scores = [] weights = [0.6, 0.9, 0.8] # print("angle ",angle_diff_list) #print(threat_bot,"grggrgtr") for i in xrange(len(state.awayPos) - 1): sc = angle_diff_list[i][1] * weights[0] + dist_list[i][ 1] * weights[1] + angle_diff_list_ball[i][1] * weights[2] scores.append([angle_diff_list[i][0], sc]) scores.sort(key=lambda x: x[1], reverse=True) #print("pThreat ",scores) return scores[0][0] else: return -1
def shape(self): #copied from Ship.shape() # h = self.heading # hp = h.perp() # p1 = self.position + h * 0.75 # p2 = self.position + hp * 0.25 # p3 = self.position - hp * 0.25 # return [p1,p2,p3] d = 0.25 p1 = self.position + Vector2D(d, d) #movingbody; just a bit bigger. p2 = self.position + Vector2D(-d, d) p3 = self.position + Vector2D(-d, -d) p4 = self.position + Vector2D(d, -d) return [p1, p2, p3, p4]
def opponent_bot_with_ball(state): ballPos = Vector2D(state.ballPos.x, state.ballPos.y) closest_bot = None distance = 999999 for opp_id, awayPos in enumerate(state.awayPos): opp_pos = Vector2D(awayPos.x, awayPos.y) dist = opp_pos.dist(ballPos) if dist < distance: distance = dist closest_bot = opp_id if closest_bot is not None: if kub_has_ball(state, closest_bot, is_opponent = True): return closest_bot return None
def secondary_threat(self, state, vec, primary_threat_bot=-1): away_in_our_side = [] home_in_our_side = [] Upper_limit = Vector2D(-HALF_FIELD_MAXX, OUR_GOAL_MAXY / 1.2 + BOT_BALL_THRESH) Lower_limit = Vector2D(-HALF_FIELD_MAXX, OUR_GOAL_MINY / 1.2 - BOT_BALL_THRESH) #our bots on our side for home_bot_id in xrange(len(state.homeDetected)): if state.homePos[home_bot_id].x < 0: home_in_our_side.append(home_bot_id) #opponents closer to our goalie side not the primary_threat for away_bot_id in xrange(len(state.awayDetected)): if state.awayPos[ away_bot_id].x < 0 and away_bot_id is not primary_threat_bot: away_in_our_side.append(away_bot_id) #calculate max open angle Max_Open_Angle = 0.0 secondary_threat_id = -1 for away_bot_id in away_in_our_side: OpenAngle = abs( self.angle_at_vextex(state.awayPos[away_bot_id], Upper_limit, Lower_limit)) for bots in away_in_our_side: if bots is not away_bot_id: if self.point_in_traingle(state.awayPos[away_bot_id], Upper_limit, Lower_limit, state.awayPos[bots]): temp_theta = 2 * asin(BOT_RADIUS / ((state.awayPos[away_bot_id] - state.awayPos[bots]).absSq())) OpenAngle -= temp_theta for bots in home_in_our_side: if self.point_in_traingle(state.awayPos[away_bot_id], Upper_limit, Lower_limit, state.homePos[bots]): temp_theta = 2 * asin(BOT_RADIUS / ((state.awayPos[away_bot_id] - state.homePos[bots]).absSq())) OpenAngle -= temp_theta if OpenAngle > Max_Open_Angle: Max_Open_Angle = OpenAngle secondary_threat_id = away_bot_id #return secondary_threat_id return secondary_threat_id
def generate(sw_boundary=Point2D(-25, -25), ne_boundary=Point2D(25, 25)): """ :type sw_boundary: Point2D :type ne_boundary: Point2D """ while True: problem = { 'pnt1': Point2D(random.randint(sw_boundary.x, ne_boundary.x), random.randint(sw_boundary.y, ne_boundary.y)) } while True: pnt2 = Point2D(random.randint(sw_boundary.x, ne_boundary.x), random.randint(sw_boundary.y, ne_boundary.y)) if problem['pnt1'].x != pnt2.x and problem['pnt1'].y != pnt2.y: problem['pnt2'] = pnt2 break while True: pnt = Point2D(random.randint(sw_boundary.x, ne_boundary.x), random.randint(sw_boundary.y, ne_boundary.y)) if not on_line(pnt, problem['pnt1'], problem['pnt2']): problem['pnt'] = pnt break for _i in range(50): v = Vector2D(random.randint(-10, 10), random.randint(-10, 10)) if solve(problem['pnt'], problem['pnt1'], problem['pnt2'], v)['does_hit'] \ and v.x != 0 and v.y != 0: problem['vec'] = v return problem
def __init__(self, world): position0 = Point2D() velocity0 = Vector2D(0.0, 0.0) MovingBody.__init__(self, position0, velocity0, world) self.speed = 0.0 self.angle = 90.0 self.impulse = 0
def __init__(self,world): dy = 1.0 dx = random.uniform(-3.0,3.0) self.heading = Vector2D(dx,dy) offset = -self.START_Y position = world.bounds.point_at(random.random(), (1.0+offset)/2.0) Agent.__init__(self,position,world)
def isComplete(self, state): botpos = Vector2D(int(state.homePos[self.bot_id].x), int(state.homePos[self.bot_id].y)) ballpos = Vector2D(int(state.ballPos.x), int(state.ballPos.y)) dis_from_point = math.sqrt( math.pow(ballpos.x - botpos.x, 2) + math.pow(ballpos.y - botpos.y, 2)) angle = ballpos.normalizeAngle( ballpos.angle(botpos) - (state.homePos[botID].theta)) if (dis_from_point < 3 * BOT_POINT_THRESH) and (math.fabs(angle) < 0.2): return True else: return False '''
def __init__(self, position0, world): self.INITIAL_SPEED = self.START_SPEED * (60.0 / world.FPS) self.TOO_SLOW = self.INITIAL_SPEED / 20.0 self.SLOW_DOWN_BY = 0.2 self.SLOWDOWN = self.SLOW_DOWN_BY * (60.0 / world.FPS) #weird issues velocity0 = Vector2D.random() * self.INITIAL_SPEED MovingBody.__init__(self, position0, velocity0, world)
def __init__(self, p0, world, radius, lifetime): MovingBody.__init__(self, p0, Vector2D(), world) self.COLLISION_DAMAGE = Flare.COLLISION_DAMAGE * (60.0 / self.world.FPS) self.radius = radius self.lifetime = lifetime self.has_existed = 0
def steer(self): if not self.wrecked: t_part = self.get_heading() * self.ACCELERATION * self.thrust b_part = self.velocity.direction( ) * -1.0 * self.ACCELERATION * self.braking return t_part + b_part else: return Vector2D()
def makeGuns(self): #should be pretty self explanatory I hope. for i in range(-20, 40, 20): self.cannons.append( Launcher(Point2D(float(i), self.wallbounds.ymin), Vector2D(0.0, 1.0), self)) self.cannons.append( Launcher(Point2D(float(i), self.wallbounds.ymax), Vector2D(0.0, -1.0), self)) for k in range(3): kr = (k - 1) * 15 self.cannons.append( Launcher(Point2D(self.wallbounds.xmin, float(kr)), Vector2D(1.0, 0.0), self)) self.cannons.append( Launcher(Point2D(self.wallbounds.xmax, float(kr)), Vector2D(-1.0, 0.0), self))
def goalKeeper_callback(state): global pub, goalie_tac, cur_goalie if goalie_tac == None: cur_goalie = state.our_goalie goalie_tac = TGoalie.TGoalie(cur_goalie, state) if cur_goalie != state.our_goalie: cur_goalie_pos = Vector2D(state.homePos[cur_goalie].x, state.homePos[cur_goalie].y) new_goalie_pos = Vector2D(state.homePos[state.our_goalie].x, state.homePos[state.our_goalie].y) if (cur_goalie_pos.dist(new_goalie_pos) < 2.5 * BOT_RADIUS): goalie_tac.execute(state, pub) return cur_goalie = state.our_goalie goalie_tac = TGoalie.TGoalie(cur_goalie, state) goalie_tac.execute(state, pub) print("goalie : ", cur_goalie)
def shape(self): pacShape = [] pacShape.append(self.position + Vector2D(-.25, -.5)) pacShape.append(self.position + Vector2D(.25, -.5)) pacShape.append(self.position + Vector2D(.5, -.25)) pacShape.append(self.position + Vector2D(.5, .25)) pacShape.append(self.position + Vector2D(.25, .5)) pacShape.append(self.position + Vector2D(-.25, .5)) pacShape.append(self.position + Vector2D(-.5, .25)) pacShape.append(self.position + Vector2D(-.5, -.25)) return pacShape
def get_lock(self, t_pos): lock = None pos_locks = [ s for s in self.world.agents if (isinstance(s, Ship) and (s != self.source)) ] for pos in pos_locks: if lock != None: if ((pos.position - t_pos).magnitude() < (lock.position - t_pos).magnitude()): lock = pos else: if (pos.position - t_pos).magnitude() < 5: lock = pos if lock == None: lock = MovingBody( t_pos + Vector2D(), Vector2D(), self.world ) #Build a special class for a missile locked onto space? Or should it lock onto the cursor? Or what? return lock
def shape(self): points = [] to_make = 20 made = 0 while made < to_make: angle = (360 * made / to_make) * math.pi / 180.0 vec = Vector2D(math.cos(angle), math.sin(angle)) points.append(self.position + vec * float(self.radius)) made += 1 return points
def closest_opponent(state, position): p = position closest_bot, closest_dist = float("inf") for opp_id, awayPos in enumerate(state.awayPos): opp_pos = Vector2D(awayPos.x, awayPos.y) dist = opp_pos.dist(p) if dist < closest_dist: closest_dist = dist closest_bot = opp_id return closest_bot
def __init__(self, position, color, world): #Actually the initialization for all of my specific pickups is the same, it's just #their effects are different. I would have loved to better integrate this system #with the timer in the main KarlGame file, but I haven't the time. I once dreamed of #pickups that would make the character smaller/bigger, or reverse the arrow key directions #so pushing up means going down. ACtually those wouldn't be so hard to do, just the #integration into the main game is kinda putting me off it. self.world = world self.world.pickups.append(self) self.position = position corners = [ self.position + Vector2D(-0.5, 0.5), self.position - Vector2D(-0.5, 0.5) ] pts = self.world.worldToPixel(corners) self.selfID = self.world.canvas.create_rectangle(pts, fill=color, width=0, tags='Pickup')
def threat_with_ball(self, state): threat = -1 away_in_our_side_with_ball = [] ballPos = Vector2D(int(state.ballPos.x), int(state.ballPos.y)) for away_bot_id in xrange(len(state.awayPos)): if state.awayPos[away_bot_id].x < 0 and ballPos.dist( state.awayPos[away_bot_id]) <= DRIBBLER_BALL_THRESH: threat = away_bot_id min_dist = inf if threat is -1: ballPos = Vector2D(int(state.ballPos.x), int(state.ballPos.y)) for away_bot in xrange(len(state.awayPos)): dist = ballPos.dist( Vector2D(int(state.awayPos[away_bot].x), int(state.awayPos[away_bot].y))) if dist < min_dist: min_dist = dist threat = away_bot #if min_dist < BOT_BALL_DIST_THRESH: return threat, min_dist
def ball_velocity_direction(self, state): ballVel = Vector2D(int(state.ballVel.x), int(state.ballVel.y)) ballPos = Vector2D(int(state.ballPos.x), int(state.ballPos.y)) Upper_limit = Vector2D(-HALF_FIELD_MAXX, int(OUR_GOAL_MAXY / 2 + BOT_BALL_THRESH)) Lower_limit = Vector2D(-HALF_FIELD_MAXX, int(OUR_GOAL_MINY / 2 - BOT_BALL_THRESH)) alpha_1 = atan( (Upper_limit.y - ballPos.y) / (ballPos.x - Upper_limit.x)) alpha_2 = atan( (Lower_limit.y - ballPos.y) / (ballPos.x - Lower_limit.x)) if ballVel.x < 0 or 1: try: ball_vel_angle = atan(state.ballVel.y * -1 / state.ballVel.x) except: if state.ballVel.y < 0: ball_vel_angle = pi / 2 elif state.ballVel.y > 0: ball_vel_angle = pi * -0.5 else: ball_vel_angle = 0 else: return False, inf #deciding the direction of the ball's velocity if ballVel.y > 0: if (ball_vel_angle > alpha_2 and ball_vel_angle < alpha_1): return True, ball_vel_angle else: return False, ball_vel_angle else: if (abs(ball_vel_angle) > abs(alpha_1) and abs(ball_vel_angle) < abs(alpha_2)): return True, ball_vel_angle else: return False, ball_vel_angle
def intersection_with_line(self, line2): if not isinstance(line, line2): raise ValueError("Expected Line instance, got %s" %type(line2).__name__) c1 = self.point.y - self.slope * self.point.x c2 = line2.point.y - line2.slope * line2.point.x m1 = self.slope m2 = line2.slope P = Vector2D() try: P.x = (c2 - c1) / (m1 - m2) P.y = (m1 * c2 - m2 * c1) / (m1 - m2) except: return None
def intersection_with_line(self, line): if not isinstance(line, Line): raise ValueError("Expected instance of type Line, got %s" %type(line).__name__) if not self.if_intersect_with_line(line): raise ValueError("Line and Circle doesn't intersect") C = self.center R = self.radius L = line theta = L.slope M = L.nearest_point_on_line(C) print(M.x,M.y) d = L.distance_from_point(C) r = math.sqrt(R**2 - d**2) print(r) # A = Vector2D(M.x + r * math.cos(theta), M.y + r * math.sin(theta)) # B = Vector2D(M.x - r * math.cos(theta), M.y - r * math.sin(theta)) A, B = Vector2D(), Vector2D() A.x = float(M.x + r * math.cos(theta)) A.y = float(M.y + r * math.sin(theta)) B.x = float(M.x - r * math.cos(theta)) B.y = float(M.y - r * math.sin(theta)) return A, B
def target_shapes_and_colors(self): # def get_heading(self): # angle = self.angle * math.pi / 180.0 # return Vector2D(math.cos(angle), math.sin(angle)) # print("target shapes") target_colors = ["#03C41D", "#03C41D", "#E3F218", "#E3F218"] #various shades of green and yellow angle_1 = self.target_angle_1 * math.pi / 180.0 angle_2 = self.target_angle_2 * math.pi / 180.0 vec_1 = Vector2D(math.cos(angle_1), math.sin(angle_1)) vec_2 = Vector2D(math.cos(angle_2), math.sin(angle_2)) vecs = [vec_1, vec_1 * (-1.0), vec_2, vec_2 * (-1.0)] shapes = [] for i in range(len(vecs)): v = vecs[i] h = v.perp() p1 = self.mouse_position + v * 0.5 #numbers are determined arbitrarily p2 = self.mouse_position + v * 1.0 + h * 0.2 p3 = self.mouse_position + v * 1.0 - h * 0.2 #forgot a minus sign here - that was the error earlier, I think shapes.append(([p1, p2, p3], target_colors[i])) return shapes
def make_shape(self): angle = 0.0 dA = 2.0 * math.pi / 15.0 center = Point2D(0.0, 0.0) self.polygon = [] for i in range(15): if i % 3 == 0 and random.random() < 0.2: r = self.radius / 2.0 + random.random() * 0.25 else: r = self.radius - random.random() * 0.25 dx = math.cos(angle) dy = math.sin(angle) angle += dA offset = Vector2D(dx, dy) * r self.polygon.append(offset)
def projection_on_line(self, point, theta = math.pi/2): ######################## ########### change fucntion to find projection on any angle ######################## if not isinstance(point, Vector2D): raise ValueError("Expected Vector2D, got %s" %type(point).__name__) p = point angle = math.atan(self.slope) - theta p = point a = self.slope b = -1 c = self.point.y - self.slope * self.point.x closest_p = Vector2D() closest_p.x = float((b * (b * p.x - a * p.y) - a * c) / (a**2 + b**2)) closest_p.y = float((a * (-b * p.x + a * p.y) - b * c) / (a**2 + b**2)) return closest_p
def execute(self, state, pub, opp_bot): p_threat = opp_bot p_threat_pos = Vector2D(int(state.awayPos[p_threat].x), int(state.awayPos[p_threat].y)) x = p_threat_pos.x + DISTANCE_ORIENTATION * cos( state.awayPos[p_threat].theta) y = p_threat_pos.y + DISTANCE_ORIENTATION * sin( state.awayPos[p_threat].theta) self.sParams.GoToPointP.x = x self.sParams.GoToPointP.y = y self.sParams.GoToPointP.finalslope = self.botPos.normalizeAngle( state.awayPos[p_threat].theta + pi) sGoToPoint.execute(self.sParams, state, self.bot_id, pub)