Last active
February 11, 2022 22:27
-
-
Save trafficone/c76c1e63900b64dc7e30d3c8cfa46ebc to your computer and use it in GitHub Desktop.
Word Guessing Game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"errors" | |
"fmt" | |
"io/ioutil" | |
"math" | |
"math/rand" | |
"os" | |
"strings" | |
"time" | |
) | |
// grep '^\w\{5\}$' /usr/share/dict/words | tr '[:upper:]' '[:lower:]' | sort -u > five_letter_words | |
const WORDLEN = 5 | |
const WORDFILE = "five_letter_words" | |
func load_words(wordfile string) (*[]string, error) { | |
file, err := ioutil.ReadFile(wordfile) | |
if err != nil { | |
return nil, fmt.Errorf("Could not read from file %s: error: %s", wordfile, err) | |
} | |
words := strings.Split(string(file[:]), "\n") | |
return &words, nil | |
} | |
func evaluate_guess(guess_str, actual_str string, words *[]string) (string, error) { | |
// First see if guess is in words, invalid guesses are rejected | |
// Since words is sorted, we binary search | |
i := 0 | |
v := 0 | |
found := false | |
guess := []rune(guess_str) | |
actual := []rune(actual_str) | |
words_length := len(*words) | |
running := true | |
for j := words_length - 2; running; j = int(math.Round(float64(j) / 2.0)) { | |
if j == 1 { | |
running = false | |
} | |
check_index := i + j | |
if check_index > words_length { | |
break | |
} | |
check := (*words)[check_index] | |
v = strings.Compare(guess_str, check) | |
if v == 0 { | |
found = true | |
break | |
} else if v > 0 { | |
i += j | |
} | |
} | |
if !found { | |
return "", errors.New("Guess not valid") | |
} | |
output := make([]rune, WORDLEN) | |
for i := 0; i < WORDLEN; i++ { | |
output[i] = rune('✖') | |
} | |
for i := 0; i < WORDLEN; i++ { | |
if guess[i] == actual[i] { | |
output[i] = rune('◎') | |
actual[i] = rune(' ') | |
} | |
} | |
for i := 0; i < WORDLEN; i++ { | |
for j := 0; j < WORDLEN; j++ { | |
if i != j && output[i] != rune('◎') && guess[i] == actual[j] { | |
output[i] = rune('〇') | |
actual[j] = rune(' ') | |
} | |
} | |
} | |
return string(output), nil | |
} | |
func main() { | |
fmt.Println("Welcome to WeirdIe") | |
fmt.Printf("Guess the %d letter word I'm thinking of\n", WORDLEN) | |
fmt.Println("In 6 guesses or fewer!") | |
rand.Seed(time.Now().UnixNano()) | |
words, _ := load_words(WORDFILE) | |
actual := (*words)[rand.Intn(len(*words))] | |
reader := bufio.NewReader(os.Stdin) | |
for i := 1; i <= 6; i++ { | |
guess := "" | |
for { | |
fmt.Printf("%d > ", i) | |
guess, _ = reader.ReadString('\n') | |
guess = strings.Replace(guess, "\n", "", -1) | |
guess = strings.Replace(guess, "\r", "", -1) | |
if len(guess) != WORDLEN { | |
fmt.Printf("Guess must be %d letters, try again\n", WORDLEN) | |
continue | |
} | |
result, err := evaluate_guess(guess, actual, words) | |
if err != nil { | |
fmt.Println(err) | |
} else { | |
fmt.Printf(" %s\n", result) | |
break | |
} | |
} | |
if guess == actual { | |
fmt.Printf("You won in %d turns!\n", i) | |
return | |
} | |
} | |
fmt.Printf("Sorry, the word was \"%s\"\n", actual) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment