diff --git a/go.mod b/go.mod index f001292..06f7383 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module mayhem-party go 1.19 -require github.com/micmonay/keybd_event v1.1.1 // indirect +require ( + github.com/go-yaml/yaml v2.1.0+incompatible // indirect + github.com/micmonay/keybd_event v1.1.1 // indirect +) diff --git a/go.sum b/go.sum index 1a6387e..33758c8 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/micmonay/keybd_event v1.1.1 h1:rv7omwXWYL9Lgf3PUq6uBgJI2k1yGkL/GD6dxc6nmSs= github.com/micmonay/keybd_event v1.1.1/go.mod h1:CGMWMDNgsfPljzrAWoybUOSKafQPZpv+rLigt2LzNGI= diff --git a/src/device/input/input.go b/src/device/input/input.go index 3619a11..840dbbb 100644 --- a/src/device/input/input.go +++ b/src/device/input/input.go @@ -5,5 +5,5 @@ type Input interface { } func New() Input { - return NewRandom(RandomCharFromRange('a', 'g')) + return NewRandom(randomCharFromRange('a', 'g')) } diff --git a/src/device/input/random.go b/src/device/input/random.go index e5998a9..dbfafa7 100644 --- a/src/device/input/random.go +++ b/src/device/input/random.go @@ -1,8 +1,14 @@ package input import ( + "bytes" + "fmt" + "io" "math/rand" + "os" "time" + + "github.com/go-yaml/yaml" ) type Button struct { @@ -35,13 +41,36 @@ func (r *Random) Read() []Button { } } -func RandomCharFromRange(start, stop byte) func() byte { +func randomCharFromRange(start, stop byte) func() byte { return func() byte { return start + byte(rand.Int()%int(1+stop-start)) } } -func RandomCharFromWeights(m map[byte]int) func() byte { +func randomCharFromWeightFile(p string) func() byte { + b, err := os.ReadFile(p) + if err != nil { + panic(err) + } + return randomCharFromWeightReader(bytes.NewReader(b)) +} + +func randomCharFromWeightReader(r io.Reader) func() byte { + var m map[string]int + if err := yaml.NewDecoder(r).Decode(&m); err != nil { + panic(err) + } + byted := map[byte]int{} + for k, v := range m { + if len(k) != 1 { + panic(fmt.Sprintf("keys must be 1 character but got %q", k)) + } + byted[k[0]] = v + } + return randomCharFromWeights(byted) +} + +func randomCharFromWeights(m map[byte]int) func() byte { type pair struct { b byte i int diff --git a/src/device/input/random_exported_test.go b/src/device/input/random_exported_test.go new file mode 100644 index 0000000..ff5bcd1 --- /dev/null +++ b/src/device/input/random_exported_test.go @@ -0,0 +1,16 @@ +package input_test + +import ( + "mayhem-party/src/device/input" + "testing" +) + +func TestNew(t *testing.T) { + r := input.New() + for i := 0; i < 15; i++ { + batch := r.Read() + for _, got := range batch { + t.Logf("[%d] %c:%v", i, got.Char, got.Down) + } + } +} diff --git a/src/device/input/random_test.go b/src/device/input/random_test.go index 9824f04..df0812e 100644 --- a/src/device/input/random_test.go +++ b/src/device/input/random_test.go @@ -1,31 +1,45 @@ -package input_test +package input import ( - "mayhem-party/src/device/input" + "strings" "testing" ) -func TestRandom(t *testing.T) { - r := input.NewRandom(input.RandomCharFromRange('a', 'z')) - for i := 0; i < 100; i++ { - batch := r.Read() - for _, got := range batch { - t.Logf("[%d] %c:%v", i, got.Char, got.Down) - } - } -} - func TestRandomCharFromWeights(t *testing.T) { weights := map[byte]int{ 'a': 1, 'b': 99, } - foo := input.RandomCharFromWeights(weights) + foo := randomCharFromWeights(weights) for { got := foo() - t.Logf("%c", got) if got == 'a' { break } } } + +func TestRandomCharFromWeightsReader(t *testing.T) { + t.Run("json", func(t *testing.T) { + b := `{"a": 1}` + r := strings.NewReader(b) + foo := randomCharFromWeightReader(r) + for i := 0; i < 10; i++ { + if got := foo(); got != 'a' { + t.Errorf("%c", got) + } + } + }) + t.Run("yaml", func(t *testing.T) { + b := ` +a: 2000 + ` + r := strings.NewReader(b) + foo := randomCharFromWeightReader(r) + for i := 0; i < 10; i++ { + if got := foo(); got != 'a' { + t.Errorf("%c", got) + } + } + }) +}