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) }