Created
January 16, 2020 09:15
-
-
Save ifserge/3ce107874f4f1c07fa41830fc4a7f6da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import model | |
import math | |
from model import WeaponType | |
class MyStrategy: | |
def __init__(self): | |
pass | |
def get_action(self, unit, game, debug): | |
#print(unit.size.x, unit.size.y) | |
def distance_sqr(a, b): | |
return (a.x - b.x) ** 2 + (a.y - b.y) ** 2 | |
nearest_enemy = min( | |
filter(lambda u: u.player_id != unit.player_id, game.units), | |
key=lambda u: distance_sqr(u.position, unit.position), | |
default=None) | |
nearest_ally = min( | |
filter(lambda u: (u.player_id == unit.player_id) and (u.id != unit.id), game.units), | |
key=lambda u: distance_sqr(u.position, unit.position), | |
default=None) | |
nearest_weapon = min( | |
filter(lambda box: isinstance( | |
box.item, model.Item.Weapon), game.loot_boxes), | |
key=lambda box: distance_sqr(box.position, unit.position), | |
default=None) | |
nearest_rocket = min( | |
filter(lambda box: isinstance( | |
box.item, model.Item.Weapon) and (box.item.weapon_type == WeaponType.ROCKET_LAUNCHER), game.loot_boxes), | |
key=lambda box: distance_sqr(box.position, unit.position), | |
default=None) | |
nearest_medical_pack = min( | |
filter(lambda box: isinstance( | |
box.item, model.Item.HealthPack), game.loot_boxes), | |
key=lambda box: distance_sqr(box.position, unit.position), | |
default=None) | |
#for b in game.bullets: | |
# print(b.weapon_type) | |
# print(b.velocity) | |
medical_pack_distance = None | |
enemy_medical_pack_distance = None | |
if nearest_medical_pack is not None: | |
medical_pack_distance = distance_sqr(nearest_medical_pack.position, unit.position) | |
enemy_medical_pack_distance = distance_sqr(nearest_medical_pack.position, nearest_enemy.position) | |
target_pos = unit.position | |
target_is_enemy = False | |
if (nearest_medical_pack is not None) and (unit.health < game.properties.unit_max_health * 0.6) and \ | |
(medical_pack_distance / (1e-6 + enemy_medical_pack_distance) < 1.05): | |
target_pos = nearest_medical_pack.position | |
elif (nearest_medical_pack is not None) and (unit.health < game.properties.unit_max_health * 0.3): | |
target_pos = nearest_medical_pack.position | |
elif ((unit.weapon is None) or (unit.weapon.magazine == 0)) and (nearest_weapon is not None): | |
target_pos = nearest_weapon.position | |
elif (unit.weapon is not None) and (not (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER)) and (nearest_rocket is not None) and (unit.health > game.properties.unit_max_health * 0.6): | |
target_pos = nearest_rocket.position | |
#debug.draw(model.CustomData.Log("Nearest rocket pos: {}".format(str(nearest_rocket.item)))) | |
elif nearest_enemy is not None: | |
target_pos = nearest_enemy.position | |
#debug.draw(model.CustomData.Log("Nearest enemy pos: {}".format(str(target_pos)))) | |
target_is_enemy = True | |
aim = model.Vec2Double(0, 0) | |
aim_x, aim_y = 0, 0 | |
#print(type(game.properties.unit_size), game.properties.unit_size) | |
if nearest_enemy is not None: | |
aim_x = nearest_enemy.position.x - unit.position.x | |
aim_y = nearest_enemy.position.y - unit.position.y - \ | |
math.copysign(0.3, nearest_enemy.position.y - unit.position.y) | |
aim = model.Vec2Double(aim_x, aim_y) | |
d = (aim_x ** 2.0 + aim_y ** 2.0) ** 0.5 | |
aim_x = aim_x / d * 20.0 | |
aim_y = aim_y / d * 20.0 | |
jump = target_pos.y > unit.position.y | |
ux, uy = int(unit.position.x), int(unit.position.y) | |
shoot_flag = True | |
y_thr = 0.5 | |
if (unit.weapon is not None) and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER): | |
y_thr = 0.3 | |
max_mnx = 2 | |
if ux <= 2: | |
max_mnx = 1 | |
max_plx = 2 | |
if ux >= len(game.level.tiles) - 2: | |
max_plx = 1 | |
if (aim.x < -0.5) & game.level.tiles[ux - 1][uy] == model.Tile.WALL: | |
shoot_flag = False | |
if (aim.x > 0.5) & game.level.tiles[ux + 1][uy] == model.Tile.WALL: | |
shoot_flag = False | |
if (aim.x > 0.5) & (aim.y > y_thr) & ((game.level.tiles[ux + 1][uy + 1] == model.Tile.WALL) | ( | |
game.level.tiles[ux + max_plx][uy + 1] == model.Tile.WALL)): | |
shoot_flag = False | |
if (aim.x > 0.5) & (aim.y < -y_thr) & ((game.level.tiles[ux + 1][uy - 1] == model.Tile.WALL) | ( | |
game.level.tiles[ux + max_plx][uy - 1] == model.Tile.WALL)): | |
shoot_flag = False | |
if (aim.x < -0.5) & (aim.y > y_thr) & ((game.level.tiles[ux - 1][uy + 1] == model.Tile.WALL) | ( | |
game.level.tiles[ux - max_mnx][uy + 1] == model.Tile.WALL)): | |
shoot_flag = False | |
if (aim.x < -0.5) & (aim.y < -y_thr) & ((game.level.tiles[ux - 1][uy - 1] == model.Tile.WALL) | ( | |
game.level.tiles[ux - max_mnx][uy - 1] == model.Tile.WALL)): | |
shoot_flag = False | |
if (unit.weapon is not None) and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER) and (aim.y < -y_thr) and ( | |
game.level.tiles[ux][uy - 1] == model.Tile.WALL): | |
shoot_flag = False | |
if (unit.weapon is not None): # and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER): | |
ux_ = unit.position.x | |
uy_ = unit.position.y + 0.9 | |
for ix in range(300): | |
uux = math.floor(ux_ + (ix+1.0) * aim_x * 0.01) | |
uuy = math.floor(uy_ + (ix+1.0) * aim_y * 0.01) | |
if nearest_ally is not None: | |
ddx = (nearest_ally.position.x + 0.45 - (ux_ + (ix + 1.0) * aim_x * 0.01)) ** 2 | |
ddy = (nearest_ally.position.y + 0.9 - (uy_ + (ix + 1.0) * aim_y * 0.01)) ** 2 | |
dd = (ddx + ddy) ** 0.5 | |
if dd < 1.04: | |
shoot_flag = False | |
break | |
if nearest_enemy is not None: | |
ddx = (nearest_enemy.position.x + 0.45 - (ux_ + (ix+1.0) * aim_x * 0.01)) ** 2 | |
ddy = (nearest_enemy.position.y + 0.9 - (uy_ + (ix+1.0) * aim_y * 0.01)) ** 2 | |
dd = (ddx + ddy) ** 0.5 | |
if dd < 1.3: | |
break | |
if (uux < len(game.level.tiles)) and (uux >= 0) and (uuy >= 0) and (uuy < len(game.level.tiles[0])) and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER): | |
if game.level.tiles[uux][uuy] == model.Tile.WALL: | |
shoot_flag = False | |
break | |
uux = math.floor(ux_ + (ix + 1.0) * aim_x * 0.01 + 0.5) | |
uuy = math.floor(uy_ + (ix + 1.0) * aim_y * 0.01 + 0.5) | |
if (uux < len(game.level.tiles)) and (uux >= 0) and (uuy >= 0) and (uuy < len(game.level.tiles[0])) and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER): | |
if game.level.tiles[uux][uuy] == model.Tile.WALL: | |
shoot_flag = False | |
break | |
uux = math.floor(ux_ + (ix + 1.0) * aim_x * 0.01) | |
uuy = math.floor(uy_ + (ix + 1.0) * aim_y * 0.01 + 0.5) | |
if (uux < len(game.level.tiles)) and (uux >= 0) and (uuy >= 0) and (uuy < len(game.level.tiles[0])) and (unit.weapon.typ == WeaponType.ROCKET_LAUNCHER): | |
if game.level.tiles[uux][uuy] == model.Tile.WALL: | |
shoot_flag = False | |
break | |
health_x = 4 | |
if unit.health < game.properties.unit_max_health * 0.81: | |
health_x = 10 | |
if (nearest_ally is not None) and (nearest_enemy is not None) and ( | |
distance_sqr(unit.position, nearest_enemy.position) > distance_sqr(nearest_ally.position, nearest_enemy.position)): | |
health_x += 4.9 | |
vel = target_pos.x - unit.position.x | |
if target_is_enemy and (math.fabs(target_pos.x - unit.position.x) >= health_x): | |
vel = target_pos.x - unit.position.x - math.copysign(health_x, target_pos.x - unit.position.x) | |
if math.fabs(target_pos.x - unit.position.x) < 10: | |
jump = True | |
elif target_is_enemy and (math.fabs(target_pos.x - unit.position.x) < health_x): | |
vel = -math.copysign(70, vel) | |
if math.fabs(target_pos.x - unit.position.x) < 10: | |
jump = True | |
elif math.fabs(vel) < 7: | |
vel = math.copysign(70, vel) | |
if vel > 0 and game.level.tiles[ux + 1][uy] == model.Tile.WALL: | |
jump = True | |
if vel < 0 and game.level.tiles[ux - 1][uy] == model.Tile.WALL: | |
jump = True | |
swap_weapon = False | |
nearest_rocket_distance = 1e9 | |
if nearest_rocket is not None: | |
nearest_rocket_distance = (nearest_rocket.position.x - unit.position.x) + \ | |
(nearest_rocket.position.y - unit.position.y) | |
if (unit.weapon is not None) and (unit.weapon.typ != model.WeaponType.ROCKET_LAUNCHER) and \ | |
(nearest_rocket is not None) and (nearest_rocket_distance < 0.5): | |
swap_weapon = True | |
reload_flag = False | |
if (unit.weapon is not None) and (unit.weapon.magazine == 0): | |
reload_flag = True | |
return model.UnitAction( | |
velocity=vel, | |
jump=jump, | |
jump_down=not jump, | |
aim=aim, | |
shoot=shoot_flag, | |
reload=reload_flag, | |
swap_weapon=swap_weapon, | |
plant_mine=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment