使用说明¶
opt 库是一个获取球场环境信息和控制坦克操控的库。里面涵盖非常丰富的角度距离等测量函数,坦克控制函数等。 你可以使用 opt.TANK 获取到当前所需要超控的坦克,使用 opt.BALL 获取球的信息。
注意,opt.TANK 应当在每一个 update 函数内调用,已获取当前属于此函数的坦克实例。
>>> def tank_update():
>>> opt.TANK # 获取到所要操控坦克的信息
>>> def tank1_update():
>>> opt.TANK # 获取到 tank1 的信息
>>> def tank2_update():
>>> opt.TANK # 获取到 tank2 的信息
以此类推,不同 function 中的 opt.TANK 将代表不同的坦克实例。 如果在函数 function 外使用 opt.TANK 将无法引用到正确的坦克实例。
比赛中规定,控制坦克唯一有效的方法是通过规定的坦克函数输出(前后,左右速度)来控制坦克的运动。举例:
>>> def tank_update():
>>> # 这里是你的 magic code
>>> vs, hs = 1, 0 # 这里是你此时决定要如何操控坦克的 前后,左右 速度
>>> return vs, hs
初赛只需要控制一辆坦克,所以函数名的 tank_update,而复赛需要控制多辆坦克,每个坦克有自己独立的函数名。
>>> def tank1_update():
>>> return 1, 0
>>> def tank2_update():
>>> return 1, 1
>>> ...
>>> def tank5_update():
>>> return 1, 1
坦克 前后,左右 速度的操控定义类似玩具汽车的操控手柄,分别有前后,左右两个操控杆。
vs:控制前后的力度。取值范围 [-1,+1], -1 为最大后退力度,1 为最大前进力度,0 保持不动
hs: 左转右转控制力度。取值范围 [-1,+1],-1 为最大左转角度,1 为最大右转角度,0 直行。注意!当 vs=0,没有前进动力的时候, hs 无论是什么值,无论转多厉害,坦克都在原地不动,都没有效果。
最终速度结果是 vs 和 hs 的叠加结果,类似于遥控汽车手柄的操作方式。
-
opt.
GROUND_WIDTH
¶ 球场东至西长度(米)
- Type
float
-
opt.
GROUND_HEIGHT
¶ 球场北至南长度(米)
- Type
float
-
opt.
TANK_WIDTH
¶ 坦克宽度(米)
- Type
float
-
opt.
TANK_LENGTH
¶ 坦克长度(米)
- Type
float
-
opt.
DOOR_WIDTH
¶ 球门宽度(米)
- Type
float
-
opt.
ENEMY_DOOR_LEFT
¶ 面朝我方球门时,对方球门左柱 x,y 坐标。获取方式 opt.ENEMY_DOOR_LEFT.x; opt.ENEMY_DOOR_LEFT.y
- Type
-
opt.
ENEMY_DOOR_RIGHT
¶ 面朝我方球门时,对方球门右柱 x,y 坐标。获取方式 opt.ENEMY_DOOR_RIGHT.x; opt.ENEMY_DOOR_RIGHT.y
- Type
-
class
opt.
Ball
(data_list)¶ 基类:
opt.Sprite
球的功能与属性。 使用 opt.BALL 调用实例。
-
i
¶ id
- Type
int
-
x
¶ x 坐标
- Type
float
-
y
¶ y 坐标
- Type
float
-
vx
¶ x 方向速度
- Type
float
-
vy
¶ y 方向速度
- Type
float
-
r
¶ 朝向的弧度信息,东方向为 0 度,北方向为 π/2,南方向是 -π/2
- Type
Radian
-
vr
¶ 角速度,弧度/秒
- Type
Radian, None
-
a
¶ 朝向的角度信息,东方向为 0 度,北方向为 90 度,南方向是 -90 度
- Type
Angle
-
property
angle
¶ 物体朝向角度,东边为 0 度,北为 90,南为 -90
- 返回
角度
- 返回类型
Angle
实际案例
>>> # opt.BALL.x, opt.BALL.y, opt.BALL.r = 0, 0, 1.5707963267948966 >>> print(opt.BALL.angle) 90
-
is_tank_in_range
(tank: opt.Sprite, r: float) → bool¶ 判断坦克是否在自己的 range 内
- 参数
tank (Tank) – 坦克
r (float) – range 范围
- 返回
True/False
实际案例
>>> # opt.BALL.x, opt.BALL.y = 0, 0 >>> # opt.TANK.x, opt.TANK.y = 1, 1 >>> print(opt.BALL.is_tank_in_range(opt.TANK, 2)) True
>>> print(opt.BALL.is_tank_in_range(opt.TANK, 1)) False
-
on_east_of
(tank: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定坦克的东边
- 参数
tank (Tank) – 选定坦克
offset (float) – 额外距离
- 返回
True/False
实际案例
>>> # opt.BALL.x, opt.BALL.y = 0, 0 >>> # opt.TANK.x, opt.TANK.y = 1, 0 >>> print(opt.BALL.on_east_of(opt.TANK)) False
-
on_north_of
(tank: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定坦克的北
- 参数
tank (Tank) – 选定坦克
offset (float) – 额外距离
- 返回
True/False
实际案例
>>> # opt.BALL.x, opt.BALL.y = 0, 0 >>> # opt.TANK.x, opt.TANK.y = 1, 0 >>> print(opt.BALL.on_north_of(opt.TANK)) False
-
on_south_of
(tank: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定坦克的南边
- 参数
tank (Tank) – 选定坦克
offset (float) – 额外距离
- 返回
True/False
实际案例
>>> # opt.BALL.x, opt.BALL.y = 0, 0 >>> # opt.TANK.x, opt.TANK.y = 1, 1 >>> print(opt.BALL.on_south_of(opt.TANK)) True
-
on_west_of
(tank: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定坦克的西边
- 参数
tank (Tank) – 选定坦克
offset (float) – 额外距离
- 返回
True/False
实际案例
>>> # opt.BALL.x, opt.BALL.y = 0, 0 >>> # opt.TANK.x, opt.TANK.y = 1, 0 >>> print(opt.BALL.on_west_of(opt.TANK)) True
>>> print(opt.BALL.on_west_of(opt.TANK, 2)) False
-
property
radian
¶ 物体朝向弧度,东边为 0 度,北为 π/2,南为 -π/2
- 返回
弧度
- 返回类型
Radian
实际案例
>>> # opt.BALL.x, opt.BALL.y, opt.BALL.r = 0, 0, 1.5707963267948966 >>> print(opt.BALL.radian) 1.5707963267948966
-
property
radian_velocity
¶ 角速度,单位为弧度/秒
- 返回
角速度
- 返回类型
Radian
-
property
radius
¶ 球的半径
- 返回
米
- 返回类型
float
-
-
class
opt.
Bullet
(data_list)¶ 基类:
opt.Sprite
坦克的子弹属性。 使用 opt.BULLET 调用实例。
-
property
angle
¶ 物体朝向角度,东边为 0 度,北为 90,南为 -90
- 返回
角度
- 返回类型
Angle
实际案例
>>> # opt.BULLET.x, opt.BULLET.y, opt.BULLET.r = 0, 0, 1.5707963267948966 >>> print(opt.BULLET.angle) 90
-
property
radian
¶ 物体朝向弧度,东边为 0 度,北为 π/2,南为 -π/2
- 返回
弧度
- 返回类型
Radian
实际案例
>>> # opt.BULLET.x, opt.BULLET.y, opt.BULLET.r = 0, 0, 1.5707963267948966 >>> print(opt.BULLET.radian) 1.5707963267948966
-
property
radian_velocity
¶ 角速度,单位为弧度/秒
- 返回
角速度
- 返回类型
Radian
-
property
-
class
opt.
Env
(ball, tanks, bullets)¶ 基类:
object
环境信息。 使用 opt.ENV 调用实例。
-
class
opt.
Pos
(x, y)¶ 基类:
object
点坐标
-
property
x
¶ x 坐标
- 返回
x 坐标
- 返回类型
float
-
property
y
¶ y 坐标
- 返回
y 坐标
- 返回类型
float
-
property
-
class
opt.
Sprite
(i, x, y, vx, vy, r, vr=None)¶ 基类:
object
负责记录场上物体的状态信息,如坦克,球,子弹的状态信息。如果直接赋值其状态信息无法影响到物体的运动。
-
i
¶ id
- Type
int
-
x
¶ x 坐标
- Type
float
-
y
¶ y 坐标
- Type
float
-
vx
¶ x 方向速度
- Type
float
-
vy
¶ y 方向速度
- Type
float
-
r
¶ 朝向的弧度信息,东方向为 0 度,北方向为 π/2,南方向是 -π/2
- Type
Radian
-
vr
¶ 角速度,弧度/秒
- Type
Radian, None
-
a
¶ 朝向的角度信息,东方向为 0 度,北方向为 90 度,南方向是 -90 度
- Type
Angle
-
-
class
opt.
Tank
(data_list, i)¶ 基类:
opt.Sprite
坦克功能与属性。 使用 opt.TANK 调用实例。
-
i
¶ id
- Type
int
-
x
¶ x 坐标
- Type
float
-
y
¶ y 坐标
- Type
float
-
vx
¶ x 方向速度
- Type
float
-
vy
¶ y 方向速度
- Type
float
-
r
¶ 朝向的弧度信息,东方向为 0 度,北方向为 π/2,南方向是 -π/2
- Type
Radian
-
vr
¶ 角速度,弧度/秒
- Type
Radian, None
-
a
¶ 朝向的角度信息,东方向为 0 度,北方向为 90 度,南方向是 -90 度
- Type
Angle
-
property
angle
¶ 物体朝向角度,东边为 0 度,北为 90,南为 -90
- 返回
角度
- 返回类型
Angle
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 1.5707963267948966 >>> print(opt.TANK.angle) 90
-
angle_to
(x: float, y: float) → opt.Angle¶ 获取物体与某坐标(x, y) 的角度
- 参数
x (float) – 目标 x 坐标
y (float) – 目标 y 坐标
- 返回
角度
- 返回类型
Angle
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.angle_to(-1, 0)) 180.0
-
chase_ball
() → tuple¶ 设置为追球模式,返回操控规则
- 返回
需要采取的前后,左右速度
- 返回类型
(float, float)
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> # opt.BALL.x, opt.BALL.y = 4, 0 >>> print(opt.TANK.chase_ball()) (1, 0)
-
property
cool_remain
¶ 坦克发射炮弹还需要的冷却时间。开炮后,需要 20s 的冷却时间
- 返回
还需等待的冷却时间(毫秒)
- 返回类型
int
-
distance_to
(x: float, y: float) → float¶ 获取物体与某坐标 (x, y) 距离
- 参数
x (float) – 目标 x 坐标
y (float) – 目标 y 坐标
- 返回
距离
- 返回类型
float
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.distance_to(2, 0)) 2.0
-
static
do_fire
() → None¶ 设置开火,没有设置时,默认不开火。坦克需要 20s 的准备时间才能开火,并且每次开火完,也需要另外 20s 准备下一次开火。 注意:当赛制的时间小于 20s 时,使用这个函数将不会有任何效果。
实际案例
>>> opt.TANK.do_fire()
-
face_enemy_door
(offset: float = 0) → bool¶ 是否面向对方球门,接受一定程度的偏置处理。
- 参数
offset (float) – 球门边缘的偏置位移,正数往球门两侧增大范围,负数往球门内缩小范围。需在(-8,+8)之间,默认为 0
- 返回
True/False
- 引发
AssertionError – offset must in a range of (-8, +8)
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.face_enemy_door()) True
-
face_my_door
(offset: float = 0) → bool¶ 是否面向我方球门,接受一定程度的偏置处理。
- 参数
offset (float) – 球门边缘的偏置位移,正数往球门两侧增大范围,负数往球门内缩小范围。需在(-8,+8)之间,默认为 0
- 返回
True/False
- 引发
AssertionError – offset must in a range of (-8, +8)
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.face_my_door()) False
-
goto
(x: float, y: float, policy: int = 0, *args, **kwargs) → tuple¶ 输入某地点,计算当前坦克去到此地点的操控速度,并返回操控速度
- 参数
x (float) – 目标 x 坐标
y (float) – 目标 y 坐标
policy (int) – 策略种类。默认 0
*args – 所选策略需要用到的参数
**kwargs – 所选策略需要用到的参数
- 返回
需要采取的前后,左右速度
- 返回类型
(float, float)
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.goto(4, 0)) (1, 0)
-
is_ball_in_range
(distance: float, left_view: Optional[Union[opt.Angle, opt.Radian, float, int]] = None, right_view: Optional[Union[opt.Angle, opt.Radian, float, int]] = None) → bool¶ 判断球是否在自己的 距离范围 和 朝向的角度范围 内。 如果左右视野任意一个为 None,那么只会判断距离范围是否满足。
- 参数
distance (float) – range 范围
left_view (Angle, Radian, float, int, None) – 左边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。默认为 None
right_view (Angle, Radian, float, int, None) – 右边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。默认为 None
- 返回
True/False
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> # opt.BALL.x, opt.BALL.y = 1, 0 >>> print(opt.TANK.is_ball_in_range(2)) True
>>> print(opt.TANK.is_ball_in_range(2, Angle(10), Angle(-10))) True
>>> print(opt.TANK.is_ball_in_range(2, Angle(90), Angle(30))) False
-
is_enemy
() → bool¶ 判断此坦克是否为对方坦克
- 返回
True/False
-
is_mine
() → bool¶ 判断此坦克是否为我方坦克
- 返回
True/False
-
is_point_in_range
(x: float, y: float, distance: float, left_view: Optional[Union[opt.Angle, opt.Radian, float, int]] = None, right_view: Optional[Union[opt.Angle, opt.Radian, float, int]] = None) → bool¶ 判断某个点坐标是否在自己的 距离范围 和 朝向的角度范围 内。 如果左右视野任意一个为 None,那么只会判断距离范围是否满足。
- 参数
x (float) – 点的 x 坐标
y (float) – 点的 y 坐标
distance (float) – range 范围
left_view (Angle, Radian, float, int, None) – 左边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。默认为 None
right_view (Angle, Radian, float, int, None) – 右边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。默认为 None
- 返回
True/False
- 引发
AssertionError – left_view must >= right_view
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.is_point_in_range(1, 0, 2)) True
>>> print(opt.TANK.is_point_in_range(1, 0, 2, Angle(10), Angle(-10))) True
>>> print(opt.TANK.is_point_in_range(1, 0, 2, Angle(90), Angle(30))) False
-
is_stuck
(slow_speed=0.2)¶ 判断是否在短时间内运动缓慢或者卡住不动。
- 参数
slow_speed (float) – 自定义的缓慢速度量,如果横纵轴速度有一个超出这个量级,就没有卡住。默认为 0.2
- 返回
True/False
实际案例
>>> # 当程序运行了多个 step,并且坦克都没有移动 >>> print(opt.TANK.is_stuck()) True
-
property
left_velocity
¶ 左履带转动速度 :returns: 米/秒 :rtype: float
-
property
length
¶ 坦克长度 :returns: 米 :rtype: float
-
static
not_fire
() → None¶ 设置不开火, 默认不开火
实际案例
>>> opt.TANK.not_fire()
-
observe
(left_view: Union[opt.Angle, opt.Radian, int, float], right_view: Union[opt.Angle, opt.Radian, int, float], include_ball: bool = False) → List[opt.Sprite]¶ 获取坦克左右视野内的坦克或球
- 参数
left_view (Angle, Radian, float, int, None) – 左边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。
right_view (Angle, Radian, float, int, None) – 右边界范围,以朝向为基准逆时针旋转。单位为弧度,如果传入角度,将会自动转换成弧度。
include_ball (bool) – 是否需要观测球,默认为 False
- 返回
在这个观测范围内的物体列表
- 引发
AssertionError – left_view must >= right_view
实际案例
>>> tanks = opt.TANK.observe(20, 10) # 逆时针方向,观测前方向 20 弧度至 10 弧度的范围
-
on_east_of
(item: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定物体的东边
>>> # opt.TANK.x, opt.TANK.y = 0, 0 >>> # opt.BALL.x, opt.BALL.y = 1, 0 >>> print(opt.TANK.on_east_of(opt.BALL)) False
-
on_north_of
(item: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定物体的北边
实际案例
>>> # opt.TANK.x, opt.TANK.y = 0, 0 >>> # opt.BALL.x, opt.BALL.y = 1, 0 >>> print(opt.TANK.on_north_of(opt.BALL)) False
-
on_south_of
(item: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定物体的南边
实际案例
>>> # opt.TANK.x, opt.TANK.y = 0, 0 >>> # opt.BALL.x, opt.BALL.y = 1, 1 >>> print(opt.TANK.on_south_of(opt.BALL)) True
-
on_west_of
(item: opt.Sprite, offset: float = 0) → bool¶ 判断是否在选定物体的西边
>>> # opt.TANK.x, opt.TANK.y = 0, 0 >>> # opt.BALL.x, opt.BALL.y = 1, 0 >>> print(opt.TANK.on_west_of(opt.BALL)) True
>>> print(opt.TANK.on_west_of(opt.BALL, 2)) False
-
policy1
(x: float, y: float, v_strength: float = 1.0, h_strength: float = 1.0) → tuple¶ 坦克移动策略 1
- 参数
x (float) – 需要移动去的 x 坐标
y (float) – 需要移动去的 y 坐标
v_strength (float) – 前后操控强度,取值范围 [0, 1]
h_strength (float) – 左右操控强度,取值范围 [0, 1]
- 返回
需要采取的前后,左右速度
- 返回类型
(float, float)
-
property
radian
¶ 物体朝向弧度,东边为 0 度,北为 π/2,南为 -π/2
- 返回
弧度
- 返回类型
Radian
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 1.5707963267948966 >>> print(opt.TANK.radian) 1.5707963267948966
-
radian_to
(x: float, y: float) → opt.Radian¶ 获取物体与某坐标(x, y) 的弧度
- 参数
x (float) – 目标 x 坐标
y (float) – 目标 y 坐标
- 返回
弧度
- 返回类型
Radian
实际案例
>>> # opt.TANK.x, opt.TANK.y, opt.TANK.r = 0, 0, 0 >>> print(opt.TANK.radian_to(-1, 0)) 3.141592653589793
-
property
radian_velocity
¶ 角速度,单位为弧度/秒
- 返回
角速度
- 返回类型
Radian
-
property
right_velocity
¶ 右履带转动速度 :returns: 米/秒 :rtype: float
-
property
width
¶ 坦克宽度 :returns: 米 :rtype: float
-
-
opt.
a2r
(angle: Union[float, int, opt.Angle]) → opt.Radian¶ 角度转弧度
- 参数
angle (Angle, float, int) – 角度
- 返回
弧度
- 返回类型
Radian
实际案例
>>> print(a2r(180)) 3.141592653589793
-
opt.
distance
(x1: float, y1: float, x2: float, y2: float) → float¶ 计算两点之间直线距离
- 参数
x1 (float) – 点 1 的 x 坐标
y1 (float) – 点 1 的 y 坐标
x2 (float) – 点 2 的 x 坐标
y2 (float) – 点 2 的 y 坐标
- 返回
两点之间的直线距离,单位米
- 返回类型
float
实际案例
>>> print(distance(0, 0, 0, 1)) 1.0
-
opt.
r2a
(radian: Union[float, int, opt.Radian]) → opt.Angle¶ 弧度转角度
- 参数
radian (Radian, float, int) – 弧度
- 返回
角度
- 返回类型
Angle
实际案例
>>> print(r2a(math.pi)) 180.0
-
opt.
relative_angle
(x1: float, y1: float, a1: Union[opt.Angle, float], x2: float, y2: float) → opt.Angle¶ 获取 坐标1(附方向) 与 坐标2 的角度,角度值为逆时针转动。
- 参数
x1 (float) – 坐标1 的 x 坐标
y1 (float) – 坐标1 的 y 坐标
a1 (Angle, float) – 坐标1 的角度(相对于东方向逆时针旋转)
x2 (float) – 坐标2 的 x 坐标
y2 (float) – 坐标2 的 y 坐标
- 返回
角度
- 返回类型
Angle
实际案例
>>> print(relative_angle(0, 0, 0, -1, 0)) 180.0
-
opt.
relative_radian
(x1: float, y1: float, r1: Union[opt.Radian, float], x2: float, y2: float) → opt.Radian¶ 获取 坐标1(附方向) 与 坐标2 的弧度,弧度值为逆时针转动。
- 参数
x1 (float) – 坐标1 的 x 坐标
y1 (float) – 坐标1 的 y 坐标
r1 (Radian, float) – 坐标1 的弧度(相对于东方向逆时针旋转)
x2 (float) – 坐标2 的 x 坐标
y2 (float) – 坐标2 的 y 坐标
- 返回
弧度
- 返回类型
Radian
实际案例
>>> print(relative_radian(0, 0, 0, -1, 0)) 3.141592653589793
-
opt.
remaining_time
() → int¶ 返回剩余时间
- 返回
剩余时间(帧数)
- 返回类型
int
-
opt.
score
() → Tuple[int, int]¶ 返回双方得分,两个元素的元组,我方分数为元组的第一位,对方分数为第二位
- 返回
(我方分数,对方分数)
- 返回类型
(int, int)
-
opt.
score_diff
() → int¶ 返回当前比分差异,如果为正则为我方领先,如果为负则对方领先。
- 返回
比分差
- 返回类型
int
-
opt.
time_step
() → int¶ 返回当前程序运行次数,每一帧算一次
- 返回
运行次数(帧数)
- 返回类型
int