i'm completely new to Lua and i have got this error multiple times "'end' expected (to close 'while' at line 3) near ''" i have checked to find answers online and no luck so i was hoping someone could help me fix this problem, thanks alot
Here is my code :
print ("Welcome to the maze")
while input ~= "leave" do
print ("What do you want to do first? Leave or inspect?")
input = io.read()
if input == "inspect" then
print (" You venture towards the maze.")
end
if input == "leave" then
print ("You turn around and run.")
end
I've never seen lua, but i think reading the error will be the solution:
'end' expected (to close 'while' at line 3)
So i need to put end to code:
print ("Welcome to the maze")
while input ~= "leave" do
print ("What do you want to do first? Leave or inspect?")
input = io.read()
if input == "inspect" then
print (" You venture towards the maze.")
end
if input == "leave" then
print ("You turn around and run.")
end
end
Related
I am working with Lua 5.1. This is the program I am currently trying to run.
print ("What is your name?")
playerName = io.read()
print ("Are you a boy or a girl?")
playerGender = io.read()
repeat
if playerGender ~= "boy" or "girl" or "male" or "female" then
print ("I'm sorry, that is not a valid answer.")
print ("Are you a boy or a girl?")
playerGender = io.read()
end
until (playerGender == "boy" or "girl" or "male" or "female")
No matter what, whether I enter one of the valid answers or if it's just random gibberish- the program responds with "I'm sorry, that is not a valid answer. Are you a boy or a girl?" Then you are prompted to enter your gender again- but no matter what the answer it just terminates the program- or it carries on to whatever other code there is to run.
Is there anything wrong with my code or logic that would be making the program to behave this way? Should I use something else other than the "repeat - if - then - end - else" block I am currently using? Any help would be appreciated!
Apparently there is a misconception about how comparison and boolean operators work. The following line will always evaluate to true:
playerGender ~= "boy" or "girl" or "male" or "female"
Why is that? To make clearer what happens, let's add some parenthesis to show how the expression is evaluted according to operator precedence:
(playerGender ~= "boy") or ("girl") or ("male") or ("female")
This means, we have four expressions connected with or operators. This means, if any of those sub-expressions is truthy, the whole expression is true. In Lua, all values except for false and nil are truthy. As all three strings "girl", "male" and "female" are truthy, the entire expression is always true.
The following will do what you want:
(playerGender ~= "boy") and (playerGender ~= "girl") and (playerGender ~= "male") and (playerGender ~= "female")
Now you have four expressions connected with and operators, which means, all of the sub-expressions need to be true (i.e. all string comparisons are unequal) for the entire expression to be true.
The until condition has the same problem, i.e. the expression is always truthy because the strings always are truthy. You could simplify the loop as follows:
while playerGender ~= "boy" and playerGender ~= "girl" and playerGender ~= "male" and playerGender ~= "female" do
print ("I'm sorry, that is not a valid answer.")
print ("Are you a boy or a girl?")
playerGender = io.read()
end
Does anyone happen to know why the result of executing the below code prints ace alongside the Boys? Given ace is on a separate line plus it isn't indented same as the 2nd line shouldn't it print a second row instead of continuing?
for i in range(8):
print ("Boy", end=" ")
print ("ace")
print("qwerty")
Result >>>>>
Boy Boy Boy Boy Boy Boy Boy Boy ace
qwerty
Think of the 'end' parameter as the controller for the next 'print' statement.
During the last iteration of the loop, the 'end' parameter sets the control on the same line as 'Boy Boy... Boy'. So, ace is printed after space (" ")
By default, the value of 'end' is '\n', which represents new-line. So the control goes to the next line after printing the 'ace'
In this program: https://repl.it/EvM6, io.read() should cause input to be assigned to a variable, which is then printed to the screen. But, an odd error appears, which reads,
"{"command":"input","data":"foo\n","error":""}".
Why does this error occur? Is there any way to fix it?
The function io.read() was substituted with custom one. The result returned by standard io.read() will be different.
A quick-and-dirty way to fix it:
local io_read_orig = io.read
function io.read()
return (
loadstring(
"return "..io_read_orig():match[[^{"command":".-","data":(".*"),"error":".*"}$]]
)():gsub("\n$","")
)
end
-- By StarBuck
print("Type something, then press enter.")
local input = io.read()
print(input)
this is an engineer at Repl.it. This was a bug in our Lua REPL implementation. It's now fixed. I apologize for the confusion.
function msgcontains(msg, what)
msg = msg:lower()
-- Should be replaced by a more complete parser
if type(what) == "string" and string.find(what, "|", 1, true) ~= nil then
what = what:explode("|")
end
-- Check recursively if what is a table
if type(what) == "table" then
for _, v in ipairs(what) do
if msgcontains(msg, v) then
return true
end
end
return false
end
what = string.gsub(what, "[%%%^%$%(%)%.%[%]%*%+%-%?]", function(s) return "%" .. s end)
return string.match(msg, what) ~= nil
end
This function is used on a RPG server, basically I'm trying to match what the player says
e.g; if msgcontains(msg, "hi") then
msg = the message the player sent
However, it's matching anything like "yesimstupidhi", it really shouldn't match it because "hi" isn't a single word, any ideas what can I do? T_T
Frontiers are good for dealing with boundaries of the pattern (see Lua frontier pattern match (whole word search)) and you won't have to modify the string:
return msg:match('%f[%a]'..what..'%f[%A]') ~= nil
The frontier '%f[%a]' matches only if the previous character was not in '%a' and the next is. The frontier pattern is available since 5.1 and official since 5.2.
You can use a trick mentioned by Egor in his comment, namely: add some non-word characters to the input string, and then enclose the regex with non-letter %A (or non-alphanumeric with %W if you want to disallow digits, too).
So, use
return string.match(' '..msg..' ', '%A'..what..'%A') ~= nil
or
return string.match(' '..msg..' ', '%W'..what..'%W') ~= nil
This code:
--This will print "yes im stupid hi" since "yes" is a whole word
msg = "yes im stupid hi"
if msgcontains(msg, "yes") then
print(msg)
end
--This will not print anything
msg = "yesim stupid hi"
if msgcontains(msg, "yes") then
print(msg)
end
Here is a CodingGround demo
Just think about "what's a word". A word has specific characters in front and behind it, like whitespaces (space, tabulator, newline, carriage return, ...) or punctation (comma, semicolon, dot, line, ...). Furthermore a word can be at the text begin or end.
%s, %p, ^ and $ should interest you.
For more, see here.
I need help turning off this feature if possible from the interactive mode or I'm going to go mad. The REPL insists on an equal sign before every expression if you want the value. I find this very irritating and unintuitive. To make matters worse, if you mistakenly forget the equal sign, it takes you to this secondary prompt which can only be exited by
typing an expression that'll cause an error.
*** str="This is some string"
*** str
>>
>>
>> =
>>
>> =str
stdin:6: unexpected symbol near '='
*** =str
This is some string
*** #str
stdin:1: unexpected symbol near '#'
*** =#str
19
***
*** 545+8
stdin:1: unexpected symbol near '545'
*** =545+8
553
***
I need a lesson in using the REPL:
Is there a way to get rid of the equal sign so that it behaves like other REPLs?
How do you exit from the secondary prompt without doing what I did?
Everything you enter in standalone Lua is treated as a statement, as opposed to an expression. The statements are evaluated, and their results, if any, are printed to the terminal. This is why you need to prepend = (really shorthand for return) to the expressions you gave as example to get them to display properly without error.
The "secondary prompt" you are seeing is what happens when you enter an incomplete statement.
In interactive mode, if you write an incomplete statement, the interpreter waits for its completion by issuing a different prompt.
You exit from it by completing the statement.
However, it's not too difficult to make your own REPL that does what you want. Of course, you lose the ability to progressively build statements from incomplete chunks this way, but maybe you don't need that.
local function print_results(...)
-- This function takes care of nils at the end of results and such.
if select('#', ...) > 1 then
print(select(2, ...))
end
end
repeat -- REPL
io.write'> '
io.stdout:flush()
local s = io.read()
if s == 'exit' then break end
local f, err = load(s, 'stdin')
if err then -- Maybe it's an expression.
-- This is a bad hack, but it might work well enough.
f = load('return (' .. s .. ')', 'stdin')
end
if f then
print_results(pcall(f))
else
print(err)
end
until false
Since Lua 5.3, you don't need the =, because Lua first tries to interpret it as an expression now.
From the reference manual:
In interactive mode, Lua repeatedly prompts and waits for a line. After reading a line, Lua first try to interpret the line as an expression. If it succeeds, it prints its value. Otherwise, it interprets the line as a statement. If you write an incomplete statement, the interpreter waits for its completion by issuing a different prompt.
A little test:
Lua 5.3.0 Copyright (C) 1994-2014 Lua.org, PUC-Rio
> str = 'hello' .. ' Lua'
> str
hello Lua
> 1 + 2
3
>