Browse Source

refactor: extract methods and tests

Alex White 6 months ago
parent
commit
32d7c673de
5 changed files with 186 additions and 175 deletions
  1. 0 127
      fallout.go
  2. 116 0
      game.go
  3. 1 48
      game_test.go
  4. 19 0
      word.go
  5. 50 0
      word_test.go

+ 0 - 127
fallout.go

@@ -4,19 +4,8 @@ import (
 	"bufio"
 	"fmt"
 	"os"
-	"sort"
 )
 
-type Game struct {
-	Words  map[string]*Word
-	Length int
-}
-
-type Word struct {
-	Word  string
-	Score int
-}
-
 func main() {
 
 	game := NewGame()
@@ -66,33 +55,6 @@ func main() {
 	}
 }
 
-func NewGame() *Game {
-	return &Game{
-		Words: make(map[string]*Word),
-	}
-}
-
-func (g Game) FilterWords(guess string, score int) {
-	for _, word := range g.Words {
-		if !word.MatchesGuess(guess, score) {
-			delete(g.Words, word.Word)
-		}
-	}
-}
-
-func (w Word) MatchesGuess(guess string, numMatchingChars int) bool {
-
-	score := 0
-
-	for idx, letter := range w.Word {
-		if string(letter) == string(guess[idx]) {
-			score++
-		}
-	}
-
-	return score == numMatchingChars
-}
-
 func getGuessAndScoreFromStdin() (string, int) {
 	reader := bufio.NewReader(os.Stdin)
 	fmt.Print("Enter Guess: ")
@@ -109,92 +71,3 @@ func getGuessAndScoreFromStdin() (string, int) {
 
 	return guess, score
 }
-
-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
-
-	for _, word := range g.Words {
-		sortedWordScores = append(sortedWordScores, word.Word)
-	}
-
-	// sort words by score
-	sort.Slice(sortedWordScores, func(i, j int) bool {
-		return g.Words[sortedWordScores[i]].Score > g.Words[sortedWordScores[j]].Score
-	})
-
-	return sortedWordScores
-}
-
-func (g Game) getBestGuess() (string, error) {
-	return g.getSortedScores()[0], nil
-}
-
-func (g Game) scoreWordsByCommonLetterLocations() error {
-	letterIdxScores := make(map[int]map[string]int)
-
-	var lastWord string
-	for _, word := range g.Words {
-		word.Score = 0
-		lastWord = word.Word
-	}
-
-	for idx := range lastWord {
-		letterIdxScores[idx] = make(map[string]int)
-	}
-
-	for _, word := range g.Words {
-		for idx, letter := range word.Word {
-			letterIdxScores[idx][string(letter)]++
-		}
-	}
-
-	for _, word := range g.Words {
-		for idx, letter := range word.Word {
-			word.Score += letterIdxScores[idx][string(letter)]
-		}
-	}
-
-	return nil
-}
-
-func (g Game) getWordsFromStdin() error {
-
-	fmt.Println("Enter Words, one per line. Enter a period to end input.")
-
-	for {
-		reader := bufio.NewReader(os.Stdin)
-		word, _ := reader.ReadString('\n')
-		word = word[:len(word)-1]
-		if word == "." {
-			fmt.Println("got Words!")
-			break
-		}
-
-		if g.Length == 0 {
-			g.Length = len(word)
-		} else {
-			if len(word) != g.Length {
-				fmt.Printf("Error: All words must be the same length (%d), skipping: %s\n", g.Length, word)
-				continue
-			}
-		}
-		g.Words[word] = &Word{Word: word}
-	}
-
-	return nil
-}

+ 116 - 0
game.go

@@ -0,0 +1,116 @@
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+	"sort"
+)
+
+type Game struct {
+	Words  map[string]*Word
+	Length int
+}
+
+func NewGame() *Game {
+	return &Game{
+		Words: make(map[string]*Word),
+	}
+}
+
+func (g Game) scoreWordsByCommonLetterLocations() error {
+	letterIdxScores := make(map[int]map[string]int)
+
+	var lastWord string
+	for _, word := range g.Words {
+		word.Score = 0
+		lastWord = word.Word
+	}
+
+	for idx := range lastWord {
+		letterIdxScores[idx] = make(map[string]int)
+	}
+
+	for _, word := range g.Words {
+		for idx, letter := range word.Word {
+			letterIdxScores[idx][string(letter)]++
+		}
+	}
+
+	for _, word := range g.Words {
+		for idx, letter := range word.Word {
+			word.Score += letterIdxScores[idx][string(letter)]
+		}
+	}
+
+	return nil
+}
+
+func (g Game) FilterWords(guess string, score int) {
+	for _, word := range g.Words {
+		if !word.MatchesGuess(guess, score) {
+			delete(g.Words, word.Word)
+		}
+	}
+}
+
+func (g Game) getSortedScores() []string {
+
+	var sortedWordScores []string
+
+	for _, word := range g.Words {
+		sortedWordScores = append(sortedWordScores, word.Word)
+	}
+
+	// sort words by score
+	sort.Slice(sortedWordScores, func(i, j int) bool {
+		return g.Words[sortedWordScores[i]].Score > g.Words[sortedWordScores[j]].Score
+	})
+
+	return sortedWordScores
+}
+
+func (g Game) getBestGuess() (string, error) {
+	return g.getSortedScores()[0], nil
+}
+
+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) getWordsFromStdin() error {
+
+	fmt.Println("Enter Words, one per line. Enter a period to end input.")
+
+	for {
+		reader := bufio.NewReader(os.Stdin)
+		word, _ := reader.ReadString('\n')
+		word = word[:len(word)-1]
+		if word == "." {
+			fmt.Println("got Words!")
+			break
+		}
+
+		if g.Length == 0 {
+			g.Length = len(word)
+		} else {
+			if len(word) != g.Length {
+				fmt.Printf("Error: All words must be the same length (%d), skipping: %s\n", g.Length, word)
+				continue
+			}
+		}
+		g.Words[word] = &Word{Word: word}
+	}
+
+	return nil
+}

+ 1 - 48
fallout_test.go → game_test.go

@@ -6,7 +6,7 @@ import (
 	"testing"
 )
 
-func Test_scoreWordsByCommonLetterLocations(t *testing.T) {
+func TestGame_scoreWordsByCommonLetterLocations(t *testing.T) {
 	type args struct {
 		words []string
 	}
@@ -53,53 +53,6 @@ func Test_scoreWordsByCommonLetterLocations(t *testing.T) {
 	}
 }
 
-func TestWord_MatchesGuess(t *testing.T) {
-	type fields struct {
-		Word  string
-		Score int
-	}
-	type args struct {
-		guess            string
-		numMatchingChars int
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		args   args
-		want   bool
-	}{
-		{
-			name:   "no letters in common",
-			fields: fields{Word: "aaa"},
-			args:   args{guess: "bbb", numMatchingChars: 0},
-			want:   true,
-		},
-		{
-			name:   "one letter in common",
-			fields: fields{Word: "aaa"},
-			args:   args{guess: "abb", numMatchingChars: 1},
-			want:   true,
-		},
-		{
-			name:   "one letter in common where expecting 2",
-			fields: fields{Word: "aaa"},
-			args:   args{guess: "aba", numMatchingChars: 1},
-			want:   false,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			w := Word{
-				Word:  tt.fields.Word,
-				Score: tt.fields.Score,
-			}
-			if got := w.MatchesGuess(tt.args.guess, tt.args.numMatchingChars); got != tt.want {
-				t.Errorf("MatchesGuess() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
 func TestGame_FilterWords(t *testing.T) {
 	type fields struct {
 		Words  map[string]*Word

+ 19 - 0
word.go

@@ -0,0 +1,19 @@
+package main
+
+type Word struct {
+	Word  string
+	Score int
+}
+
+func (w Word) MatchesGuess(guess string, numMatchingChars int) bool {
+
+	score := 0
+
+	for idx, letter := range w.Word {
+		if string(letter) == string(guess[idx]) {
+			score++
+		}
+	}
+
+	return score == numMatchingChars
+}

+ 50 - 0
word_test.go

@@ -0,0 +1,50 @@
+package main
+
+import "testing"
+
+func TestWord_MatchesGuess(t *testing.T) {
+	type fields struct {
+		Word  string
+		Score int
+	}
+	type args struct {
+		guess            string
+		numMatchingChars int
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   bool
+	}{
+		{
+			name:   "no letters in common",
+			fields: fields{Word: "aaa"},
+			args:   args{guess: "bbb", numMatchingChars: 0},
+			want:   true,
+		},
+		{
+			name:   "one letter in common",
+			fields: fields{Word: "aaa"},
+			args:   args{guess: "abb", numMatchingChars: 1},
+			want:   true,
+		},
+		{
+			name:   "one letter in common where expecting 2",
+			fields: fields{Word: "aaa"},
+			args:   args{guess: "aba", numMatchingChars: 1},
+			want:   false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			w := Word{
+				Word:  tt.fields.Word,
+				Score: tt.fields.Score,
+			}
+			if got := w.MatchesGuess(tt.args.guess, tt.args.numMatchingChars); got != tt.want {
+				t.Errorf("MatchesGuess() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}