mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-28 05:33:48 -08:00
Add Lua port of 03_Animal
This commit is contained in:
181
03_Animal/lua/Animal.lua
Normal file
181
03_Animal/lua/Animal.lua
Normal file
@@ -0,0 +1,181 @@
|
||||
--
|
||||
-- Animal.lua
|
||||
--
|
||||
|
||||
-- maintain a flat table/list of all the known animals
|
||||
local animals = {
|
||||
"FISH",
|
||||
"BIRD"
|
||||
}
|
||||
|
||||
-- store the questions as a binary tree with each node having a
|
||||
-- "y" or "n" branch
|
||||
-- if the node has a member named "a" it's an answer, with an index
|
||||
-- into the animals list.
|
||||
-- Otherwise, it's a question that leads to more nodes.
|
||||
local questionTree = {
|
||||
q = "DOES IT SWIM",
|
||||
y = { a = 1 },
|
||||
n = { a = 2 }
|
||||
}
|
||||
|
||||
-- print the given prompt string and then wait for input
|
||||
-- loops until a non-empty input is given
|
||||
-- returns the input as an upper-case string
|
||||
function askPrompt(promptString)
|
||||
local answered = false
|
||||
local a
|
||||
while (not answered) do
|
||||
print(promptString)
|
||||
a = io.read()
|
||||
a = string.upper(a)
|
||||
if (string.len(a) > 0) then
|
||||
answered = true
|
||||
end
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
-- print the given prompt string and then wait for the
|
||||
-- user to enter a string beginning with "Y" or "N"
|
||||
function askYesOrNo(promptString)
|
||||
local a
|
||||
while ((a ~= "Y") and (a ~= "N")) do
|
||||
a = askPrompt(promptString)
|
||||
a = a:sub(1,1)
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
-- prints the introductory text from the original BASIC program
|
||||
function printIntro()
|
||||
print(string.format("%32s", " ") .. "ANIMAL")
|
||||
print(string.format("%15s", " ") .. "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
|
||||
print()
|
||||
print()
|
||||
print()
|
||||
print("PLAY 'GUESS THE ANIMAL'")
|
||||
print("THINK OF AN ANIMAL AND THE COMPUTER WILL TRY TO GUESS IT.")
|
||||
print()
|
||||
end
|
||||
|
||||
-- prints the animals known in the source list
|
||||
function listKnownAnimals()
|
||||
print()
|
||||
print("ANIMALS I ALREADY KNOW ARE:")
|
||||
|
||||
local x
|
||||
local item
|
||||
for x = 1,#animals do
|
||||
-- use string.format to space each animal in a 12-character-wide "cell"
|
||||
item = string.format("%-12s", animals[x])
|
||||
|
||||
-- io.write() works like print(), but doesn't automatically add a carriage return/newline
|
||||
io.write(item)
|
||||
|
||||
-- every fifth item, start a new line
|
||||
if ((x % 5) == 0) then
|
||||
io.write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
print()
|
||||
print()
|
||||
end
|
||||
|
||||
-- Prompts the user for info about the animal they were thinking of, then
|
||||
-- uses that to add a new branch to the tree
|
||||
-- curNode: the node in the tree where the computer made a wrong guess
|
||||
-- branch: the answer the user gave to curNode's question
|
||||
function addAnimalToTree(curNode, branch)
|
||||
local newAnimal
|
||||
local curResponse = curNode[branch]
|
||||
local guessedIndex = curResponse.a
|
||||
local guessedAnimal = animals[guessedIndex]
|
||||
local newQuestion, newAnswer, newIndex
|
||||
local newNode
|
||||
|
||||
newAnimal = askPrompt("THE ANIMAL YOU WERE THINKING OF WAS A ?")
|
||||
newQuestion = askPrompt("PLEASE TYPE IN A QUESTION THAT WOULD DISTINGUISH A "..
|
||||
tostring(newAnimal).." FROM A "..tostring(guessedAnimal))
|
||||
newAnswer = askYesOrNo("FOR A "..tostring(newAnimal).." THE ANSWER WOULD BE?")
|
||||
|
||||
-- add the new animal to the master list at the end, and
|
||||
-- save off its index in the list
|
||||
table.insert(animals, newAnimal)
|
||||
newIndex = #animals
|
||||
|
||||
-- create a new node for the question we just learned
|
||||
newNode = {}
|
||||
newNode.q = newQuestion
|
||||
if (newAnswer == "Y") then
|
||||
newNode.y = { a = newIndex }
|
||||
newNode.n = { a = guessedIndex }
|
||||
else
|
||||
newNode.y = { a = guessedIndex }
|
||||
newNode.n = { a = newIndex }
|
||||
end
|
||||
|
||||
-- replace the previous answer with our new node
|
||||
curNode[branch] = newNode
|
||||
end
|
||||
|
||||
-- Starts at the root of the question tree and asks questions about
|
||||
-- the user's animal until the computer hits an "a" answer node and tries
|
||||
-- to make a guess
|
||||
function askAboutAnimal()
|
||||
local curNode = questionTree
|
||||
local finished = false
|
||||
local response, responseIndex
|
||||
local nextNode, animalName
|
||||
while (not finished) do
|
||||
response = askYesOrNo(curNode.q .. "?")
|
||||
|
||||
-- convert the response "Y" or "N" to the lowercase "y" or "n" that we use to name our branches
|
||||
branch = string.lower(response)
|
||||
nextNode = curNode[branch]
|
||||
|
||||
-- is the next node an answer node, or another question?
|
||||
if (nextNode.a ~= nil) then
|
||||
-- it's an answer, so make a guess
|
||||
animalName = animals[nextNode.a]
|
||||
response = askYesOrNo("IS IT A "..tostring(animalName).."?")
|
||||
if (response == "Y") then
|
||||
-- we got the correct answer, so prompt for a new animal
|
||||
print()
|
||||
print("WHY NOT TRY ANOTHER ANIMAL?")
|
||||
else
|
||||
-- incorrect answer, so add a new entry at this point in the tree
|
||||
addAnimalToTree(curNode, branch)
|
||||
end
|
||||
|
||||
-- whether we were right or wrong, we're finished with this round
|
||||
finished = true
|
||||
else
|
||||
-- it's another question, so advance down the tree
|
||||
curNode = nextNode
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- MAIN CONTROL SECTION
|
||||
|
||||
printIntro()
|
||||
|
||||
-- loop forever until the player requests an exit by entering a blank line
|
||||
local exitRequested = false
|
||||
local answer
|
||||
|
||||
while (not exitRequested) do
|
||||
print("ARE YOU THINKING OF AN ANIMAL?")
|
||||
answer = io.read()
|
||||
answer = string.upper(answer)
|
||||
|
||||
if (string.len(answer) == 0) then
|
||||
exitRequested = true
|
||||
elseif (answer:sub(1,4) == "LIST") then
|
||||
listKnownAnimals()
|
||||
elseif (answer:sub(1,1) == "Y") then
|
||||
askAboutAnimal()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user