1
0
forked from Mirror/wren

Add an animals guessing game example.

This commit is contained in:
Bob Nystrom
2015-11-29 09:43:47 -08:00
parent c46507d937
commit a38753d1d6
2 changed files with 89 additions and 1 deletions

86
example/animals.wren Normal file
View File

@ -0,0 +1,86 @@
import "io" for Stdin
// Implements the classic "Animals" guessing game. The user thinks of an animal.
// The program asks a series of yes/no questions to try to guess the animal
// they are thinking of. If the program fails, it asks the user for a new
// question and adds the animal to its knowledge base.
//
// Internally, the program's brain is stored as a binary tree. Leaf nodes are
// animals. Internal nodes are yes/no questions that choose which branch to
// explore.
class Node {
// Reads a "yes" or "no" (or something approximating) those and returns true
// if yes was entered.
promptYesNo(prompt) {
while (true) {
var line = promptString(prompt)
if (line.startsWith("y") || line.startsWith("Y")) return true
if (line.startsWith("n") || line.startsWith("N")) return false
// Quit.
if (line.startsWith("q") || line.startsWith("Q")) Fiber.yield()
}
}
// Writes a prompt and reads a string of input.
promptString(prompt) {
System.write("%(prompt) ")
return Stdin.readLine()
}
}
class Animal is Node {
construct new(name) {
_name = name
}
ask() {
// Hit a leaf, so see if we guessed it.
if (promptYesNo("Is it a %(_name)?")) {
System.print("I won! Let's play again!")
return null
}
// Nope, so add a new animal and turn this node into a branch.
var name = promptString("I lost! What was your animal?")
var question = promptString(
"What question would distinguish a %(_name) from a %(name)?")
var isYes = promptYesNo(
"Is the answer to the question 'yes' for a %(name)?")
System.print("I'll remember that. Let's play again!")
var animal = Animal.new(name)
return Question.new(question, isYes ? animal : this, isYes ? this : animal)
}
}
class Question is Node {
construct new(question, ifYes, ifNo) {
_question = question
_ifYes = ifYes
_ifNo = ifNo
}
ask() {
// Recurse into the branches.
if (promptYesNo(_question)) {
var result = _ifYes.ask()
if (result != null) _ifYes = result
} else {
var result = _ifNo.ask()
if (result != null) _ifNo = result
}
return null
}
}
var root = Question.new("Does it live in the water?",
Animal.new("frog"), Animal.new("goat"))
// Play games until the user quits.
Fiber.new {
while (true) root.ask()
}.call()

View File

@ -356,8 +356,10 @@ def run_api_test(path):
def run_example(path):
# The guess number requires user input.
# Don't run examples that require user input.
if "animals" in path: return
if "guess_number" in path: return
run_script(WREN_APP, path, "example")