Skip to content

Instantly share code, notes, and snippets.

@ifserge
Created January 16, 2020 09:15
Show Gist options
  • Save ifserge/3ce107874f4f1c07fa41830fc4a7f6da to your computer and use it in GitHub Desktop.
Save ifserge/3ce107874f4f1c07fa41830fc4a7f6da to your computer and use it in GitHub Desktop.
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