Documentation
¶
Overview ¶
Package attacklog turns a bot run log into a per-unit account of what the deploy phase actually did.
It exists because the aggregate line is not evidence. A real 1280x720 attack logged `all units successfully deployed` and `remaining=0` while the same log recorded, further up, that the Barbarian King and Grand Warden had failed to deploy, that the Balloon and Electro Dragon reconciles had exhausted and been marked deployed on an OCR reading of zero *against a slot that still looked non-empty*, and that five Ice Spells had been tapped inside a 42x29 px box.
The gap was in how the run was checked, not in the parser: the geometry tools answer "are the taps inside the deployable band", which is necessary and nowhere near sufficient. This package answers "which units actually deployed, and were the spells placed somewhere they do work".
It reads the log's *intent and outcome lines* — what the bot decided and what its own reconcile concluded. It cannot see the game. A unit it calls unverified is one whose completion the bot could not establish either, which is exactly the category worth reporting.
Index ¶
Constants ¶
const DefaultSpellRadius = 100.0
DefaultSpellRadius is the reach a single spell placement is assumed to cover, in live pixels. It is the yardstick for "did these taps overlap": the village view spans roughly 44 tiles across 1280 px at the 720p device profile, so ~29 px per tile, and a freeze covers a handful of tiles. The number is a heuristic on purpose — the report prints the measured spacing beside it so a reader can judge for themselves instead of trusting a verdict.
const MinCastSpacing = DefaultSpellRadius * stackFactor
MinCastSpacing is the smallest live-pixel gap at which two casts of the same spell are working adjacent ground instead of the same ground. It is exported because it is not only a reporting threshold: the spell deployer enforces it as an invariant (see internal/attack's minCastSpacingRef), so that the tool which measures the defect and the code that would commit it agree on one number. Five Ice Spells tapped 11 px apart is how this was found.
Variables ¶
This section is empty.
Functions ¶
func IsDeployLine ¶
IsDeployLine reports whether a log line describes a deploy tap carrying coordinates — the lines this package reads coordinates from.
Types ¶
type Placement ¶
type Placement struct {
Unit string
Taps []Point
MinSpacing float64
Span float64
// Overlapped is true when two casts landed within half a cast's reach of
// each other, i.e. one of them was spent on ground the other already covers.
Overlapped bool
// Tight is the milder case: closer than a full reach, but not stacked.
Tight bool
// Stacked is how many taps have another tap within half a reach.
Stacked int
}
Placement is one spell unit's tap geometry, with the analysis applied.
type Report ¶
type Report struct {
Path string
Edge string
Projection string
DisplayK float64
ClampedTop int
ClampedBtm int
ClampedPts int
BandKnown bool
Units []Unit
SpellRadius float64
// CountFabricated names the units whose troop count could not be read, so
// the deploy used a fallback number instead of what the card held.
CountFabricated []string
ZeroCountSlots int
TotalSlots int
}
Report is the parsed run.
func (*Report) FailedUnits ¶
FailedUnits returns the units whose deployment the run did not establish, excluding the ones that were never in the bar.
func (*Report) OverlappedSpells ¶
OverlappedSpells returns the spell units whose taps are stacked within half a cast's reach, which means part of the cast landed on ground a previous cast already covers.
func (*Report) Placements ¶
Placements returns the spell units with their spacing analysis, which is where the report's "did the spells overlap" answer comes from.
type Unit ¶
type Unit struct {
Name string
Kind string // troop | siege | hero | spell | event
Verdict Verdict
Reason string
// Taps are the coordinates the log says were fired for this unit.
Taps []Point
// MinSpacing is the smallest distance between any two of its taps, and Span
// the largest. For a spell fired several times these are the whole question:
// five freezes 23 px apart are one freeze.
MinSpacing float64
Span float64
}
Unit is one line of the report.
type Verdict ¶
type Verdict string
Verdict is what the log lets us say about one unit.
const ( // ConfirmedDeploy means the bot observed the card leave the bar (an explicit // success signal, e.g. "sweep reconciled slot empty" or "hero deployed"). ConfirmedDeploy Verdict = "deployed" // Failed means the bot said so ("will be marked failed"). Failed Verdict = "FAILED" // Unverified means the bot believed it deployed but the evidence in the log // is a fallback or a contradiction: a zero-OCR "spent" verdict against a // slot its own visual check called non-empty, or a reconcile that exhausted // and was handed on. These are the ones that turn into "it didn't use all // the troops" with no error anywhere. Unverified Verdict = "UNVERIFIED" // NotInBar means the card was never in the army bar, so skipping it is // correct rather than a failure. NotInBar Verdict = "not in bar" )