|
@@ -0,0 +1,143 @@
|
|
|
|
+package main
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "fmt"
|
|
|
|
+ "os"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+type Simulation struct {
|
|
|
|
+ Game *Game
|
|
|
|
+ BestGuess string
|
|
|
|
+ BestGuessRounds int
|
|
|
|
+ SuccessCount int
|
|
|
|
+ FailCount int
|
|
|
|
+ TotalRounds int
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func NewSimulator(g Game) *Simulation {
|
|
|
|
+ return &Simulation{
|
|
|
|
+ Game: &g,
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s Simulation) SimulateAllPossibleGames() error {
|
|
|
|
+
|
|
|
|
+ bestGuessLossCount := 99
|
|
|
|
+ bestGuessTotalRounds := 99
|
|
|
|
+
|
|
|
|
+ wordLossCounts := make(map[string]int)
|
|
|
|
+ totalRounds := make(map[string]int)
|
|
|
|
+
|
|
|
|
+ for initialWord := range s.Game.Words {
|
|
|
|
+ fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
|
|
|
+ lossCount, totalRoundCount := s.SimulateOneGame(initialWord)
|
|
|
|
+ wordLossCounts[initialWord] = lossCount
|
|
|
|
+ totalRounds[initialWord] = totalRoundCount
|
|
|
|
+ if lossCount < bestGuessLossCount {
|
|
|
|
+ bestGuessLossCount = lossCount
|
|
|
|
+ bestGuessTotalRounds = totalRoundCount
|
|
|
|
+ } else if lossCount == bestGuessLossCount && totalRoundCount < bestGuessTotalRounds {
|
|
|
|
+ bestGuessTotalRounds = totalRoundCount
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
|
|
|
+
|
|
|
|
+ err := s.Game.scoreWordsByCommonLetterLocations()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return fmt.Errorf("Error scoring Words: %s", err)
|
|
|
|
+ }
|
|
|
|
+ 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])
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s Simulation) SimulateOneGame(initialWord string) (int, int) {
|
|
|
|
+
|
|
|
|
+ lossCount := 0
|
|
|
|
+ totalRounds := 0
|
|
|
|
+ maxRounds := 4
|
|
|
|
+
|
|
|
|
+ANSWER_LOOP:
|
|
|
|
+ for answer := range s.Game.Words {
|
|
|
|
+
|
|
|
|
+ simulatedGame := NewGame()
|
|
|
|
+ simulatedGame.Words = make(map[string]*Word)
|
|
|
|
+ for word := range s.Game.Words {
|
|
|
|
+ simulatedGame.Words[word] = &Word{Word: word}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ guess := initialWord
|
|
|
|
+
|
|
|
|
+ for guessRounds := 1; guessRounds <= maxRounds; guessRounds++ {
|
|
|
|
+
|
|
|
|
+ totalRounds++
|
|
|
|
+
|
|
|
|
+ if guess == answer {
|
|
|
|
+ fmt.Printf("Rounds: %d Initial Word: %s Target Word: %s\n", guessRounds, initialWord, answer)
|
|
|
|
+ if guessRounds > maxRounds {
|
|
|
|
+ lossCount++
|
|
|
|
+ }
|
|
|
|
+ continue ANSWER_LOOP
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ score := s.getScore(guess, answer)
|
|
|
|
+ //fmt.Printf("Score: %d\n", score)
|
|
|
|
+
|
|
|
|
+ simulatedGame.FilterWords(guess, score)
|
|
|
|
+ //fmt.Printf("Words remaining: %+v\n", simulatedGame.Words)
|
|
|
|
+
|
|
|
|
+ err := simulatedGame.scoreWordsByCommonLetterLocations()
|
|
|
|
+ if err != nil {
|
|
|
|
+ fmt.Printf("Error scoring Words: %s\n", err)
|
|
|
|
+ os.Exit(1)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(simulatedGame.Words) == 1 {
|
|
|
|
+ //fmt.Printf("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)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if guessRounds > maxRounds {
|
|
|
|
+ lossCount++
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fmt.Printf("Rounds: %d Initial Word: %s Target Word: %s\n", guessRounds, initialWord, answer)
|
|
|
|
+ continue ANSWER_LOOP
|
|
|
|
+ }
|
|
|
|
+ } 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)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ fmt.Printf("\nInitial Word: %s Loss Count: %d Total Rounds: %d\n", initialWord, lossCount, totalRounds)
|
|
|
|
+
|
|
|
|
+ return lossCount, totalRounds
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s Simulation) getScore(guess string, answer string) int {
|
|
|
|
+ score := 0
|
|
|
|
+
|
|
|
|
+ for idx, letter := range answer {
|
|
|
|
+ if string(letter) == string(guess[idx]) {
|
|
|
|
+ score++
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return score
|
|
|
|
+}
|