From 8c465586316f222fc2241572cdf0b62c6490ab21 Mon Sep 17 00:00:00 2001 From: aconconi Date: Fri, 14 Oct 2022 20:33:51 +0200 Subject: [PATCH 1/4] 25_Chief port to Lua and updated readme --- 25_Chief/lua/README.md | 23 +++++++++- 25_Chief/lua/chief.lua | 101 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 25_Chief/lua/chief.lua diff --git a/25_Chief/lua/README.md b/25_Chief/lua/README.md index c063f42f..4c84051b 100644 --- a/25_Chief/lua/README.md +++ b/25_Chief/lua/README.md @@ -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. diff --git a/25_Chief/lua/chief.lua b/25_Chief/lua/chief.lua new file mode 100644 index 00000000..281ba645 --- /dev/null +++ b/25_Chief/lua/chief.lua @@ -0,0 +1,101 @@ +--- Helper function for tabulating messages. +local function tab(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, tab(n) .. "x x") + end + table.insert(bolt_lines, tab(20) .. "x xxx") + table.insert(bolt_lines, tab(19) .. "x x") + table.insert(bolt_lines, tab(18) .. "xx x") + for n = 19, 12, -1 do + table.insert(bolt_lines, tab(n) .. "x x") + end + table.insert(bolt_lines, tab(11) .. "xx") + table.insert(bolt_lines, tab(10) .. "x") + table.insert(bolt_lines, tab(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(tab(29) .. "Chief") + print(tab(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() From 6676cd90abf23692412ef5668a9c673dea4ade68 Mon Sep 17 00:00:00 2001 From: aconconi Date: Fri, 14 Oct 2022 20:42:02 +0200 Subject: [PATCH 2/4] Added credits header to source code. --- 25_Chief/lua/chief.lua | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/25_Chief/lua/chief.lua b/25_Chief/lua/chief.lua index 281ba645..39a2e4e2 100644 --- a/25_Chief/lua/chief.lua +++ b/25_Chief/lua/chief.lua @@ -1,3 +1,23 @@ +--[[ +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 tab(n) return string.rep(" ", n) end From 15d0301cd53ee5139164acdda4b5cf6c42791716 Mon Sep 17 00:00:00 2001 From: Alex Conconi <4670015+aconconi@users.noreply.github.com> Date: Fri, 14 Oct 2022 20:43:50 +0200 Subject: [PATCH 3/4] Update README.md punctuation --- 25_Chief/lua/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/25_Chief/lua/README.md b/25_Chief/lua/README.md index 4c84051b..937d758c 100644 --- a/25_Chief/lua/README.md +++ b/25_Chief/lua/README.md @@ -7,7 +7,7 @@ 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 +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 From 98238c5e0851f34ca7dfce6f05e4bb5554dbd06b Mon Sep 17 00:00:00 2001 From: aconconi Date: Tue, 18 Oct 2022 12:12:44 +0200 Subject: [PATCH 4/4] renamed function tab to space --- 25_Chief/lua/chief.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/25_Chief/lua/chief.lua b/25_Chief/lua/chief.lua index 39a2e4e2..6ac885b2 100644 --- a/25_Chief/lua/chief.lua +++ b/25_Chief/lua/chief.lua @@ -19,24 +19,24 @@ Lua port by Alex Conconi, 2022. --- Helper function for tabulating messages. -local function tab(n) return string.rep(" ", n) end +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, tab(n) .. "x x") + table.insert(bolt_lines, space(n) .. "x x") end - table.insert(bolt_lines, tab(20) .. "x xxx") - table.insert(bolt_lines, tab(19) .. "x x") - table.insert(bolt_lines, tab(18) .. "xx x") + 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, tab(n) .. "x x") + table.insert(bolt_lines, space(n) .. "x x") end - table.insert(bolt_lines, tab(11) .. "xx") - table.insert(bolt_lines, tab(10) .. "x") - table.insert(bolt_lines, tab(9) .. "*\n") + 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 @@ -85,8 +85,8 @@ end --- Main game function. local function chief_game() --- Print game introduction and challenge - print(tab(29) .. "Chief") - print(tab(14) .. "Creative Computing Morristown, New Jersey\n\n") + 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.")