From 726997d799edc388cd448e978d5bb0755aaa551c Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Tue, 7 Jul 2026 16:46:32 -0400 Subject: feat: bitpacked and base64 encoded VisitedRooms in player YAML to keep the file human readable --- internal/player/player.go | 3 +- internal/player/roomset.go | 109 ++++++++++++++++++++++++++++++++++++++++ internal/player/roomset_test.go | 87 ++++++++++++++++++++++++++++++++ internal/player/stats.go | 7 +-- 4 files changed, 199 insertions(+), 7 deletions(-) create mode 100644 internal/player/roomset.go create mode 100644 internal/player/roomset_test.go (limited to 'internal/player') diff --git a/internal/player/player.go b/internal/player/player.go index 65026e7..fcf274b 100644 --- a/internal/player/player.go +++ b/internal/player/player.go @@ -333,8 +333,7 @@ func New(name string) *Player { RoomID: 0, MapSymbols: make(map[int]MapSymbolData), Stats: PlayerStats{ - RoomsVisited: make(map[int]bool), - MobKills: make(map[string]int), + MobKills: make(map[string]int), }, } for _, s := range AllSkills { diff --git a/internal/player/roomset.go b/internal/player/roomset.go new file mode 100644 index 0000000..3565bb6 --- /dev/null +++ b/internal/player/roomset.go @@ -0,0 +1,109 @@ +package player + +import ( + "encoding/base64" + "math/bits" + + "gopkg.in/yaml.v3" +) + +type RoomSet struct { + bits []byte +} + +func (rs *RoomSet) Add(roomID int) { + if roomID < 0 { + return + } + byteIdx := roomID / 8 + if byteIdx >= len(rs.bits) { + nb := make([]byte, byteIdx+1) + copy(nb, rs.bits) + rs.bits = nb + } + rs.bits[byteIdx] |= 1 << (roomID % 8) +} + +func (rs *RoomSet) Has(roomID int) bool { + if roomID < 0 { + return false + } + byteIdx := roomID / 8 + return byteIdx < len(rs.bits) && rs.bits[byteIdx]&(1<<(roomID%8)) != 0 +} + +func (rs *RoomSet) Len() int { + n := 0 + for _, b := range rs.bits { + n += bits.OnesCount8(b) + } + return n +} + +func (rs RoomSet) IsZero() bool { + return len(rs.bits) == 0 +} + +func (rs *RoomSet) Keys() []int { + var keys []int + for byteIdx, b := range rs.bits { + if b == 0 { + continue + } + base := byteIdx * 8 + for bitIdx := 0; bitIdx < 8; bitIdx++ { + if b&(1<