浏览代码

feat: game setup

Alex White 7 月之前
当前提交
c799059d0c
共有 4 个文件被更改,包括 186 次插入0 次删除
  1. 1 0
      .gitignore
  2. 130 0
      fallout.go
  3. 52 0
      fallout_test.go
  4. 3 0
      go.mod

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.idea

+ 130 - 0
fallout.go

@@ -0,0 +1,130 @@
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+	"sort"
+)
+
+type Game struct {
+	Words map[string]*Word
+}
+
+type Word struct {
+	Word  string
+	Score int
+}
+
+func main() {
+
+	game := NewGame()
+
+	err := game.getWordsFromStdin()
+	if err != nil {
+		fmt.Printf("Error getting Words from stdin: %s\n", err)
+		os.Exit(1)
+	}
+
+	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)
+	}
+
+	// get guess and Score from stdin
+
+	// remove Words that don't match guess and Score
+
+}
+
+func NewGame() *Game {
+	return &Game{
+		Words: make(map[string]*Word),
+	}
+}
+
+func (g Game) printSortedScores() error {
+
+	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
+	})
+
+	fmt.Print("\nWords sorted by Score:\n")
+	for _, word := range sortedWordScores {
+		fmt.Printf("%s: %d\n", word, g.Words[word].Score)
+	}
+	fmt.Println("")
+
+	return 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.")
+
+	wordLen := 0
+
+	for {
+		reader := bufio.NewReader(os.Stdin)
+		word, _ := reader.ReadString('\n')
+		word = word[:len(word)-1]
+		if word == "." {
+			fmt.Println("got Words!")
+			break
+		}
+
+		if wordLen == 0 {
+			wordLen = len(word)
+		} else {
+			if len(word) != wordLen {
+				fmt.Printf("Error: All words must be the same length (%d), skipping: %s\n", wordLen, word)
+				continue
+			}
+		}
+		g.Words[word] = &Word{Word: word}
+	}
+
+	return nil
+}

+ 52 - 0
fallout_test.go

@@ -0,0 +1,52 @@
+package main
+
+import (
+	"testing"
+)
+
+func Test_scoreWordsByCommonLetterLocations(t *testing.T) {
+	type args struct {
+		words []string
+	}
+	tests := []struct {
+		name string
+		args args
+		want map[string]int
+	}{
+		{
+			name: "no letters in common",
+			args: args{words: []string{"aaa", "bbb"}},
+			want: map[string]int{"aaa": 3, "bbb": 3},
+		},
+		{
+			name: "one letter in common",
+			args: args{words: []string{"aaa", "abb"}},
+			want: map[string]int{"aaa": 4, "abb": 4},
+		},
+		{
+			name: "three Words with some letters in common",
+			args: args{words: []string{"aaa", "abb", "aab"}},
+			want: map[string]int{"aaa": 6, "abb": 6, "aab": 7},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			game := NewGame()
+			for _, word := range tt.args.words {
+				game.Words[word] = &Word{Word: word}
+			}
+
+			err := game.scoreWordsByCommonLetterLocations()
+			if err != nil {
+				t.Errorf("Error scoring Words: %s\n", err)
+				t.FailNow()
+			}
+
+			for word, score := range tt.want {
+				if game.Words[word].Score != score {
+					t.Errorf("Word %s has score %d, expected %d", word, game.Words[word].Score, score)
+				}
+			}
+		})
+	}
+}

+ 3 - 0
go.mod

@@ -0,0 +1,3 @@
+module fallout
+
+go 1.22.0