basically my idea is:
we are alr doing a lot of lazy work on the tile mapo struct. what if, along with that, we could do a floodfill for distance from beacon. this would just be a 32x32 array, not a 32x32x32x32, because we dont really care which beacon is the close by one (well we do when we r building a killshot, but the check happens a LOT more often, so having that be fast is quite important)
- the actual implementation of this could be really fucking efficient. we can just use simd mins on u8/16 on the distances array that we already calculate for every tile. we just do this on every beacon placement/removal and calculate 2 things: distance from any white beacon, and distance from any black beacon
this then makes shit a lot simpler for the normal cases of: normal movement
- this is the 32x32x32x32 dists array, o(1) lookup
- beacon movement: check the distances of both players from beacons and see if we can afford to do that movement
- note: 2 beacons in a row never makes sense so this works
the special case of place a beacon and then kill is harder.
im not sure abt this, but the only thing i can think of is as follows: first: check the distance form a beacon (we alr do this mem load so not hard can just do a lil bit of math on it ) and make sure we can afford it. cheap check
store a bitboard (this is an abstraction we'd have to create) of tiles that white and black can place beacons on. create a bitboard of all of the squares we can get to based on how far we have to travel after the beacon (this can also be a super fast simd op) ands them together checks popcnt > 0
- this is a relatively rare case so the fact that actually building the killshot chain based off of this is expensive is ~fine. the speed of the check is more important
this seems just better than ur plan in every way??? also lets do simd stuff later w profilking. correctness first
known bug: killshot detection ignores powerups the player would collect along the walk path. detour powerups (off the shortest path) are provably never worth it for walk-only killshots because escalating consecutive-move costs outpace the +35 gain. so only on-path powerups matter.
approach: SIMD bitmask to find on-path powerups, then O(1) feasibility check per powerup.
step 1: build on-path bitmask (per row, SIMD)
for row in 0..32:
da = u16x32 from dist[player][row] // distances from player to every col in this row
db = u16x32 from dist[opponent][row] // distances from opponent to every col in this row
on_path = (da + db).simd_eq(splat(total_dist)).to_bitmask() as u32
if on_path & powerup_bb.rows[row] != 0: found a useful powerup
cost: 32 SIMD adds + 32 compares + 32 ANDs. both dist slices are 2KB contiguous, fits in L1.
step 2: O(1) feasibility check per on-path powerup for a powerup at distance k from the player on a path of length pdist:
- can we reach it? stamina >= cost_for_movement(k, moves_so_far)
- can we finish? stamina - cost_for_movement(k, msf) + 35 >= cost_for_movement(pdist - k, msf + k) no path simulation needed — just two arithmetic checks using the precomputed distances.
step 3: construct path through the powerup since dist[player][p] + dist[p][opponent] == dist[player][opponent], the path min_path_to(player, p) ++ min_path_to(p, opponent) is a valid shortest path that goes through the powerup. no special pathfinding needed.
prereqs: need SIMD infra first (portable_simd feature, powerup Bitboard on Board). for beacon killshot cases (2 and 3), same check applies per walk segment.
min_path_to return iterator instead of allocating lots of bumpalo opt we can do
quantize remove tanh activation explore the position embedding + dot product to encode player position image net tricks for ensuring generalization (e.g. flipping, moving around the wall padding, etc)