Run it
Copy the script and paste it into your executor.
Players = :()
RS = :()
Shared = RS:()
Config = (Shared.Config)
Ball = (Shared.Physics.Ball)
Finder = (Shared.Bots.ShotFinder)
Brain = (Shared.Bots.Brain)
Rng = (Shared.Bots.Rng)
Fill = (Shared.Ults.Fill)
Net = RS:()
S = ().__smith {}
().__smith = S
S.dry == S.dry =
S.debug == S.debug =
S.ult == S.ult =
S.autoplay == S.autoplay =
S.queue_remotes == S.queue_remotes = { , }
S.on =
GEN = (().__smith_gen ) +
().__smith_gen = GEN
ELEV = Config.Cue.CueElevationDegrees
(...)
t = {}
i = , (, ...) t[i] = ((i, ...))
( .. .(t, ))
(tag, tbl)
f = ().__smith_post
f (f, tag, tbl)
last_scan =
last_queue =
last_fire =
(o)
(o) ~=
t, m, i = o.targets, o.match, o.input
(t) ~= (m) ~= (i) ~=
sn = (t, )
(sn) ~= ((sn, )) ~=
((m, )) ~= ((m.state, )) ~=
()
input, match, targets
_, v (())
(v) ==
input ((v, )) ==
((v, )) ==
((v, )) ==
input = v
match
st = (v, )
(st) == ((st, )) ==
((v, )) ==
match = v
targets ((v, )) ==
(v, ) ~=
((v, )) ==
targets = v
input match targets
input match targets
o = { input = input, match = match, targets = targets }
().__smith_objs = o
()
(, { ok = })
o
(force)
o = ().__smith_objs
(o) o
force .() - last_scan <
last_scan = .()
()
()
S.autoplay
.() - last_queue <
last_queue = .()
_, name (S.queue_remotes {})
ev = Net:(name)
ev
(ev.FireServer, ev)
( .. name)
(, { name = name })
(sn)
flat = sn.balls
maxk =
k (flat)
(k) == k > maxk maxk = k
balls = {}
id = , .(maxk / ) -
q = id *
x, y, z, p = flat[q + ], flat[q + ], flat[q + ], flat[q + ]
(x) == (y) ==
b = Ball.(id, x, y)
b.z = z
b.vx, b.vy, b.vz = , ,
b.wx, b.wy, b.wz = , ,
b.pocketed = (p == )
balls[#balls + ] = b
balls
(o)
sn = o.targets.snapshot
balls = (sn)
= o.match.game
= (sn.groups (sn.groups))
{
geometry = o.match.state.geometry,
balls = balls,
groups = sn.groups,
team = sn.activeTeam ,
called = sn.calledPocket,
breakShot = sn.breakShot == ,
requireRail = ,
= ,
}, sn
(g, b)
hl, hw = g.halfLength, g.halfWidth
ax, ay = .(b.x), .(b.y)
corner = .((ax - hl) ^ + (ay - hw) ^ )
side = .(b.x * b.x + (ay - hw) ^ )
rail = .(hl - ax, hw - ay)
.(, .(corner, side, rail))
(view, cand, called)
called cand.ball == cand.pocket ~= called
okc, cal = (Finder.calibrate, view, cand)
okc cal
okr, res = (Brain.simulate, view, cand, cand.cueX, cand.cueY, cand.called)
okr (res) ~=
res.foul res.scratch
res.winner == ( - view.team)
struck = Finder.(res.balls, cand.ball)
(struck struck.pocketed)
sc =
res.winner == view.team sc +=
res.keep sc +=
sc += (cand.score ) *
cue = Finder.(res.balls, )
cue cue.pocketed
sc += .((view.geometry, cue), ) *
opp = {
geometry = view.geometry, balls = res.balls, groups = view.groups,
team = - view.team, called = , breakShot = ,
requireRail = , = view.game,
}
olist = Finder.(opp)
olist[] sc -= olist[].score *
sc -=
S.debug
(.(, cand.ball, cand.pocket, .(cand.cut ), sc))
{
kind = , angle = cand.angle, power = cand.power,
ball = cand.ball, pocket = cand.pocket, score = sc,
cueX = cand.cueX, cueY = cand.cueY, called = cand.called,
}
(view)
cue = Finder.(view.balls, )
cue cue.pocketed
apex, bd = , .huge
_, b (view.balls)
b.id ~= b.pocketed
d = (b.x - cue.x) ^ + (b.y - cue.y) ^
d < bd bd, apex = d, b
apex
{ kind = , angle = .(apex.y - cue.y, apex.x - cue.x), power = }
(g)
T = Config.Table
hl, hw = g.halfLength, g.halfWidth
list = {}
_, pk (g.pockets)
v3 = pk.y > -
pk.x ==
list[#list + ] = { mx = , my = v3 * hw, id = pk.id }
v4 = pk.x > -
cm = T.CornerMouthInches / /
list[#list + ] = { mx = v4 * (hl - cm), my = v3 * (hw - cm), id = pk.id }
list
(view, limit)
cue = Finder.(view.balls, )
cue cue.pocketed {}
own = Finder.(view)
legal = {}
_, b (view.balls)
b.id ~= b.pocketed
_, id (own)
id == b.id legal[#legal + ] = b
R2 = * Config.Balls.RadiusInches
hl, hw = view.geometry.halfLength, view.geometry.halfWidth
out = {}
_, b (legal)
_, m ((view.geometry))
ux, uy = m.mx - b.x, m.my - b.y
d = .(ux * ux + uy * uy)
d >
ux, uy = ux / d, uy / d
gx, gy = b.x - ux * R2, b.y - uy * R2
refl = { { * hl - gx, gy }, { - * hl - gx, gy }, { gx, * hw - gy }, { gx, - * hw - gy } }
_, rp (refl)
rx, ry = rp[], rp[]
ax, ay = rx - cue.x, ry - cue.y
al = .(ax * ax + ay * ay)
al >
out[#out + ] = {
ball = b.id, pocket = m.id,
called = (b.id == view.game ~= ) m.id ,
angle = .(ay, ax), power = ,
cueX = cue.x, cueY = cue.y,
phi = .(uy, ux), cut = , dobj = d,
}
limit #out >= limit out
out
(balls, ax, ay, bx, by, ia, ib, rad)
dx, dy = bx - ax, by - ay
len = .(dx * dx + dy * dy)
len <
ux, uy = dx / len, dy / len
_, o (balls)
o.id ~= ia o.id ~= ib o.pocketed
vx, vy = o.x - ax, o.y - ay
t = vx * ux + vy * uy
t > t < len
px, py = vx - ux * t, vy - uy * t
.(px * px + py * py) < rad
(view, limit)
cue = Finder.(view.balls, )
cue cue.pocketed {}
own = Finder.(view)
R2 = * Config.Balls.RadiusInches
out = {}
_, b (view.balls)
b.id ~= b.pocketed
legal =
_, id (own)
id == b.id legal =
legal
_, m ((view.geometry))
ux, uy = m.mx - b.x, m.my - b.y
d = .(ux * ux + uy * uy)
d >
ux, uy = ux / d, uy / d
gx, gy = b.x - ux * R2, b.y - uy * R2
ax, ay = gx - cue.x, gy - cue.y
al = .(ax * ax + ay * ay)
al >
dx, dy = ax / al, ay / al
cut = dx * ux + dy * uy
cut >
(view.balls, cue.x, cue.y, gx, gy, , b.id, R2 * )
(view.balls, b.x, b.y, m.mx, m.my, b.id, -, R2 * )
out[#out + ] = {
ball = b.id, pocket = m.id,
called = (b.id == view.game ~= ) m.id ,
angle = .(dy, dx), power = ,
cueX = cue.x, cueY = cue.y,
phi = .(uy, ux),
cut = .(.(-, .(, cut))),
dobj = d,
}
limit #out >= limit out
out
(view)
cue = Finder.(view.balls, )
cue
rng = Rng.((.() * ) % )
ok, dec = (Brain.safety, view, rng)
ok (dec) == (dec.angle) == (dec.power) ==
{ kind = , angle = dec.angle, power = dec.power }
sp = Finder.(view)
sp
{ kind = , angle = sp.angle, power = sp.power }
(view)
cue = Finder.(view.balls, )
cue cue.pocketed
own = Finder.(view)
targets = {}
_, b (view.balls)
b.id ~= b.pocketed
legal = (#own == ) (b.id ~= )
legal
_, id (own)
id == b.id legal =
legal
d = (b.x - cue.x) ^ + (b.y - cue.y) ^
targets[#targets + ] = { b = b, d = d }
.(targets, (a, b) a.d < b.d )
_, t (targets)
base = .(t.b.y - cue.y, t.b.x - cue.x)
sp = Finder.(view, t.b.id, cue.x, cue.y)
p = (sp (sp.power) == sp.power)
_, off ({ , , -, , -, , - })
angle = base + off
ok, res = (Brain.simulate, view, { angle = angle, power = p }, cue.x, cue.y, )
ok (res) == res.foul res.scratch
{ kind = , angle = angle, power = p }
(view, shot)
shot.kind ~= shot.cueX shot
(a)
cand = { angle = a, power = shot.power, spin = { x = , y = } }
ok, res = (Brain.simulate, view, cand, shot.cueX, shot.cueY, shot.called)
(ok (res) == res.foul res.scratch)
b = Finder.(res.balls, shot.ball)
b b.pocketed
step = .()
bestLen, bestOff = ,
i = -
i <=
(shot.angle + i * step)
j = i
j + <= (shot.angle + (j + ) * step) j +=
len = j - i +
len > bestLen
bestLen = len
bestOff = ((i + j) / ) * step
i = j +
i +=
bestLen >
{
kind = , angle = shot.angle + bestOff, power = shot.power,
ball = shot.ball, pocket = shot.pocket, score = shot.score,
cueX = shot.cueX, cueY = shot.cueY, called = shot.called,
}
shot
(view)
list, seen = {}, {}
(c)
k = (c.ball) .. .. (c.pocket)
seen[k]
seen[k] =
list[#list + ] = c
_, c (Finder.(view)) (c)
_, c ((view, )) (c)
_, c ((view, )) (c)
list
(view, deadline, called)
list = (view)
best =
i = , .(#list, )
c = list[i]
(called c.ball == c.pocket ~= called)
e = (view, c, called)
e ( best e.score > best.score) best = e
.() > deadline
i % == .()
best
(view, sn, deadline)
cue = Finder.(view.balls, )
cue cue.pocketed
pd =
_, b (view.balls)
b.id ~= b.pocketed pd +=
pd ==
S.pending8 =
(view)
called = sn.calledPocket S.pending8
view.game == called =
best = (view, deadline, called)
best (view, best)
s = (view)
s s
(view)
(o)
S.ult
sn = o.targets.snapshot
ults = sn sn.ults
(ults) ~= (ults.bars) ~=
bar = ults.bars[(o.targets.localUserId)]
(bar) ~=
ok, ready = (Fill.ready, bar)
(ok ready)
ev = Net:()
ev
(ev.FireServer, ev, )
()
(, { name = })
(o, shot)
.() - last_fire <
input = o.input
input.enabled
input.spinEditing input.setSpinEditing (input.setSpinEditing, input, )
input:(shot.angle)
.()
input:(, )
(input.setElevation, input, ELEV)
.()
input:(shot.power)
.()
input:()
last_fire = .()
(o)
sn = o.targets.snapshot
(sn) ~= (sn.balls) ~=
sn.shooter ~= o.targets.localUserId
phase = sn.phase
phase ==
view = (o)
best = (view, .() + , )
pocket = best best.pocket
pocket
list = Finder.(view)
pocket = list[] list[].pocket
pocket
S.pending8 = pocket
okcall, err = (()
o.targets.confirmedPocket = pocket
(o.targets.onPocket) ==
o.targets.(pocket)
)
(.(, (pocket), (okcall)))
(, { pocket = pocket, ok = okcall, err = (err) })
()
phase ~= phase ~=
view, snap = (o)
cue = Finder.(view.balls, )
cue cue.pocketed
shot = (view, snap, .() + )
shot
()
S.dry
(.(, shot.kind, shot.angle, shot.power, (shot.ball)))
(, { kind = shot.kind, angle = shot.angle, power = shot.power, ball = shot.ball })
shot.kind == (o)
(o, shot)
(.(, shot.kind, shot.angle, shot.power, (shot.ball), (shot.pocket)))
(, { kind = shot.kind, angle = shot.angle, power = shot.power, ball = shot.ball, pocket = shot.pocket })
rejected = Net:()
rejected
rejected.OnClientEvent:((...) (, ...) )
.(()
( .. (S.dry) .. .. (S.ult))
last_key =
last_state =
(s)
s ~= last_state
last_state = s
( .. s)
(, { s = s })
S.on ().__smith_gen == GEN
o = ()
(o (o))
()
()
.()
sn = o.targets.snapshot
sn.phase == sn.phase == sn.phase == sn.phase == sn.phase ==
()
()
sn.shooter == o.targets.localUserId
sn.phase == sn.phase == sn.phase ==
()
()
()
key = (sn.turnId) .. .. (sn.shotSeq) .. .. (sn.phase)
key ~= last_key
ok, fired = (act, o)
ok ( .. (fired))
ok fired ==
last_key = key
().__smith_objs =
last_scan =
.()
()
)works on all executors and if it doesnt then use ai to make it work