Files
basic-computer-games/25_Chief/lua/chief.lua
2022-10-18 12:12:44 +02:00

122 lines
4.0 KiB
Lua

--[[
Chief
From: BASIC Computer Games (1978)
Edited by David H. Ahl
In the words of the program author, John Graham, “CHIEF is designed to
give people (mostly kids) practice in the four operations (addition,
multiplication, subtraction, and division).
It does this while giving people some fun. And then, if the people are
wrong, it shows them how they should have done it.
CHIEF was written by John Graham of Upper Brookville, New York.
Lua port by Alex Conconi, 2022.
]]--
--- Helper function for tabulating messages.
local function space(n) return string.rep(" ", n) end
--- Generates a multi-line string representing a lightning bolt
local function bolt()
local bolt_lines = {}
for n = 29, 21, -1 do
table.insert(bolt_lines, space(n) .. "x x")
end
table.insert(bolt_lines, space(20) .. "x xxx")
table.insert(bolt_lines, space(19) .. "x x")
table.insert(bolt_lines, space(18) .. "xx x")
for n = 19, 12, -1 do
table.insert(bolt_lines, space(n) .. "x x")
end
table.insert(bolt_lines, space(11) .. "xx")
table.insert(bolt_lines, space(10) .. "x")
table.insert(bolt_lines, space(9) .. "*\n")
table.insert(bolt_lines, string.rep("#", 25) .. "\n")
return table.concat(bolt_lines, "\n")
end
--- Print the prompt and read a yes/no answer from stdin.
local function ask_yes_or_no(prompt)
io.stdout:write(prompt .. " ")
local answer = string.lower(io.stdin:read("*l"))
-- any line starting with a 'y' or 'Y' is considered a 'yes'
return answer:sub(1, 1) == "y"
end
--- Print the prompt and read a valid number from stdin.
local function ask_number(prompt)
io.stdout:write(prompt .. " ")
while true do
local n = tonumber(io.stdin:read("*l"))
if n then
return n
else
print("Enter a valid number.")
end
end
end
--- Explain the solution to persuade the player.
local function explain_solution()
local k = ask_number("What was your original number?")
-- For clarity we kept the same variable names of the original BASIC version
local f = k + 3
local g = f / 5
local h = g * 8
local i = h / 5 + 5
local j = i - 1
print("So you think you're so smart, eh?")
print("Now watch.")
print(k .. " plus 3 equals " .. f .. ". This divided by 5 equals " .. g .. ";")
print("this times 8 equals " .. h .. ". If we divide by 5 and add 5,")
print("we get " .. i .. ", which, minus 1, equals " .. j .. ".")
end
--- Main game function.
local function chief_game()
--- Print game introduction and challenge
print(space(29) .. "Chief")
print(space(14) .. "Creative Computing Morristown, New Jersey\n\n")
print("I am Chief Numbers Freek, the great math god.")
if not ask_yes_or_no("Are you ready to take the test you called me out for?") then
print("Shut up, wise tongue.")
end
-- Print how to obtain the end result.
print(" Take a number and add 3. Divide this number by 5 and")
print("multiply by 8. Divide by 5 and add the same. Subtract 1.")
-- Ask the result end and reverse calculate the original number.
local end_result = ask_number(" What do you have?")
local original_number = (end_result + 1 - 5) * 5 / 8 * 5 - 3
-- If it is an integer we do not want to print any zero decimals.
local int_part, dec_part = math.modf(original_number)
if dec_part == 0 then original_number = int_part end
-- If the player challenges the answer, print the explanation.
if not ask_yes_or_no("I bet your number was " .. original_number .. ". Am I right?") then
explain_solution()
-- If the player does not accept the explanation, zap them.
if not ask_yes_or_no("Now do you believe me?") then
print("YOU HAVE MADE ME MAD!!!")
print("THERE MUST BE A GREAT LIGHTNING BOLT!\n\n")
print(bolt())
print("I hope you believe me now, for your sake!!")
end
end
end
--- Run the game.
chief_game()