commit ed31a4bc69f4445f78d49fdc27dc2b2155f950f1
parent 6e6be1afe5775e90656161d597e232cd973ebf56
Author: Agastya Chandrakant <me@hanabi.in>
Date: Fri, 18 Feb 2022 01:10:47 +0530
Refactor more code; also, reject repeated guesses.
Diffstat:
M | src/main.go | | | 47 | ++++------------------------------------------- |
D | src/utils/fns.go | | | 142 | ------------------------------------------------------------------------------- |
A | src/utils/gameplay-fns.go | | | 195 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 199 insertions(+), 185 deletions(-)
diff --git a/src/main.go b/src/main.go
@@ -1,50 +1,11 @@
package main
import (
- "fmt"
-
- "git.hanabi.in/dev/wordle-cli/src/algos"
- "git.hanabi.in/dev/wordle-cli/src/utils"
-)
-
-const (
- chances = 6
- word_size = 5
+ gameplay "git.hanabi.in/dev/wordle-cli/src/utils"
)
func main() {
- answer := utils.SelectAnswer()
- guesses := startGuessing(answer)
- fmt.Printf("Answer was: %s.\n", answer)
- utils.PrintShare(guesses)
-}
-
-func startGuessing(answer string) []string {
-
- var alphabet = utils.InitAlphabetTable()
- var anslookup = algos.GenAnsLookup(answer)
- var colouredChoices = []string{}
- fmt.Printf("Guess a %d-letter word. You have %d tries.\n", word_size, chances)
-
- for cur_chance := 1; cur_chance <= chances; {
- utils.GuessPrompt(cur_chance)
- guess, err := utils.GetValidGuess(word_size)
- if err != nil {
- fmt.Printf("%v", err)
- } else {
- cur_chance++
- if guess != answer {
- colour_string := algos.GetColours(answer, guess, anslookup, alphabet)
- colouredChoices = append(colouredChoices, colour_string)
- utils.PrintColouredGuess(colour_string, guess)
- } else if guess == answer {
- colour_string := "GGGGG" // If the answer was correct, GetColours is not called, hence hard-coding.
- colouredChoices = append(colouredChoices, colour_string)
- fmt.Println("Correct guess!")
- break
- }
- }
- utils.PrintColouredAlpha(alphabet)
- }
- return colouredChoices
+ answer := gameplay.SelectAnswer()
+ guesses := gameplay.StartGuessing(answer)
+ gameplay.GracefullyFinishGame(answer, guesses)
}
diff --git a/src/utils/fns.go b/src/utils/fns.go
@@ -1,142 +0,0 @@
-package utils
-
-import (
- "fmt"
- "math/rand"
- "strings"
-
- "git.hanabi.in/dev/wordle-cli/src/algos"
- "git.hanabi.in/dev/wordle-cli/src/colours"
- "git.hanabi.in/dev/wordle-cli/src/data"
-)
-
-// From a pre-defined sorted list of words, pick a random word which is the answer.
-func SelectAnswer() string {
- words := []string{}
- for _, elem := range data.Words {
- words = append(words, elem)
- }
- algos.Shuffle(words)
- index := rand.Intn(len(words))
- return words[index]
-}
-
-// Create a lookup table for alphabet, initialise them to grey colour.
-func InitAlphabetTable() algos.Lookup {
- var alphabet_table = make(algos.Lookup, 0)
- letters := "abcdefghijklmnopqrstuvwxyz"
- for _, elem := range letters {
- letter_char := string(elem)
- alphabet_table[letter_char] = colours.Code_grey
- }
- return alphabet_table
-}
-
-// Check if the word is of the size of answer. Returns true if size mismatch.
-func IsWrongGuessSize(guess string, word_size int) bool {
- return len(guess) != word_size
-}
-
-// Get user input for the guess, and process it (lower case)
-func FetchGuess() string {
- var guess string
- fmt.Scanf("%s", &guess)
- guess = strings.ToLower(guess)
- return guess
-}
-
-// Check if guessed word is not in the list of possible words. Returns true if not found.
-func IsNotValidWord(guess string) bool {
- idx := algos.BinarySearch(data.Words, guess)
- return idx == -1
-}
-
-// returns either a valid guess, XOR an error.
-func GetValidGuess(word_size int) (string, error) {
- guess := FetchGuess()
- if IsWrongGuessSize(guess, word_size) {
- error_msg := fmt.Errorf("Word should be of length %d.\n", word_size)
- return guess, error_msg
- }
- if IsNotValidWord(guess) {
- error_msg := fmt.Errorf("Not a valid word.\n")
- return guess, error_msg
- }
- return guess, nil
-}
-
-// Print the guess prompt.
-func GuessPrompt(chance int) {
- msg := colours.Bold(fmt.Sprintf("Guess #%d?: ", chance))
- fmt.Print(msg)
-}
-
-// Look at colour_string (Y,G,R) and print the characters of word in colour.
-func PrintColouredGuess(colour_string, word string) {
- for idx, word_elem := range word {
- col_str_char := string(colour_string[idx])
- word_char := string(word_elem)
- if col_str_char == "R" {
- fmt.Print(colours.Red(word_char))
- } else if col_str_char == "Y" {
- fmt.Print(colours.Yellow(word_char))
- } else if col_str_char == "G" {
- fmt.Print(colours.Green(word_char))
- }
- }
- fmt.Println()
-}
-
-// Print coloured alphabet for aiding which words to guess.
-func PrintColouredAlpha(alphabet algos.Lookup) {
- kbd_rows := []string{"qwertyuiop", "asdfghjkl", "zxcvbnm"} // keyboard layout printing.
- for _, kbd_row := range kbd_rows {
- for _, kbd_key := range kbd_row {
- kbd_key_char := string(kbd_key)
- char_col_code := alphabet[kbd_key_char]
- if char_col_code == colours.Code_grey {
- fmt.Print(colours.Grey(kbd_key_char))
- } else if char_col_code == colours.Code_red {
- fmt.Print(colours.Red(kbd_key_char))
- } else if char_col_code == colours.Code_yellow {
- fmt.Print(colours.Yellow(kbd_key_char))
- } else if char_col_code == colours.Code_green {
- fmt.Print(colours.Green(kbd_key_char))
- }
- fmt.Print(" ")
- }
- fmt.Println()
- }
- fmt.Println()
-}
-
-// Print share emoji.
-func PrintShare(guesses []string) {
- if shouldPrintShareEmojis() {
- fmt.Println()
- for _, row := range guesses {
- for _, elem_byte := range row {
- elem := string(elem_byte)
- if elem == "R" {
- fmt.Print("🌑")
- } else if elem == "Y" {
- fmt.Print("🌕")
- } else if elem == "G" {
- fmt.Print("✅")
- }
- }
- fmt.Println()
- }
- }
-}
-
-// Prompt if the share emojies be printed.
-func shouldPrintShareEmojis() bool {
- var ans string
- fmt.Print(colours.Bold("Share your results?[yN]: "))
- fmt.Scanf("%s", &ans)
- if ans == "Y" || ans == "y" {
- return true
- }
- return false
-}
diff --git a/src/utils/gameplay-fns.go b/src/utils/gameplay-fns.go
@@ -0,0 +1,195 @@
+package gameplay
+
+import (
+ "fmt"
+ "math/rand"
+ "strings"
+
+ "git.hanabi.in/dev/wordle-cli/src/algos"
+ "git.hanabi.in/dev/wordle-cli/src/colours"
+ "git.hanabi.in/dev/wordle-cli/src/data"
+)
+
+const (
+ chances = 6
+ word_size = 5
+)
+
+// From a pre-defined sorted list of words, pick a random word which is the answer.
+func SelectAnswer() string {
+ words := []string{}
+ for _, elem := range data.Words {
+ words = append(words, elem)
+ }
+ algos.Shuffle(words)
+ index := rand.Intn(len(words))
+ return words[index]
+}
+
+// Create a lookup table for alphabet, initialise them to grey colour.
+func initAlphabetTable() algos.Lookup {
+ var alphabet_table = make(algos.Lookup, 0)
+ letters := "abcdefghijklmnopqrstuvwxyz"
+ for _, elem := range letters {
+ letter_char := string(elem)
+ alphabet_table[letter_char] = colours.Code_grey
+ }
+ return alphabet_table
+}
+
+// Check if the word is of the size of answer. Returns true if size mismatch.
+func isWrongGuessSize(guess string) bool {
+ return len(guess) != word_size
+}
+
+// Get user input for the guess, and process it (lower case)
+func fetchGuess() string {
+ var guess string
+ fmt.Scanf("%s", &guess)
+ guess = strings.ToLower(guess)
+ return guess
+}
+
+// Check if guessed word is not in the list of possible words. Returns true if not found.
+func isNotValidWord(guess string) bool {
+ idx := algos.BinarySearch(data.Words, guess)
+ return idx == -1
+}
+
+// returns either a valid guess, XOR an error.
+func getValidGuess(prev_guesses []string) (string, error) {
+ guess := fetchGuess()
+ var error_msg error = nil
+ if isWrongGuessSize(guess) {
+ error_msg = fmt.Errorf("Word should be of length %d.\n", word_size)
+ } else if isNotValidWord(guess) {
+ error_msg = fmt.Errorf("Not a valid word.\n")
+ } else if isOldGuess(guess, prev_guesses) {
+ error_msg = fmt.Errorf("You already guessed this word.\n")
+ }
+ return guess, error_msg
+}
+
+// Check if the current guess was already guessed or not.
+func isOldGuess(guess string, prev_guesses []string) bool {
+ for _, elem := range prev_guesses {
+ if elem == guess {
+ return true
+ }
+ }
+ return false
+}
+
+// Print the guess prompt.
+func guessPrompt(chance int) {
+ msg := colours.Bold(fmt.Sprintf("Guess #%d?: ", chance))
+ fmt.Print(msg)
+}
+
+// Look at colour_string (Y,G,R) and print the characters of word in colour.
+func printColouredGuess(colour_string, word string) {
+ for idx, word_elem := range word {
+ col_str_char := string(colour_string[idx])
+ word_char := string(word_elem)
+ if col_str_char == "R" {
+ fmt.Print(colours.Red(word_char))
+ } else if col_str_char == "Y" {
+ fmt.Print(colours.Yellow(word_char))
+ } else if col_str_char == "G" {
+ fmt.Print(colours.Green(word_char))
+ }
+ }
+ fmt.Println()
+}
+
+// Print coloured alphabet for aiding which words to guess.
+func printColouredAlpha(alphabet algos.Lookup) {
+ kbd_rows := []string{"qwertyuiop", "asdfghjkl", "zxcvbnm"} // keyboard layout printing.
+ for _, kbd_row := range kbd_rows {
+ for _, kbd_key := range kbd_row {
+ kbd_key_char := string(kbd_key)
+ char_col_code := alphabet[kbd_key_char]
+ if char_col_code == colours.Code_grey {
+ fmt.Print(colours.Grey(kbd_key_char))
+ } else if char_col_code == colours.Code_red {
+ fmt.Print(colours.Red(kbd_key_char))
+ } else if char_col_code == colours.Code_yellow {
+ fmt.Print(colours.Yellow(kbd_key_char))
+ } else if char_col_code == colours.Code_green {
+ fmt.Print(colours.Green(kbd_key_char))
+ }
+ fmt.Print(" ")
+ }
+ fmt.Println()
+ }
+ fmt.Println()
+}
+
+// Print share emoji.
+func printShare(guesses []string) {
+ if shouldPrintShareEmojis() {
+ fmt.Println()
+ for _, row := range guesses {
+ for _, elem_byte := range row {
+ elem := string(elem_byte)
+ if elem == "R" {
+ fmt.Print("🌑")
+ } else if elem == "Y" {
+ fmt.Print("🌕")
+ } else if elem == "G" {
+ fmt.Print("✅")
+ }
+ }
+ fmt.Println()
+ }
+ }
+}
+
+// Prompt if the share emojies be printed.
+func shouldPrintShareEmojis() bool {
+ var ans string
+ fmt.Print(colours.Bold("Share your results?[yN]: "))
+ fmt.Scanf("%s", &ans)
+ if ans == "Y" || ans == "y" {
+ return true
+ }
+ return false
+}
+
+func StartGuessing(answer string) []string {
+
+ var alphabet = initAlphabetTable()
+ var anslookup = algos.GenAnsLookup(answer)
+ var prev_guesses = []string{}
+ var colouredChoices = []string{}
+ fmt.Printf("Guess a %d-letter word. You have %d tries.\n", word_size, chances)
+
+ for cur_chance := 1; cur_chance <= chances; {
+ guessPrompt(cur_chance)
+ guess, err := getValidGuess(prev_guesses)
+ if err != nil {
+ fmt.Printf("%v", err)
+ } else {
+ cur_chance++
+ prev_guesses = append(prev_guesses, guess)
+ if guess != answer {
+ colour_string := algos.GetColours(answer, guess, anslookup, alphabet)
+ colouredChoices = append(colouredChoices, colour_string)
+ printColouredGuess(colour_string, guess)
+ } else if guess == answer {
+ colour_string := "GGGGG" // If the answer was correct, GetColours is not called, hence hard-coding.
+ colouredChoices = append(colouredChoices, colour_string)
+ fmt.Println("Correct guess!")
+ break
+ }
+ }
+ printColouredAlpha(alphabet)
+ }
+ return colouredChoices
+}
+
+// Handle end of the game once correct answer is reached, or when all chances are over.
+func GracefullyFinishGame(answer string, guesses []string) {
+ fmt.Printf("Answer was: %s.\n", answer)
+ printShare(guesses)
+}