81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
import sys, json
|
|
sys.path.insert(0, '.')
|
|
from tooling.rl_self_play.harness_client import HarnessClient, HarnessConfig
|
|
from tooling.rl_self_play.encoders import encode_legal_actions
|
|
from tooling.rl_self_play.record_expert import _DropStats, _resolve
|
|
|
|
|
|
def adv(c, slot):
|
|
for a in c.suggest(slot=slot):
|
|
v = c.view(slot=slot)
|
|
_, i2a = encode_legal_actions(v)
|
|
idx = _resolve(a, v, i2a, _DropStats())
|
|
if idx is None:
|
|
continue
|
|
r = i2a[idx]
|
|
try:
|
|
if r.get('type') == 'end_turn':
|
|
c.end_turn(slot=slot)
|
|
else:
|
|
c.act(r, slot=slot)
|
|
except Exception:
|
|
break
|
|
try:
|
|
c.end_turn(slot=slot)
|
|
except Exception:
|
|
pass
|
|
c.drain_notifications()
|
|
|
|
|
|
def ents(v, slot, key):
|
|
return [x for x in v.get(key, []) if int(x.get('owner', -1)) == slot]
|
|
|
|
|
|
def pos(x):
|
|
p = x.get('position', [-99, -99])
|
|
return (float(p[0]), float(p[1]))
|
|
|
|
|
|
def wrapdist(a, b, w=40, h=24):
|
|
dx = abs(a[0] - b[0]); dx = min(dx, w - dx)
|
|
dy = abs(a[1] - b[1]); dy = min(dy, h - dy)
|
|
return (dx * dx + dy * dy) ** 0.5
|
|
|
|
|
|
def min_interplayer_dist(v):
|
|
p0 = [pos(x) for x in ents(v, 0, 'units')] + [pos(x) for x in ents(v, 0, 'cities')]
|
|
p1 = [pos(x) for x in ents(v, 1, 'units')] + [pos(x) for x in ents(v, 1, 'cities')]
|
|
if not p0 or not p1:
|
|
return -1
|
|
return min(wrapdist(a, b) for a in p0 for b in p1)
|
|
|
|
|
|
for seed in (1, 6):
|
|
c = HarnessClient(HarnessConfig(seed=seed, players=2, player_slots=(0, 1),
|
|
map_size='duel', map_type='pangaea',
|
|
victory_mode='domination', timeout_sec=110))
|
|
v = c.view(1)
|
|
cap0 = [pos(x) for x in ents(v, 0, 'cities')]
|
|
cap1 = [pos(x) for x in ents(v, 1, 'cities')]
|
|
print('seed%d t0: P0cap=%s P1cap=%s capdist=%.1f' % (
|
|
seed, cap0, cap1, wrapdist(cap0[0], cap1[0]) if cap0 and cap1 else -1))
|
|
prev0 = prev1 = 0
|
|
combat_seen = False
|
|
mindist_ever = 999
|
|
for rnd in range(58):
|
|
v = c.view(1)
|
|
n0 = len(ents(v, 0, 'units')); n1 = len(ents(v, 1, 'units'))
|
|
# mil drop relative to prior peak observed = combat loss signal
|
|
if rnd > 0 and (n0 < prev0 or n1 < prev1):
|
|
combat_seen = True
|
|
prev0, prev1 = max(prev0, n0), max(prev1, n1)
|
|
d = min_interplayer_dist(v)
|
|
if d >= 0:
|
|
mindist_ever = min(mindist_ever, d)
|
|
if rnd % 15 == 0:
|
|
print(' t%d: P0u=%d P1u=%d mindist=%.1f' % (
|
|
int(v.get('turn', 0)), n0, n1, d))
|
|
adv(c, 0); adv(c, 1)
|
|
print(' seed%d SUMMARY: combat_seen(mil_drop)=%s min_interplayer_dist_ever=%.1f' % (
|
|
seed, combat_seen, mindist_ever))
|
|
c.shutdown()
|