Files
rgoue/game/rng.go
sneak 63d1e797e2 chore(lint): adopt canonical golangci-lint config
Replace .golangci.yml with the shared canonical config. The old
config's top-level linters-settings block was silently ignored under
the v2 schema, so the lll/funlen/cyclop/dupl thresholds now actually
apply. The four repo-specific disables (mnd, exhaustive, paralleltest,
testpackage) move out of the config into targeted in-code nolint
directives carrying their original approval dates, keeping the config
byte-identical to the canonical one.

Fixes surfaced by the stricter settings: t.Parallel() added to all 32
tests, 24 overlong lines wrapped or their comments tightened, tcell
control-code returns rewritten as character literals, dupl markers on
the identically-shaped item data tables, and two wsl_v5 defer cuddles.

No behavior changes. The repo has no golangci-lint version pin (no
Dockerfile or CI; make lint runs the host binary, currently v2.12.2),
so there was nothing to bump.
2026-08-07 20:45:02 +00:00

57 lines
1.4 KiB
Go

//nolint:mnd // C-faithful literals; names hurt C-greppability (approved 2026-07-07)
package game
// Rng is the original Rogue linear congruential generator. The C RN macro is
//
// #define RN (((seed = seed*11109+13849) >> 16) & 0xffff)
//
// with `seed` a C int; Seed is int32 so the multiplication wraps exactly the
// way 32-bit C arithmetic does. A given seed therefore produces the same
// dungeon as the C game.
type Rng struct {
Seed int32
}
// Rnd picks a very random number in [0, rng) (main.c rnd).
func (r *Rng) Rnd(rng int) int {
if rng == 0 {
return 0
}
v := r.next()
if v < 0 {
v = -v
}
return v % rng
}
// Roll rolls a number of dice (main.c roll).
func (r *Rng) Roll(number, sides int) int {
dtotal := 0
for ; number > 0; number-- {
dtotal += r.Rnd(sides) + 1
}
return dtotal
}
// next steps the generator and returns the next raw value (the RN macro).
func (r *Rng) next() int {
r.Seed = r.Seed*11109 + 13849
return int(r.Seed>>16) & 0xffff
}
// rnd is the ported code's spelling of C rnd(): every call site in the C
// sources reads rnd(x), and keeping that shape makes cross-checking easy.
func (g *RogueGame) rnd(rng int) int { return g.Rng.Rnd(rng) }
// roll is C roll().
func (g *RogueGame) roll(number, sides int) int { return g.Rng.Roll(number, sides) }
// spread gives a fuzzy number centered on nm (misc.c spread).
func (g *RogueGame) spread(nm int) int {
return nm - nm/20 + g.rnd(nm/10)
}