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 }