Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General behavioural adjustments #16

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base/bhv_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def execute(self, agent: 'PlayerAgent'):
continue
for c in range(1, 40):
dribble_pos = ball_pos + Vector2D.polar2vector(c * dribble_speed_etimate, dribble_angle_estimate)
turn_cycle = Tools.predict_player_turn_cycle(tm.player_type(), tm.body(), tm.vel().r(), tm.pos().dist(dribble_pos), (dribble_pos - tm.pos()).th(), 0.2, False)
turn_cycle = Tools.predict_player_turn_cycle(tm.player_type(), tm.body(), tm.vel().r(), tm.pos().dist(dribble_pos) * 2, (dribble_pos - tm.pos()).th(), 0.2, False)
tm_cycle = tm.player_type().cycles_to_reach_distance(tm.inertia_point(opp_min).dist(dribble_pos)) + turn_cycle
if tm_cycle <= opp_min + c:
if tm_cycle < block_cycle:
Expand Down
11 changes: 6 additions & 5 deletions base/bhv_kick.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@ def execute(self, agent: 'PlayerAgent'):
'shoot' + 'to ' + shoot_candidate.target_point.__str__() + ' ' + str(shoot_candidate.first_ball_speed))
SmartKick(shoot_candidate.target_point, shoot_candidate.first_ball_speed,
shoot_candidate.first_ball_speed - 1, 3).execute(agent)
agent.set_neck_action(NeckScanPlayers())
return True
else:
action_candidates: List[KickAction] = []

action_candidates += BhvPassGen().generator(wm)
action_candidates += BhvDribbleGen().generator(wm)

dribbles = BhvDribbleGen().generator(wm)
if dribbles is not None:
action_candidates += BhvDribbleGen().generator(wm)

if len(action_candidates) == 0:
return self.no_candidate_action(agent)
return True

best_action: KickAction = max(action_candidates)

Expand All @@ -54,7 +57,6 @@ def execute(self, agent: 'PlayerAgent'):
agent.effector().queued_next_ball_pos(),
agent.effector().queued_next_ball_vel()))

agent.set_neck_action(NeckScanPlayers())
return True

def no_candidate_action(self, agent: 'PlayerAgent'):
Expand All @@ -69,5 +71,4 @@ def no_candidate_action(self, agent: 'PlayerAgent'):
log.debug_client().add_message(best_action.type.value + 'to ' + best_action.target_ball_pos.__str__() + ' ' + str(best_action.start_ball_speed))
SmartKick(target, best_action.start_ball_speed, best_action.start_ball_speed - 2.0, 2).execute(agent)

agent.set_neck_action(NeckScanPlayers())
return HoldBall().execute(agent)
13 changes: 11 additions & 2 deletions base/bhv_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,22 @@ def execute(self, agent: 'PlayerAgent'):
agent.set_neck_action(NeckTurnToBall())
return True

if opp_min < min(tm_min, self_min):
if opp_min < min(tm_min, self_min) and agent.world().self().unum() != 1:
if Bhv_Block().execute(agent):
agent.set_neck_action(NeckTurnToBall())
return True
st = StrategyFormation().i()
target = st.get_pos(agent.world().self().unum())

if agent.world().self().unum() == 1:
target = Vector2D(target.x(), wm.ball().pos().y() / 3)

if target.x() > wm.ball().pos().x():
target = Vector2D(wm.ball().pos().x() + 7, target.y())

#if wm.ball().pos().x() > 15:
# target = Vector2D(target.x() + 20, target.y())

log.debug_client().set_target(target)
log.debug_client().add_message('bhv_move')

Expand All @@ -69,7 +78,7 @@ def execute(self, agent: 'PlayerAgent'):
dist_thr = 1.0

if GoToPoint(target, dist_thr, dash_power).execute(agent):
agent.set_neck_action(NeckTurnToBallOrScan())
agent.set_neck_action(NeckTurnToBall())
return True
return False

4 changes: 2 additions & 2 deletions base/formation_dt/setplay_our_formation.conf
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ Ball 0 0
3 -15.33 3.66
4 -9.29 -15.12
5 -10.84 13.69
6 -0.71 -0.36
6 -10.71 -0.36
7 0 -6.97
8 0.48 6.73
9 13.69 -20.13
10 10.73 24
11 16.08 0
11 -16.08 0
----- 1 -----
Ball -54 0
1 -50 -0
Expand Down
7 changes: 5 additions & 2 deletions base/generator_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ def __init__(self):
self.min_opp_dist = 0.0

def calculate_min_opp_dist(self, wm: 'WorldModel' = None):
if wm is None or wm.opponents() is None or len(wm.opponents()) == 0:
try:
if wm is None or wm.opponents() is None or len(wm.opponents()) == 0:
return 0.0
return min([opp.pos().dist(self.target_ball_pos) for opp in wm.opponents() if opp is not None and opp.unum() > 0])
except:
return 0.0
return min([opp.pos().dist(self.target_ball_pos) for opp in wm.opponents() if opp is not None and opp.unum() > 0])

def evaluate(self, wm: 'WorldModel' = None):
self.min_opp_dist = self.calculate_min_opp_dist(wm)
Expand Down
8 changes: 6 additions & 2 deletions base/generator_dribble.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
class BhvDribbleGen(BhvKickGen):
def generator(self, wm: 'WorldModel'):
global max_dribble_time

if wm.self().pos().x() > 40:
return None

start_time = time.time()
self.generate_simple_dribble(wm)

Expand Down Expand Up @@ -98,7 +102,7 @@ def simulate_kick_turns_dashes(self, wm: 'WorldModel', dash_angle, n_turn):
# trap_rel = Vector2D.polar2vector(ptype.playerSize() + ptype.kickableMargin() * 0.2 + SP.ball_size(), dash_angle)
trap_rel = Vector2D.polar2vector(ptype.player_size() + ptype.kickable_margin() * 0.2 + 0, dash_angle)

max_x = sp.pitch_half_length() - 1.0
max_x = sp.pitch_half_length() - 5.0
max_y = sp.pitch_half_width() - 1.0

for n_dash in range(max_dash, min_dash - 1, -1):
Expand Down Expand Up @@ -227,7 +231,7 @@ def check_opponent(self, wm: 'WorldModel', ball_trap_pos: Vector2D, dribble_step

target_dist = opp_pos.dist(ball_trap_pos)

if target_dist - control_area < 0.001:
if target_dist - control_area < 0.01:
if debug_dribble:
log.sw_log().dribble().add_text( "###OPP {} Catch, ball will be in his body".format(o))
return False
Expand Down
114 changes: 82 additions & 32 deletions base/generator_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def generator(self, wm: 'WorldModel'):
# and r.pos().x() < self.best_pass.target_ball_pos.x() - 5:
# break
self.generate_direct_pass(wm, r)
self.generate_lead_pass(wm, r)
self.generate_through_pass(wm, r)
#self.generate_lead_pass(wm, r)
#self.generate_through_pass(wm, r)

if debug_pass:
for candid in self.debug_list:
Expand Down Expand Up @@ -83,22 +83,22 @@ def update_receivers(self, wm: 'WorldModel'):

def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'):
sp = SP.i()
min_receive_step = 3
max_direct_pass_dist = 0.8 * smath.inertia_final_distance(sp.ball_speed_max(), sp.ball_decay())
max_receive_ball_speed = sp.ball_speed_max() * pow(sp.ball_decay(), min_receive_step)
min_direct_pass_dist = receiver.player_type().kickable_area() * 2.2
if receiver.pos().x() > sp.pitch_half_length() - 1.5 \
or receiver.pos().x() < -sp.pitch_half_length() + 5.0 \
or receiver.pos().abs_y() > sp.pitch_half_width() - 1.5:
if debug_pass:
log.sw_log().pass_().add_text( '#DPass to {} {}, out of field'.format(receiver.unum(), receiver.pos()))
return
min_receive_step = 1
max_direct_pass_dist = smath.inertia_final_distance(sp.ball_speed_max(), sp.ball_decay())
max_receive_ball_speed = 3 * sp.ball_speed_max() * pow(sp.ball_decay(), min_receive_step)
min_direct_pass_dist = 0
#if receiver.pos().x() > sp.pitch_half_length() - 1.5 \
# or receiver.pos().x() < -sp.pitch_half_length() + 5.0 \
# or receiver.pos().abs_y() > sp.pitch_half_width() - 1.5:
# if debug_pass:
# log.sw_log().pass_().add_text( '#DPass to {} {}, out of field'.format(receiver.unum(), receiver.pos()))
# return
# TODO sp.ourTeamGoalPos()
if receiver.pos().x() < wm.ball().pos().x() + 1.0 \
and receiver.pos().dist2(Vector2D(-52.5, 0)) < pow(18.0, 2):
if debug_pass:
log.sw_log().pass_().add_text( '#DPass to {} {}, danger near goal'.format(receiver.unum(), receiver.pos()))
return
#if receiver.pos().x() < wm.ball().pos().x() + 1.0 \
# and receiver.pos().dist2(Vector2D(-52.5, 0)) < pow(18.0, 2):
# if debug_pass:
# log.sw_log().pass_().add_text( '#DPass to {} {}, danger near goal'.format(receiver.unum(), receiver.pos()))
# return

ptype = receiver.player_type()
max_ball_speed = wm.self().kick_rate() * sp.max_power()
Expand All @@ -111,18 +111,18 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'):
receive_point = ptype.inertiaFinalPoint(receiver.pos(), receiver.vel())
ball_move_dist = wm.ball().pos().dist(receive_point)

if ball_move_dist < min_direct_pass_dist or max_direct_pass_dist < ball_move_dist:
if debug_pass:
log.sw_log().pass_().add_text( '#DPass to {} {}, far or close'.format(receiver.unum(), receiver.pos()))
return
#if ball_move_dist < min_direct_pass_dist or max_direct_pass_dist < ball_move_dist:
# if debug_pass:
# log.sw_log().pass_().add_text( '#DPass to {} {}, far or close'.format(receiver.unum(), receiver.pos()))
# return

if wm.game_mode().type().is_goal_kick() \
and receive_point.x() < sp.our_penalty_area_line_x() + 1.0 \
and receive_point.abs_y() < sp.penalty_area_half_width() + 1.0:
if debug_pass:
log.sw_log().pass_().add_text(
'#DPass to {} {}, in penalty area in goal kick mode'.format(receiver.unum(), receiver.pos()))
return
#if wm.game_mode().type().is_goal_kick() \
# and receive_point.x() < sp.our_penalty_area_line_x() + 1.0 \
# and receive_point.abs_y() < sp.penalty_area_half_width() + 1.0:
# if debug_pass:
# log.sw_log().pass_().add_text(
# '#DPass to {} {}, in penalty area in goal kick mode'.format(receiver.unum(), receiver.pos()))
# return

max_receive_ball_speed = min(max_receive_ball_speed, ptype.kickable_area() + (
sp.max_dash_power() * ptype.dash_power_rate() * ptype.effort_max()) * 1.8)
Expand All @@ -133,7 +133,7 @@ def generate_direct_pass(self, wm: 'WorldModel', receiver: 'PlayerObject'):
min_ball_step = sp.ball_move_step(sp.ball_speed_max(), ball_move_dist)
# TODO Penalty step
start_step = max(max(min_receive_step, min_ball_step), 0)
max_step = start_step + 2
max_step = start_step + 30
log.sw_log().pass_().add_text( '#DPass to {} {}'.format(receiver.unum(), receiver.pos()))
self.create_pass(wm, receiver, receive_point,
start_step, max_step, min_ball_speed,
Expand Down Expand Up @@ -472,27 +472,77 @@ def create_pass(self, wm: 'WorldModel', receiver, receive_point: Vector2D,
o_step,
max_step))
self.debug_list.append((self.index, receive_point, True))

candidate = KickAction()
candidate.type = KickActionType.Pass
candidate.start_ball_pos = wm.ball().pos()
candidate.target_ball_pos = receive_point
candidate.target_unum = receiver.unum()
candidate.start_ball_speed = first_ball_speed
candidate.start_ball_speed = max_first_ball_speed
candidate.evaluate(wm)
candidate.eval += 5
opp_min = wm.intercept_table().opponent_reach_cycle()
if opp_min <= 5:
candidate.eval += 30
else:
candidate.eval -= 10

if candidate.target_ball_pos.abs_y() <= 5:
candidate.eval += 30

if candidate.target_ball_pos.x() <= -50:
candidate.eval -= 1000

if wm.game_mode() != GameModeType.PlayOn:
candidate.eval += 100

if wm.self().pos().abs_x() > 40:
candidate.eval += 30

if candidate.target_ball_pos.abs_x() <= 30 and candidate.target_ball_pos.x() > candidate.start_ball_pos.x():
candidate.eval += 10
if candidate.target_ball_pos.x() >= 40 and candidate.target_ball_pos.x() < candidate.start_ball_pos.x():
candidate.eval += 30
"""

if wm.game_mode() != GameModeType.PlayOn:
candidate.eval += 100

if candidate.start_ball_pos.x() >= 30 and candidate.target_ball_pos.abs_y() <= 5:
candidate.eval += 60

if candidate.target_ball_pos.abs_y() >= 20:
candidate.eval -= 30

if candidate.target_ball_pos.abs_x() <= 30 and candidate.target_ball_pos.x() > candidate.start_ball_pos.x():
candidate.eval += 10
if candidate.target_ball_pos.x() >= 40 and candidate.target_ball_pos.x() < candidate.start_ball_pos.x():
candidate.eval += 30

opp_min = wm.intercept_table().opponent_reach_cycle()
if opp_min <= 5:
candidate.eval += 30
else:
candidate.eval -= 10

if wm.self().pos().abs_x() > 40:
candidate.eval += 30
"""
self.candidates.append(candidate)

if self.best_pass is None or candidate.eval > self.best_pass.eval:
self.best_pass = candidate

find_another_pass = False
find_another_pass = True
if not find_another_pass:
break

"""
if o_step <= step + 3:
break

if min_step + 3 <= step:
break
"""

def predict_opponents_reach_step(self, wm: 'WorldModel', first_ball_pos: Vector2D, first_ball_speed,
ball_move_angle: AngleDeg, receive_point: Vector2D, max_cycle, description):
Expand Down
23 changes: 15 additions & 8 deletions base/generator_shoot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ def generator(self, wm: 'WorldModel') -> ShootAction:
target_point = Vector2D(goal_l.x(), goal_l.y() + dist_step * i)
log.sw_log().shoot().add_text( "#shoot {} to {}".format(self.total_count, target_point))
self.create_shoot(wm, target_point)
self.create_shoot(wm, Vector2D(target_point.x(), target_point.y() + 2))
self.create_shoot(wm, Vector2D(target_point.x(), target_point.y() - 2))
if len(self.candidates) == 0:
return None

Expand All @@ -57,9 +59,12 @@ def generator(self, wm: 'WorldModel') -> ShootAction:
def create_shoot(self, wm: 'WorldModel', target_point: Vector2D):
ball_move_angle = (target_point - wm.ball().pos()).th()
goalie = wm.get_opponent_goalie()
if goalie is None or (goalie.unum() > 0 and 5 < goalie.pos_count() < 30):
#if goalie is None or (goalie.unum() > 0 and 5 < goalie.pos_count() < 30):
# TODO and wm.dirCount( ball_move_angle ) > 3
log.sw_log().shoot().add_text( "#shoot {} didnt see goalie".format(self.total_count))
# log.sw_log().shoot().add_text( "#shoot {} didnt see goalie".format(self.total_count))
# return

if wm.self().pos().abs_x() < 30 and wm.self().pos().x() > 0:
return

sp = SP.i()
Expand Down Expand Up @@ -99,9 +104,9 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed
ball_reach_step = int(
math.ceil(smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay())))

if ball_reach_step == -1:
log.sw_log().shoot().add_text( 'Cant arrive to target')
return False
#if ball_reach_step == -1:
# log.sw_log().shoot().add_text( 'Cant arrive to target')
# return False
log.sw_log().shoot().add_text( '{} {} {} {} {}'.format(first_ball_speed, ball_move_dist, sp.ball_decay(), smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay()), math.ceil(smath.calc_length_geom_series(first_ball_speed, ball_move_dist, sp.ball_decay()))))
course = ShootAction(self.total_count, target_point, first_ball_speed, ball_move_angle, ball_move_dist,
ball_reach_step)
Expand All @@ -117,6 +122,8 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed

for o in range(1, 12):
opp = wm.their_player(o)
if opp is None:
continue
if opp.unum() < 1:
log.sw_log().shoot().add_text( '## opp {} can not, unum')
continue
Expand All @@ -135,8 +142,8 @@ def check_shoot(self, wm: 'WorldModel', target_point: Vector2D, first_ball_speed
continue

if opp.goalie():
if self.maybe_goalie_catch(opp, course, wm):
return False
#if self.maybe_goalie_catch(opp, course, wm):
# return False
log.sw_log().shoot().add_text( '## opp {} can not, goalie catch')
continue

Expand Down Expand Up @@ -287,7 +294,7 @@ def evaluate_courses(self, wm: 'WorldModel'):
score += 100.0

goalie_rate = 1.0
if goalie.unum() > 0:
if goalie is not None and goalie.unum() > 0:
variance2 = 1.0 if it.goalie_never_reach else pow(10.0, 2)
angle_diff = (it.ball_move_angle - goalie_angle).abs()
goalie_rate = 1.0 - math.exp(-pow(angle_diff, 2) / (2.0 * variance2) )
Expand Down
6 changes: 3 additions & 3 deletions base/goalie_decision.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def decision(agent: 'PlayerAgent'):
SP = ServerParam.i()
wm = agent.world()

our_penalty = Rect2D(Vector2D(-SP.pitch_half_length(), -SP.penalty_area_half_width() + 1),
Size2D(SP.penalty_area_length() - 1, SP.penalty_area_width() - 2))
our_penalty = Rect2D(Vector2D(-SP.pitch_half_length(), -SP.penalty_area_half_width() - 5),
Size2D(SP.penalty_area_length() - 1, SP.penalty_area_width() - 5))

log.os_log().debug(f'########## gdc={wm.time().cycle()}')
log.os_log().debug(f'########## gd gmt={wm.game_mode().type()}')
Expand All @@ -44,7 +44,7 @@ def decision(agent: 'PlayerAgent'):
return False

if (wm.time().cycle() > wm.self().catch_time().cycle() + SP.catch_ban_cycle()
and wm.ball().dist_from_self() < SP.catchable_area() - 0.05
and wm.ball().dist_from_self() < SP.catchable_area() - 0.1
and our_penalty.contains(wm.ball().pos())):

agent.do_catch()
Expand Down
Loading