75 lines
1.3 KiB
Go
75 lines
1.3 KiB
Go
package world
|
|
|
|
import "math/bits"
|
|
|
|
// u128 is an unsigned 128-bit integer for safe squared comparisons.
|
|
type u128 struct{ hi, lo uint64 }
|
|
|
|
func u128FromMul64(a, b uint64) u128 {
|
|
hi, lo := bits.Mul64(a, b)
|
|
return u128{hi: hi, lo: lo}
|
|
}
|
|
|
|
func u128Add(a, b u128) u128 {
|
|
lo := a.lo + b.lo
|
|
hi := a.hi + b.hi
|
|
if lo < a.lo {
|
|
hi++
|
|
}
|
|
return u128{hi: hi, lo: lo}
|
|
}
|
|
|
|
func u128Cmp(a, b u128) int {
|
|
if a.hi < b.hi {
|
|
return -1
|
|
}
|
|
if a.hi > b.hi {
|
|
return 1
|
|
}
|
|
if a.lo < b.lo {
|
|
return -1
|
|
}
|
|
if a.lo > b.lo {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func abs64(x int64) int64 {
|
|
if x < 0 {
|
|
return -x
|
|
}
|
|
return x
|
|
}
|
|
|
|
func sqU128Int64(x int64) u128 {
|
|
u := uint64(abs64(x))
|
|
return u128FromMul64(u, u)
|
|
}
|
|
|
|
func distSqU128(dx, dy int64) u128 {
|
|
return u128Add(sqU128Int64(dx), sqU128Int64(dy))
|
|
}
|
|
|
|
// shortestTorusDelta returns the shortest signed delta from a->b on a torus axis of size.
|
|
// It is deterministic in tie cases (size even, exactly half): chooses negative direction.
|
|
func shortestTorusDelta(a, b, size int) int64 {
|
|
d := int64(b - a)
|
|
s := int64(size)
|
|
half := s / 2
|
|
|
|
// Normalize d into (-s, s).
|
|
d = d % s
|
|
if d <= -half {
|
|
d += s
|
|
} else if d > half {
|
|
d -= s
|
|
}
|
|
|
|
// Tie case when size even and d == +half: choose -half.
|
|
if s%2 == 0 && d == half {
|
|
d = -half
|
|
}
|
|
return d
|
|
}
|