Bläddra i källkod

feat: get best guess, with refactoring

Alex White 5 månader sedan
förälder
incheckning
94fb218930
4 ändrade filer med 175 tillägg och 17 borttagningar
  1. 27 14
      fallout.go
  2. 130 3
      fallout_test.go
  3. 8 0
      go.mod
  4. 10 0
      go.sum

+ 27 - 14
fallout.go

@@ -33,20 +33,25 @@ func main() {
 		os.Exit(1)
 	}
 
-	err = game.printSortedScores()
+	_, err = game.printSortedScores()
 	if err != nil {
 		fmt.Printf("Error printing sorted scores: %s\n", err)
 		os.Exit(1)
 	}
 
 	for i := 0; i < 3; i++ {
-		// get guess and Score from stdin
 		guess, score := getGuessAndScoreFromStdin()
 		fmt.Printf("Guess: %s, Score: %d\n", guess, score)
 
 		game.FilterWords(guess, score)
 
-		err = game.printSortedScores()
+		err = game.scoreWordsByCommonLetterLocations()
+		if err != nil {
+			fmt.Printf("Error scoring Words: %s\n", err)
+			os.Exit(1)
+		}
+
+		_, err = game.printSortedScores()
 		if err != nil {
 			fmt.Printf("Error printing sorted scores: %s\n", err)
 			os.Exit(1)
@@ -59,9 +64,6 @@ func main() {
 			}
 		}
 	}
-
-	// iterate through multiple turns
-
 }
 
 func NewGame() *Game {
@@ -108,7 +110,21 @@ func getGuessAndScoreFromStdin() (string, int) {
 	return guess, score
 }
 
-func (g Game) printSortedScores() error {
+func (g Game) printSortedScores() (string, error) {
+
+	sortedWordScores := g.getSortedScores()
+
+	fmt.Println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
+	fmt.Print("Words sorted by Score:\n")
+	for _, word := range sortedWordScores {
+		fmt.Printf("%s: %d\n", word, g.Words[word].Score)
+	}
+	fmt.Println("")
+
+	return sortedWordScores[0], nil
+}
+
+func (g Game) getSortedScores() []string {
 
 	var sortedWordScores []string
 
@@ -121,14 +137,11 @@ func (g Game) printSortedScores() error {
 		return g.Words[sortedWordScores[i]].Score > g.Words[sortedWordScores[j]].Score
 	})
 
-	fmt.Println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
-	fmt.Print("Words sorted by Score:\n")
-	for _, word := range sortedWordScores {
-		fmt.Printf("%s: %d\n", word, g.Words[word].Score)
-	}
-	fmt.Println("")
+	return sortedWordScores
+}
 
-	return nil
+func (g Game) getBestGuess() (string, error) {
+	return g.getSortedScores()[0], nil
 }
 
 func (g Game) scoreWordsByCommonLetterLocations() error {

+ 130 - 3
fallout_test.go

@@ -1,6 +1,8 @@
 package main
 
 import (
+	"fmt"
+	"github.com/stretchr/testify/assert"
 	"testing"
 )
 
@@ -156,6 +158,33 @@ func TestGame_FilterWords(t *testing.T) {
 				"bbc": {Word: "bbc"},
 			},
 		},
+		{
+			name: "real world case",
+			fields: fields{
+				Words: map[string]*Word{
+					"pleads": {Word: "pleads", Score: 13},
+					"crimes": {Word: "crimes", Score: 16},
+					"fierce": {Word: "fierce", Score: 12},
+					"wagons": {Word: "wagons", Score: 14},
+					"shiner": {Word: "shiner", Score: 14},
+					"wastes": {Word: "wastes", Score: 20},
+					"tables": {Word: "tables", Score: 17},
+					"ripped": {Word: "ripped", Score: 14},
+					"silver": {Word: "silver", Score: 16},
+					"insane": {Word: "insane", Score: 13},
+					"visage": {Word: "visage", Score: 15},
+				},
+			},
+			args: args{guess: "wastes", score: 1},
+			want: map[string]*Word{
+				"pleads": {Word: "pleads", Score: 13},
+				"insane": {Word: "insane", Score: 13},
+				"shiner": {Word: "shiner", Score: 14},
+				"visage": {Word: "visage", Score: 15},
+				"silver": {Word: "silver", Score: 16},
+				"ripped": {Word: "ripped", Score: 14},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -164,15 +193,113 @@ func TestGame_FilterWords(t *testing.T) {
 				Length: tt.fields.Length,
 			}
 			g.FilterWords(tt.args.guess, tt.args.score)
-			if len(g.Words) != len(tt.want) {
-				t.Errorf("Expected %d Words, got %d", len(tt.want), len(g.Words))
-			}
+
+			fmt.Printf("Want: %v\n", tt.want)
+			fmt.Printf("Got: %v\n", g.Words)
+
 			for word := range tt.want {
 				if _, ok := g.Words[word]; !ok {
 					t.Errorf("Word %s was removed, expected it to remain", word)
 				}
 			}
 
+			assert.Equal(t, len(tt.want), len(g.Words), "Wrong number of matches")
+
+		})
+	}
+}
+
+func TestGame_getBestGuess(t *testing.T) {
+	type fields struct {
+		Words  map[string]*Word
+		Length int
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    string
+		wantErr bool
+	}{
+		{
+			name: "simple case",
+			fields: fields{
+				Words: map[string]*Word{
+					"aaa": {Word: "aaa", Score: 3},
+					"aab": {Word: "aab", Score: 2},
+					"caa": {Word: "caa", Score: 2},
+				},
+			},
+			want: "aaa",
+		},
+		{
+			name: "real-world case",
+			fields: fields{
+				Words: map[string]*Word{
+					"pleads": {Word: "pleads", Score: 13},
+					"crimes": {Word: "crimes", Score: 16},
+					"fierce": {Word: "fierce", Score: 12},
+					"wagons": {Word: "wagons", Score: 14},
+					"shiner": {Word: "shiner", Score: 14},
+					"wastes": {Word: "wastes", Score: 20},
+					"tables": {Word: "tables", Score: 17},
+					"ripped": {Word: "ripped", Score: 14},
+					"silver": {Word: "silver", Score: 16},
+					"visage": {Word: "visage", Score: 15},
+					"insane": {Word: "insane", Score: 13},
+				},
+			},
+			want: "wastes",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			g := Game{
+				Words:  tt.fields.Words,
+				Length: tt.fields.Length,
+			}
+			got, err := g.getBestGuess()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getBestGuess() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("getBestGuess() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGame_getSortedScores(t *testing.T) {
+	type fields struct {
+		Words map[string]*Word
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   []string
+	}{
+		{
+			name: "sort words by scores",
+			fields: fields{
+				Words: map[string]*Word{
+					"pleads": {Word: "pleads", Score: 13},
+					"crimes": {Word: "crimes", Score: 16},
+					"fierce": {Word: "fierce", Score: 12},
+					"shiner": {Word: "shiner", Score: 14},
+					"wastes": {Word: "wastes", Score: 20},
+					"tables": {Word: "tables", Score: 17},
+					"visage": {Word: "visage", Score: 15},
+				},
+			},
+			want: []string{"wastes", "tables", "crimes", "visage", "shiner", "pleads", "fierce"},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			g := Game{
+				Words: tt.fields.Words,
+			}
+			assert.Equalf(t, tt.want, g.getSortedScores(), "getSortedScores()")
 		})
 	}
 }

+ 8 - 0
go.mod

@@ -1,3 +1,11 @@
 module fallout
 
 go 1.22.0
+
+require github.com/stretchr/testify v1.9.0
+
+require (
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 10 - 0
go.sum

@@ -0,0 +1,10 @@
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=