go: port foundation — types, RNG, tables, daemon scheduler
Module sneak.berlin/go/rogue, package game: - types.go: all rogue.h constants, flag types, Coord/Stats/Room/ObjInfo - creature.go/object.go: the THING union split into Creature (Player/ Monster) and Object; slices replace the C linked lists - level.go: Place map with the C column-major layout and chat/flat/moat/ winat access methods - tables.go: extern.c + init.c data (bestiary, item tables, name pools) - rng.go: the exact C LCG (seed*11109+13849), golden-tested against a compiled C reference for seed compatibility - init.go: per-game item appearance randomization (init.c) - daemon.go/daemons.go: scheduler with DaemonID replacing function pointers (ids match the C save format's mapping) - game.go: RogueGame holds all former globals; NewGame constructor
This commit is contained in:
51
game/rng.go
Normal file
51
game/rng.go
Normal file
@@ -0,0 +1,51 @@
|
||||
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
|
||||
}
|
||||
|
||||
// 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 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
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user