This question already has an answer here:
I am writing a probability model that will take any number of "Outcome"s, then when a number is rolled and passed into the model the correct "Outcome" will be returned;
Essentially the logic is a map of outcomes with indexes representing that outcomes particular weight.
Outcome One 25% Outcome Two 25% Outcome Three 50%
these values will translate to;
outcomes := make(map[int]Outcome)
outcomes[25] = Outcome{"Outcome One", 25}
outcomes[50] = Outcome{"Outcome One", 25}
outcomes[100] = Outcome{"Outcome One", 50}
I have a function that then takes an input lets say 10, and loops around outcomes until the index is larger than the input;
Expected
input: 10, output: Outcome{"Outcome One", 25}
input: 30, output: Outcome{"Outcome Two", 25}
input: 60, output: Outcome{"Outcome Two", 50}
However in my unit tests for an input of 10, I get a combination of "Outcome One" and "Outcome Two", I think the problem lies within my for loop.
ProbabilityMatrix_test.go
var outcome1 = Outcome{"Outcome One", 25}
var outcome2 = Outcome{"Outcome Two", 25}
var outcome3 = Outcome{"Outcome Three", 50}
probabilityMatrix := ProbabilityMatrix{}
probabilityMatrix.SetUp()
probabilityMatrix.AddOutcome(outcome1)
probabilityMatrix.AddOutcome(outcome2)
probabilityMatrix.AddOutcome(outcome3)
outcome := probabilityMatrix.RollA(10)
if outcome != outcome1 {
t.Errorf("%s", probabilityMatrix.Delimiters)
t.Errorf("incorrect outcome, got %s, expected %s", outcome.Name, outcome1.Name)
}
The below code returns Outcome One, around 75% of the time (correct), and Outcome Two 25%
package RealisticTemperatureGenerator
type Outcome struct {
Name string
Probability int
}
type ProbabilityMatrix struct {
Delimiters map[int]Outcome
DefaultOutcome Outcome
Total int
}
func (pm *ProbabilityMatrix) SetUp() {
pm.Delimiters = make(map[int]Outcome)
pm.Total = 0
}
func (pm *ProbabilityMatrix) AddOutcome(outcome Outcome) {
pm.DefaultOutcome = outcome
currentIndex := outcome.Probability + pm.Total
pm.Delimiters[currentIndex] = outcome
pm.Total = currentIndex
}
func (pm *ProbabilityMatrix) RollA(input int) Outcome {
return pm.WalkDelimiters(input)
}
// Problem Possibly here
func (pm ProbabilityMatrix) WalkDelimiters(input int) Outcome {
for key, _ := range pm.Delimiters {
if pm.Delimiters[key].Probability >= input {
return pm.Delimiters[key]
}
}
return pm.DefaultOutcome
}
</div>