don't count attempts with incorrect letters count + cheat mode

This commit is contained in:
Gabriel Augendre 2023-08-16 20:42:09 +02:00
parent 198d5e85ec
commit 928cfc0056
3 changed files with 44 additions and 15 deletions

View file

@ -21,6 +21,7 @@ func main() {
wordLength := flag.Int("l", defaultWordLength, "word length") wordLength := flag.Int("l", defaultWordLength, "word length")
dictionary := flag.String("f", "", "dictionary file") dictionary := flag.String("f", "", "dictionary file")
maxAttempts := flag.Int("m", defaultMaxAttempts, "maximum number of attempts") maxAttempts := flag.Int("m", defaultMaxAttempts, "maximum number of attempts")
cheat := flag.Bool("c", false, "cheat mode (prints word at the beginning)")
flag.Parse() flag.Parse()
@ -42,22 +43,34 @@ func main() {
fmt.Printf("length %d ; you have %d attempts\n", *wordLength, *maxAttempts) fmt.Printf("length %d ; you have %d attempts\n", *wordLength, *maxAttempts)
if *cheat {
fmt.Printf("word: %s\n", word)
}
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
game := gordle.New(*maxAttempts, word) 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() { for !game.Over() && scanner.Scan() {
var feedback gordle.FullFeedback var feedback gordle.FullFeedback
text := strings.ToUpper(scanner.Text()) text := strings.ToUpper(scanner.Text())
feedback, err = game.TryWord(text) feedback, err := game.TryWord(text)
fmt.Println(feedback)
switch { switch {
case errors.Is(err, gordle.ErrGameWon): case errors.Is(err, gordle.ErrGameWon):
fmt.Println(feedback)
fmt.Println("🎉 you won") fmt.Println("🎉 you won")
case errors.Is(err, gordle.ErrGameLost): case errors.Is(err, gordle.ErrGameLost):
fmt.Println(feedback)
fmt.Printf("😔 you lost, the correct word was %s\n", word) 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)
} }
} }
} }

View file

@ -13,6 +13,7 @@ var (
ErrWordNotFound = errors.New("word not found with requested length") ErrWordNotFound = errors.New("word not found with requested length")
ErrGameWon = errors.New("won game") ErrGameWon = errors.New("won game")
ErrGameLost = errors.New("game over") ErrGameLost = errors.New("game over")
ErrRunesCount = errors.New("incorrect number of letters")
) )
type ( type (
@ -62,7 +63,11 @@ func New(maxAttempts int, pickedWord string) *Game {
} }
func (g *Game) TryWord(word string) (FullFeedback, error) { 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() { if feedback.Wins() {
g.over = true g.over = true
return feedback, ErrGameWon return feedback, ErrGameWon
@ -106,9 +111,14 @@ func PickWord(reader io.Reader, wordLength int) (string, error) {
return candidates[rnd], nil return candidates[rnd], nil
} }
func CheckWord(word, input string) FullFeedback { func CheckWord(word, input string) (FullFeedback, error) {
wordRunes := []rune(word) wordRunes := []rune(word)
inputRunes := []rune(input) inputRunes := []rune(input)
if len(wordRunes) != len(inputRunes) {
return nil, ErrRunesCount
}
res := []Feedback{} res := []Feedback{}
counter := map[rune]int{} counter := map[rune]int{}
@ -137,5 +147,5 @@ func CheckWord(word, input string) FullFeedback {
} }
} }
return res return res, nil
} }

View file

@ -42,18 +42,20 @@ func TestCheckWord(t *testing.T) {
t.Parallel() t.Parallel()
tests := []struct { tests := []struct {
name string name string
word string word string
input string input string
want gordle.FullFeedback want gordle.FullFeedback
wantErr error
}{ }{
{"empty", "", "", gordle.FullFeedback{}}, {"empty", "", "", gordle.FullFeedback{}, nil},
{"missing input", "i", "", gordle.FullFeedback{gordle.FeedbackNotInWord}}, {"missing input", "i", "", nil, gordle.ErrRunesCount},
{"correct single", "i", "i", gordle.FullFeedback{gordle.FeedbackCorrect}}, {"correct single", "i", "i", gordle.FullFeedback{gordle.FeedbackCorrect}, nil},
{"incorrect place", "ab", "ba", gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace}}, {"incorrect place", "ab", "ba", gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace}, nil},
{ {
"some correct some incorrect", "aba", "baa", "some correct some incorrect", "aba", "baa",
gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace, gordle.FeedbackCorrect}, gordle.FullFeedback{gordle.FeedbackWrongPlace, gordle.FeedbackWrongPlace, gordle.FeedbackCorrect},
nil,
}, },
{ {
"complex", "testing", "xsesing", "complex", "testing", "xsesing",
@ -66,13 +68,17 @@ func TestCheckWord(t *testing.T) {
gordle.FeedbackCorrect, gordle.FeedbackCorrect,
gordle.FeedbackCorrect, gordle.FeedbackCorrect,
}, },
nil,
}, },
} }
for _, test := range tests { for _, test := range tests {
test := test test := test
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
t.Parallel() 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) { if !reflect.DeepEqual(got, test.want) {
t.Errorf("got %q, want %q", got, test.want) t.Errorf("got %q, want %q", got, test.want)
} }