|
@@ -20,114 +20,160 @@ func NewSimulator(g Game) *Simulation {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-func (s Simulation) SimulateAllPossibleGames() error {
|
|
|
+func (s Simulation) SimulateAllPossibleGames() (string, error) {
|
|
|
|
|
|
bestGuessLossCount := 99
|
|
|
bestGuessTotalRounds := 99
|
|
|
|
|
|
wordLossCounts := make(map[string]int)
|
|
|
- totalRounds := make(map[string]int)
|
|
|
+ maxRoundCounts := make(map[string]int)
|
|
|
|
|
|
for initialWord := range s.Game.Words {
|
|
|
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
|
|
- lossCount, totalRoundCount := s.SimulateOneGame(initialWord)
|
|
|
+
|
|
|
+ simulatedGame := NewGame()
|
|
|
+ simulatedGame.Words = make(map[string]*Word)
|
|
|
+ for word := range s.Game.Words {
|
|
|
+ simulatedGame.Words[word] = &Word{Word: word}
|
|
|
+ }
|
|
|
+
|
|
|
+ lossCount, maxRounds, _ := s.SimulateOneInitialWord(simulatedGame, initialWord)
|
|
|
wordLossCounts[initialWord] = lossCount
|
|
|
- totalRounds[initialWord] = totalRoundCount
|
|
|
+ maxRoundCounts[initialWord] = maxRounds
|
|
|
if lossCount < bestGuessLossCount {
|
|
|
bestGuessLossCount = lossCount
|
|
|
- bestGuessTotalRounds = totalRoundCount
|
|
|
- } else if lossCount == bestGuessLossCount && totalRoundCount < bestGuessTotalRounds {
|
|
|
- bestGuessTotalRounds = totalRoundCount
|
|
|
+ bestGuessTotalRounds = maxRounds
|
|
|
+ } else if lossCount == bestGuessLossCount && maxRounds < bestGuessTotalRounds {
|
|
|
+ bestGuessTotalRounds = maxRounds
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
|
|
|
|
|
err := s.Game.scoreWordsByCommonLetterLocations()
|
|
|
if err != nil {
|
|
|
- return fmt.Errorf("Error scoring Words: %s", err)
|
|
|
+ return "", fmt.Errorf("Error scoring Words: %s", err)
|
|
|
}
|
|
|
+
|
|
|
+ var bestGuess string
|
|
|
for _, word := range s.Game.getSortedScores() {
|
|
|
- if wordLossCounts[word] == bestGuessLossCount && totalRounds[word] == bestGuessTotalRounds {
|
|
|
- fmt.Printf("\nBest Guess: %s Failed Branches: %d Total Rounds: %d\n\n", word, bestGuessLossCount, totalRounds[word])
|
|
|
+ if wordLossCounts[word] == bestGuessLossCount && maxRoundCounts[word] == bestGuessTotalRounds {
|
|
|
+ fmt.Printf("\nBest Guess: %s Failed Branches: %d Max Rounds: %d\n\n", word, bestGuessLossCount, maxRoundCounts[word])
|
|
|
+ bestGuess = word
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return nil
|
|
|
+ return bestGuess, nil
|
|
|
}
|
|
|
|
|
|
-func (s Simulation) SimulateOneGame(initialWord string) (int, int) {
|
|
|
+func (s Simulation) SimulateOneInitialWord(game *Game, initialWord string) (lossCount, maxRounds, totalRounds int) {
|
|
|
|
|
|
- lossCount := 0
|
|
|
- totalRounds := 0
|
|
|
- maxRounds := 4
|
|
|
+ debugPrint("Initial Word: %s\n", initialWord)
|
|
|
|
|
|
-ANSWER_LOOP:
|
|
|
for answer := range s.Game.Words {
|
|
|
|
|
|
+ debugPrint(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
|
|
+
|
|
|
+ debugPrint("Target Word: %s\n", answer)
|
|
|
+
|
|
|
simulatedGame := NewGame()
|
|
|
simulatedGame.Words = make(map[string]*Word)
|
|
|
- for word := range s.Game.Words {
|
|
|
+ for word := range game.Words {
|
|
|
simulatedGame.Words[word] = &Word{Word: word}
|
|
|
}
|
|
|
|
|
|
- guess := initialWord
|
|
|
+ won, rounds := s.SimulateOneGame(simulatedGame, initialWord, answer)
|
|
|
+ if !won {
|
|
|
+ lossCount++
|
|
|
+ }
|
|
|
+ totalRounds += rounds
|
|
|
+ if rounds > maxRounds {
|
|
|
+ maxRounds = rounds
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ fmt.Printf("Summary: Initial Word: %s Loss Count: %d Max Rounds: %d Total Rounds: %d\n", initialWord, lossCount, maxRounds, totalRounds)
|
|
|
|
|
|
- for guessRounds := 1; guessRounds <= maxRounds; guessRounds++ {
|
|
|
+ return lossCount, maxRounds, totalRounds
|
|
|
+}
|
|
|
|
|
|
- totalRounds++
|
|
|
+func (s Simulation) SimulateOneGame(simulatedGame *Game, initialWord, answer string) (bool, int) {
|
|
|
|
|
|
- if guess == answer {
|
|
|
- fmt.Printf("Rounds: %d Initial Word: %s Target Word: %s\n", guessRounds, initialWord, answer)
|
|
|
- if guessRounds > maxRounds {
|
|
|
- lossCount++
|
|
|
- }
|
|
|
- continue ANSWER_LOOP
|
|
|
- }
|
|
|
+ guess := initialWord
|
|
|
|
|
|
- score := s.getScore(guess, answer)
|
|
|
- //fmt.Printf("Score: %d\n", score)
|
|
|
+ // 10 rounds max just to prevent infinite loops
|
|
|
+ var round int
|
|
|
+ for round = 1; round <= 10; round++ {
|
|
|
|
|
|
- simulatedGame.FilterWords(guess, score)
|
|
|
- //fmt.Printf("Words remaining: %+v\n", simulatedGame.Words)
|
|
|
+ if round == 1 {
|
|
|
+ debugPrint("First guess, initial Word: %s\n", initialWord)
|
|
|
|
|
|
- err := simulatedGame.scoreWordsByCommonLetterLocations()
|
|
|
+ } else {
|
|
|
+
|
|
|
+ //simulatedSubGame := NewGame()
|
|
|
+ //simulatedSubGame.Words = make(map[string]*Word)
|
|
|
+ //for word := range simulatedGame.Words {
|
|
|
+ // simulatedSubGame.Words[word] = &Word{Word: word}
|
|
|
+ //}
|
|
|
+ //subSimulator := NewSimulator(*simulatedSubGame)
|
|
|
+ //
|
|
|
+ //var err error
|
|
|
+ //guess, err = subSimulator.SimulateAllPossibleGames()
|
|
|
+ //if err != nil {
|
|
|
+ // fmt.Printf("Error simulating all possible games: %s\n", err)
|
|
|
+ // os.Exit(1)
|
|
|
+ //}
|
|
|
+
|
|
|
+ var err error
|
|
|
+ guess, err = simulatedGame.getBestGuess()
|
|
|
if err != nil {
|
|
|
- fmt.Printf("Error scoring Words: %s\n", err)
|
|
|
+ fmt.Printf("Error calculating best guess: %s\n", err)
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
+ debugPrint("Round %d, guess: %s\n", round, guess)
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- if len(simulatedGame.Words) == 1 {
|
|
|
- //fmt.Printf("The word is: %s\n", guess)
|
|
|
- for word := range simulatedGame.Words {
|
|
|
+ score := s.getScore(guess, answer)
|
|
|
+ debugPrint("guess '%s' matches %d locations in answer '%s'\n", guess, score, answer)
|
|
|
|
|
|
- if word != answer {
|
|
|
- fmt.Printf("Incorrectly guessed word: %s => This should never happen!\n", word)
|
|
|
- os.Exit(1)
|
|
|
- }
|
|
|
+ simulatedGame.FilterWords(guess, score)
|
|
|
+ debugPrint("Words remaining after filtering: %+v\n", simulatedGame.Words)
|
|
|
|
|
|
- if guessRounds > maxRounds {
|
|
|
- lossCount++
|
|
|
- }
|
|
|
+ if guess == answer {
|
|
|
+ break
|
|
|
+ }
|
|
|
|
|
|
- fmt.Printf("Rounds: %d Initial Word: %s Target Word: %s\n", guessRounds, initialWord, answer)
|
|
|
- continue ANSWER_LOOP
|
|
|
+ if len(simulatedGame.Words) == 1 {
|
|
|
+ debugPrint("The word is: %s\n", guess)
|
|
|
+ for word := range simulatedGame.Words {
|
|
|
+
|
|
|
+ if word != answer {
|
|
|
+ fmt.Printf("Incorrectly guessed word: %s => This should never happen!\n", word)
|
|
|
+ os.Exit(1)
|
|
|
}
|
|
|
- } else {
|
|
|
- //fmt.Printf("Number of words remaining: %d\n", len(simulatedGame.Words))
|
|
|
- }
|
|
|
|
|
|
- guess, err = simulatedGame.getBestGuess()
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("Error calculating best guess: %s\n", err)
|
|
|
- os.Exit(1)
|
|
|
+ break
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ err := simulatedGame.scoreWordsByCommonLetterLocations()
|
|
|
+ if err != nil {
|
|
|
+ fmt.Printf("Error scoring Words: %s\n", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+
|
|
|
+ debugPrint("End round %d, not solved, %d words remaining\n", round, len(simulatedGame.Words))
|
|
|
+ }
|
|
|
+
|
|
|
+ if round > 4 {
|
|
|
+ fmt.Printf("Loss: Matched in %d rounds => Initial Word: %s Target Word: %s\n", round, initialWord, answer)
|
|
|
+ return false, round
|
|
|
}
|
|
|
- fmt.Printf("\nInitial Word: %s Loss Count: %d Total Rounds: %d\n", initialWord, lossCount, totalRounds)
|
|
|
|
|
|
- return lossCount, totalRounds
|
|
|
+ fmt.Printf("Win: Matched in %d rounds => Initial Word: %s Target Word: %s\n", round, initialWord, answer)
|
|
|
+ return true, round
|
|
|
}
|
|
|
|
|
|
func (s Simulation) getScore(guess string, answer string) int {
|