Merge pull request #822 from aconconi/25-chief-lua

25-chief-lua
This commit is contained in:
Jeff Atwood
2022-10-31 15:33:16 -07:00
committed by GitHub
2 changed files with 143 additions and 1 deletions

View File

@@ -1,3 +1,24 @@
Original source downloaded [from Vintage Basic](http://www.vintage-basic.net/games.html)
Conversion to [Lua](https://www.lua.org/)
Conversion to [Lua](https://www.lua.org/) by Alex Conconi
---
### Lua porting notes
- I did not like the old Western movie language style in the game introduction
and decided to tone it down, even if this deviates from the original BASIC
version.
- The `craps_game` function contains the main game logic: it
- prints the game credits and presents the intro question;
- asks for the end result and computes the original numer;
- calls `explain_solution` to print the various steps of the computation;
- presents the outro question and prints a `bolt` if necessary.
- Added basic input validation to accept only valid integers for numeric input.
- Minor formatting edits (lowercase, punctuation).
- Any answer to a "yes or no" question is regarded as "yes" if the input line
starts with 'y' or 'Y', else no.

121
25_Chief/lua/chief.lua Normal file
View File

@@ -0,0 +1,121 @@
--[[
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()