diff --git a/.golangci.yaml b/.golangci.yaml index 9fec5d7..abd9e7a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -25,8 +25,4 @@ linters: linters-settings: varnamelen: ignore-names: - - id - - db - ignore-decls: - - w http.ResponseWriter - - r *http.Request + - i diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/lib/gordle/gordle.go b/lib/gordle/gordle.go index e278432..0d26059 100644 --- a/lib/gordle/gordle.go +++ b/lib/gordle/gordle.go @@ -10,6 +10,14 @@ import ( var ErrWordNotFound = errors.New("word not found with requested length") +const ( + FeedbackNotInWord = Feedback("N") + FeedbackWrongPlace = Feedback("W") + FeedbackCorrect = Feedback("C") +) + +type Feedback string + func GetWord(reader *strings.Reader, wordLength int) (string, error) { var candidates []string @@ -34,3 +42,37 @@ func GetWord(reader *strings.Reader, wordLength int) (string, error) { return candidates[rnd], nil } + +func CheckWord(word, input string) []Feedback { + wordRunes := []rune(word) + inputRunes := []rune(input) + res := []Feedback{} + + counter := map[rune]int{} + + for _, r := range wordRunes { + counter[r]++ + } + + for i, wordRune := range wordRunes { + if i >= len(inputRunes) { + res = append(res, FeedbackNotInWord) + continue + } + + inputRune := inputRunes[i] + + switch { + case wordRune == inputRune: + res = append(res, FeedbackCorrect) + counter[wordRune]-- + case counter[inputRune] > 0: + res = append(res, FeedbackWrongPlace) + counter[inputRune]-- + default: + res = append(res, FeedbackNotInWord) + } + } + + return res +} diff --git a/lib/gordle/gordle_test.go b/lib/gordle/gordle_test.go index 5cb5136..c9eb522 100644 --- a/lib/gordle/gordle_test.go +++ b/lib/gordle/gordle_test.go @@ -2,6 +2,7 @@ package gordle_test import ( "errors" + "reflect" "strings" "testing" @@ -36,3 +37,45 @@ func TestGetWord(t *testing.T) { }) } } + +func TestTryWord(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + word string + input string + want []gordle.Feedback + }{ + {"empty", "", "", []gordle.Feedback{}}, + {"missing input", "i", "", []gordle.Feedback{gordle.FeedbackNotInWord}}, + {"correct single", "i", "i", []gordle.Feedback{gordle.FeedbackCorrect}}, + {"incorrect place", "ab", "ba", []gordle.Feedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace}}, + { + "some correct some incorrect", "aba", "baa", + []gordle.Feedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace, gordle.FeedbackCorrect}, + }, + { + "complex", "testing", "xsesing", + []gordle.Feedback{ + gordle.FeedbackNotInWord, + gordle.FeedbackWrongPlace, + gordle.FeedbackWrongPlace, + gordle.FeedbackNotInWord, + gordle.FeedbackCorrect, + gordle.FeedbackCorrect, + gordle.FeedbackCorrect, + }, + }, + } + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + t.Parallel() + got := gordle.CheckWord(test.word, test.input) + if !reflect.DeepEqual(got, test.want) { + t.Errorf("got %q, want %q", got, test.want) + } + }) + } +}