From 096bc29a29f8eb7f7a90571603d2d0ed4b6c1453 Mon Sep 17 00:00:00 2001 From: Troy Campbell Date: Thu, 13 Oct 2022 09:10:25 +1000 Subject: [PATCH] Added go for Animal --- 00_Alternate_Languages/03_Animal/go/main.go | 159 ++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 00_Alternate_Languages/03_Animal/go/main.go diff --git a/00_Alternate_Languages/03_Animal/go/main.go b/00_Alternate_Languages/03_Animal/go/main.go new file mode 100644 index 00000000..2eb0904e --- /dev/null +++ b/00_Alternate_Languages/03_Animal/go/main.go @@ -0,0 +1,159 @@ +package main + +import ( + "bufio" + "fmt" + "log" + "os" + "strings" +) + +type node struct { + text string + yesNode *node + noNode *node +} + +func newNode(text string, yes_node, no_node *node) *node { + n := node{text: text} + if yes_node != nil { + n.yesNode = yes_node + } + if no_node != nil { + n.noNode = no_node + } + return &n +} + +func (n *node) update(newQuestion, newAnswer, newAnimal string) { + oldAnimal := n.text + + n.text = newQuestion + + if newAnswer == "y" { + n.yesNode = newNode(newAnimal, nil, nil) + n.noNode = newNode(oldAnimal, nil, nil) + } else { + n.yesNode = newNode(oldAnimal, nil, nil) + n.noNode = newNode(newAnimal, nil, nil) + } +} + +func (n *node) isLeaf() bool { + return (n.yesNode == nil) && (n.noNode == nil) +} + +func listKnownAnimals(root *node) { + if root == nil { + return + } + + if root.isLeaf() { + fmt.Printf("%s ", root.text) + return + } + + if root.yesNode != nil { + listKnownAnimals(root.yesNode) + } + + if root.noNode != nil { + listKnownAnimals(root.noNode) + } +} + +func parseInput(message string, checkList bool, rootNode *node) string { + scanner := bufio.NewScanner(os.Stdin) + token := "" + + for { + fmt.Println(message) + scanner.Scan() + inp := strings.ToLower(scanner.Text()) + + if checkList && inp == "list" { + fmt.Println("Animals I already know are:") + listKnownAnimals(rootNode) + fmt.Println() + } + + if len(inp) > 0 { + token = inp + } else { + token = "" + } + + if token == "y" || token == "n" { + break + } + } + return token +} + +func avoidVoidInput(message string) string { + scanner := bufio.NewScanner(os.Stdin) + answer := "" + for { + fmt.Println(message) + scanner.Scan() + answer = scanner.Text() + + if answer != "" { + break + } + } + return answer +} + +func printIntro() { + fmt.Println(" Animal") + fmt.Println(" Creative Computing Morristown, New Jersey") + fmt.Println("\nPlay 'Guess the Animal'") + fmt.Println("Think of an animal and the computer will try to guess it") +} + +func main() { + yesChild := newNode("Fish", nil, nil) + noChild := newNode("Bird", nil, nil) + rootNode := newNode("Does it swim?", yesChild, noChild) + + printIntro() + + keepPlaying := (parseInput("Are you thinking of an animal?", true, rootNode) == "y") + + for keepPlaying { + keepAsking := true + + actualNode := rootNode + + for keepAsking { + if !actualNode.isLeaf() { + answer := parseInput(actualNode.text, false, nil) + + if answer == "y" { + if actualNode.yesNode == nil { + log.Fatal("invalid node") + } + actualNode = actualNode.yesNode + } else { + if actualNode.noNode == nil { + log.Fatal("invalid node") + } + actualNode = actualNode.noNode + } + } else { + answer := parseInput(fmt.Sprintf("Is it a %s?", actualNode.text), false, nil) + if answer == "n" { + newAnimal := avoidVoidInput("The animal you were thinking of was a ?") + newQuestion := avoidVoidInput(fmt.Sprintf("Please type in a question that would distinguish a '%s' from a '%s':", newAnimal, actualNode.text)) + newAnswer := parseInput(fmt.Sprintf("For a '%s' the answer would be", newAnimal), false, nil) + actualNode.update(newQuestion+"?", newAnswer, newAnimal) + } else { + fmt.Println("Why not try another animal?") + } + keepAsking = false + } + } + keepPlaying = (parseInput("Are you thinking of an animal?", true, rootNode) == "y") + } +}