57 lines
1.3 KiB
Go
57 lines
1.3 KiB
Go
package sim
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
"sort"
|
|
)
|
|
|
|
// Hash returns a digest of the complete simulation state. Two runs from the
|
|
// same seed and inputs must produce identical hashes.
|
|
func (s *State) Hash() [32]byte {
|
|
h := sha256.New()
|
|
w := func(vs ...int64) {
|
|
var b [8]byte
|
|
for _, v := range vs {
|
|
binary.LittleEndian.PutUint64(b[:], uint64(v))
|
|
h.Write(b[:])
|
|
}
|
|
}
|
|
w(s.Day, int64(len(s.Asteroids)))
|
|
for i := range s.Asteroids {
|
|
a := &s.Asteroids[i]
|
|
w(a.ID)
|
|
for _, o := range a.Ore {
|
|
w(o)
|
|
}
|
|
}
|
|
w(int64(len(s.Ships)))
|
|
for _, sh := range s.Ships {
|
|
alive := int64(0)
|
|
if sh.Alive {
|
|
alive = 1
|
|
}
|
|
w(sh.ID, sh.Owner, alive, int64(sh.Pos.X), int64(sh.Pos.Y), int64(sh.Pos.Z),
|
|
int64(sh.Vel.X), int64(sh.Vel.Y), int64(sh.Vel.Z),
|
|
int64(sh.Fuel), sh.Earned, int64(sh.Throttle), int64(sh.Azimuth), int64(sh.Pitch), sh.Target)
|
|
for _, c := range sh.Cargo {
|
|
w(c)
|
|
}
|
|
h.Write(sh.CPU.MarshalState())
|
|
}
|
|
owners := make([]int64, 0, len(s.Credits))
|
|
for o := range s.Credits {
|
|
owners = append(owners, o)
|
|
}
|
|
sort.Slice(owners, func(i, j int) bool { return owners[i] < owners[j] })
|
|
for _, o := range owners {
|
|
w(o, s.Credits[o])
|
|
}
|
|
for _, v := range s.Market.Supply {
|
|
w(v)
|
|
}
|
|
var out [32]byte
|
|
copy(out[:], h.Sum(nil))
|
|
return out
|
|
}
|