diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 64c274f..0af5776 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -21,6 +21,7 @@ func main() { wordLength := flag.Int("l", defaultWordLength, "word length") dictionary := flag.String("f", "", "dictionary file") maxAttempts := flag.Int("m", defaultMaxAttempts, "maximum number of attempts") + cheat := flag.Bool("c", false, "cheat mode (prints word at the beginning)") flag.Parse() @@ -42,22 +43,34 @@ func main() { fmt.Printf("length %d ; you have %d attempts\n", *wordLength, *maxAttempts) + if *cheat { + fmt.Printf("word: %s\n", word) + } + scanner := bufio.NewScanner(os.Stdin) game := gordle.New(*maxAttempts, word) + play(game, scanner, word, wordLength) +} + +func play(game *gordle.Game, scanner *bufio.Scanner, word string, wordLength *int) { for !game.Over() && scanner.Scan() { var feedback gordle.FullFeedback text := strings.ToUpper(scanner.Text()) - feedback, err = game.TryWord(text) - - fmt.Println(feedback) + feedback, err := game.TryWord(text) switch { case errors.Is(err, gordle.ErrGameWon): + fmt.Println(feedback) fmt.Println("🎉 you won") case errors.Is(err, gordle.ErrGameLost): + fmt.Println(feedback) fmt.Printf("😔 you lost, the correct word was %s\n", word) + case errors.Is(err, gordle.ErrRunesCount): + fmt.Printf("🤔 please provide a %d-letters word\n", *wordLength) + default: + fmt.Println(feedback) } } } diff --git a/lib/gordle/gordle.go b/lib/gordle/gordle.go index 25bbb87..67d2191 100644 --- a/lib/gordle/gordle.go +++ b/lib/gordle/gordle.go @@ -13,6 +13,7 @@ var ( ErrWordNotFound = errors.New("word not found with requested length") ErrGameWon = errors.New("won game") ErrGameLost = errors.New("game over") + ErrRunesCount = errors.New("incorrect number of letters") ) type ( @@ -62,7 +63,11 @@ func New(maxAttempts int, pickedWord string) *Game { } func (g *Game) TryWord(word string) (FullFeedback, error) { - feedback := CheckWord(g.pickedWord, word) + feedback, err := CheckWord(g.pickedWord, word) + if err != nil { + return feedback, err + } + if feedback.Wins() { g.over = true return feedback, ErrGameWon @@ -106,9 +111,14 @@ func PickWord(reader io.Reader, wordLength int) (string, error) { return candidates[rnd], nil } -func CheckWord(word, input string) FullFeedback { +func CheckWord(word, input string) (FullFeedback, error) { wordRunes := []rune(word) inputRunes := []rune(input) + + if len(wordRunes) != len(inputRunes) { + return nil, ErrRunesCount + } + res := []Feedback{} counter := map[rune]int{} @@ -137,5 +147,5 @@ func CheckWord(word, input string) FullFeedback { } } - return res + return res, nil } diff --git a/lib/gordle/gordle_test.go b/lib/gordle/gordle_test.go index 7190565..7b605e5 100644 --- a/lib/gordle/gordle_test.go +++ b/lib/gordle/gordle_test.go @@ -42,18 +42,20 @@ func TestCheckWord(t *testing.T) { t.Parallel() tests := []struct { - name string - word string - input string - want gordle.FullFeedback + name string + word string + input string + want gordle.FullFeedback + wantErr error }{ - {"empty", "", "", gordle.FullFeedback{}}, - {"missing input", "i", "", gordle.FullFeedback{gordle.FeedbackNotInWord}}, - {"correct single", "i", "i", gordle.FullFeedback{gordle.FeedbackCorrect}}, - {"incorrect place", "ab", "ba", gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace}}, + {"empty", "", "", gordle.FullFeedback{}, nil}, + {"missing input", "i", "", nil, gordle.ErrRunesCount}, + {"correct single", "i", "i", gordle.FullFeedback{gordle.FeedbackCorrect}, nil}, + {"incorrect place", "ab", "ba", gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace}, nil}, { "some correct some incorrect", "aba", "baa", gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace, gordle.FeedbackCorrect}, + nil, }, { "complex", "testing", "xsesing", @@ -66,13 +68,17 @@ func TestCheckWord(t *testing.T) { gordle.FeedbackCorrect, gordle.FeedbackCorrect, }, + nil, }, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() - got := gordle.CheckWord(test.word, test.input) + got, err := gordle.CheckWord(test.word, test.input) + if !errors.Is(err, test.wantErr) { + t.Errorf("got err %q, want %q", err, test.wantErr) + } if !reflect.DeepEqual(got, test.want) { t.Errorf("got %q, want %q", got, test.want) }