-
Notifications
You must be signed in to change notification settings - Fork 0
/
simulate.go
102 lines (95 loc) · 2.26 KB
/
simulate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"errors"
"fmt"
"time"
"github.com/Dae314/placeit-sim/binPlace"
"github.com/Dae314/placeit-sim/game"
"github.com/Dae314/placeit-sim/hyperPlace"
"github.com/Dae314/placeit-sim/midPlace"
"github.com/Dae314/placeit-sim/randPlace"
"github.com/Dae314/placeit-sim/simpleBinPlace"
"github.com/Dae314/placeit-sim/simpleBinRand"
"github.com/Dae314/placeit-sim/utils"
"golang.org/x/sync/errgroup"
)
type placeFunc func(*game.PlaceItGame) (int, error)
const parallelism = 1000
const maxTrials = 1000000
func playGame(g *game.PlaceItGame, c chan int, getPlace placeFunc) {
for {
switch g.State {
case game.WinState, game.LoseState:
c <- g.Score
return
case game.DrawState:
g.Draw()
case game.PlaceState:
placement, err := getPlace(g)
if err != nil {
endGame := &simpleBinPlace.ErrEndGame{}
if errors.As(err, &endGame) {
c <- game.CalcScore(g)
return
}
fmt.Printf("Error encountered: %v\n", err)
return
}
err = g.Place(placement)
if err != nil {
fmt.Printf("Error encountered: %v\n", err)
return
}
}
}
}
func main() {
start := time.Now()
placeMethodNames := []string{
"Random",
"Middle",
"Bin",
"Hyper Geom",
"Simple Bin",
"Simple Bin Rand",
}
placeMethods := []placeFunc{
randPlace.GetPlacement,
midPlace.GetPlacement,
binPlace.GetPlacement,
hyperPlace.GetPlacement,
simpleBinPlace.GetPlacement,
simpleBinRand.GetPlacement,
}
var averages []float32
var histograms [][]int
for _, method := range placeMethods {
resultsC := make(chan int, maxTrials)
var eg errgroup.Group
eg.SetLimit(parallelism)
var resultsS []int
for i := 0; i < maxTrials; i++ {
g := game.NewGame()
eg.Go(func() error {
playGame(&g, resultsC, method)
return nil
})
}
go func() {
eg.Wait()
close(resultsC)
}()
for r := range resultsC {
resultsS = append(resultsS, r)
}
averages = append(averages, utils.Average(resultsS))
histograms = append(histograms, utils.Histogram(resultsS, 20))
}
fmt.Printf("Trials: %d\n", maxTrials)
for i, name := range placeMethodNames {
fmt.Printf("Average for %s: %f\n", name, averages[i])
fmt.Printf("Histogram for %s: %v\n", name, histograms[i])
}
elapsed := time.Since(start)
fmt.Printf("\nSimulate took %s", elapsed)
}