Search code examples
lualua-5.1

Program Just Repeats Prompt and then Ends no Matter what I Input (using Lua 5.1)


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!


Solution

  • 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