initial commit, game init implemented

This commit is contained in:
Branden J Brown 2024-01-20 22:06:56 -06:00
commit f0dc3716e8
5 changed files with 136 additions and 0 deletions

35
game/game.go Normal file
View File

@ -0,0 +1,35 @@
package game
type Game struct {
RNG RNG
PP [2]Player
Shells []bool
Round int
Turn int
Damage int8
// Backing storage for shells.
ShellArray [8]bool
}
func NewGame() *Game {
return &Game{RNG: NewRNG()}
}
func (g *Game) StartRound() {
items := g.RNG.Intn(4) + 1
g.PP[0].StartRound(&g.RNG, items)
g.PP[1].StartRound(&g.RNG, items)
shells := g.RNG.Intn(6) + 2
for i := 0; i < shells/2; i++ {
g.ShellArray[i] = true
}
for i := shells / 2; i < shells; i++ {
g.ShellArray[i] = false
}
g.Shells = g.ShellArray[:shells]
ShuffleSlice(&g.RNG, g.Shells)
g.Round++
g.Turn = 0
g.Damage = 1
}

16
game/item.go Normal file
View File

@ -0,0 +1,16 @@
package game
type Item int8
const (
ItemNone Item = iota
ItemLens
ItemCig
ItemBeer
ItemCuff
ItemKnife
)
func NewItem(rng *RNG) Item {
return Item(rng.Intn(5)) + 1
}

17
game/player.go Normal file
View File

@ -0,0 +1,17 @@
package game
type Player struct {
HP int8
Items [8]Item
Skip bool
Cuffed bool
}
func (p *Player) StartRound(rng *RNG, items int) {
p.HP = int8(rng.Intn(3) + 2)
for i := 0; i < items; i++ {
p.Items[i] = NewItem(rng)
}
p.Skip = false
p.Cuffed = false
}

65
game/rng.go Normal file
View File

@ -0,0 +1,65 @@
package game
import (
"crypto/rand"
"encoding/binary"
"math/bits"
)
// RNG is a random number generator for shotgun.
//
// Currently xoshiro256**. Subject to change.
type RNG struct {
w, x, y, z uint64
}
// NewRNG produces a new, uniquely seeded RNG.
func NewRNG() RNG {
r := RNG{}
b := make([]byte, 8*4)
// Loop to ensure the state is never all-zero, which is an invalid state
// for xoshiro.
for r.w == 0 && r.x == 0 && r.y == 0 && r.z == 0 {
rand.Read(b)
r.w = binary.LittleEndian.Uint64(b)
r.x = binary.LittleEndian.Uint64(b[8:])
r.y = binary.LittleEndian.Uint64(b[16:])
r.z = binary.LittleEndian.Uint64(b[24:])
}
return r
}
// Uint64 produces a 64-bit pseudo-random value.
func (rng *RNG) Uint64() uint64 {
w, x, y, z := rng.w, rng.x, rng.y, rng.z
r := bits.RotateLeft64(x*5, 7) * 9
t := x << 17
y ^= w
z ^= x
x ^= y
w ^= z
y ^= t
z = bits.RotateLeft64(z, 45)
rng.w, rng.x, rng.y, rng.z = w, x, y, z
return r
}
// Intn produces an int in [0, n). Panics if n <= 0.
func (rng *RNG) Intn(n int) int {
if n <= 0 {
panic("shotgun: rng.Intn max below zero")
}
bad := ^uint(0) - ^uint(0)%uint(n)
x := uint(rng.Uint64())
for x > bad {
x = uint(rng.Uint64())
}
return int(x % uint(n))
}
func ShuffleSlice[E any, S ~[]E](rng *RNG, s S) {
for i := len(s) - 1; i > 0; i-- {
j := rng.Intn(i + 1)
s[i], s[j] = s[j], s[i]
}
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.sunturtle.xyz/studio/shotgun
go 1.21.3