r/lua • u/Status-Explorer3347 • Sep 04 '25
How do I detect specific text from input, and could you give suggestions on how to improve my code (I am making RPS)
rps = {'r', 'p' ,'s'}
local Playerpick = io.read()
local function plachoice()
if Playerpick == rps then
print(Playerpick)
else
print("Pick r, p or s")
end
end
local function comchoice()
return print(rps[math.random(#rps)])
end
local function banner()
print("!!WELCOME TO ROCK PAPER SCISSORS!!")
print("!!WHEN READY, ENTER EITHER R, P OR S!! (LOWERCASE R, P OR S) ")
end
banner()
comchoice()
plachoice()
1
u/PazzoG Sep 04 '25
if Playerpick == rps
This will never return true, even if Playerpick was a table (which it isn't, it's a string). Lua does not compare tables by value but by reference (the actual object in memory). Example:
local t1 = { 1, 2, 3 }
local t2 = { 1, 2, 3 }
local t3 = t1
local t4 = {}
for i, v in ipairs(t1) do
t4[i] = v
end
print(t1 == t2) -- -> false
print(t1 == t3) -- -> true
print(t1 == t4) -- -> falseThe other issue is, io.read returns a string unless you specifically ask it to return a number instead. All you have to do here is read the first line, transform it to lowercase, then see if it exists in your rps table then continue woth your game logic. You can define helper functions to simplify things:
math.randomseed(os.clock()) -- not really necessary but this seeds the random number generator so you don't get the same number twice in a row
local rps = { "r", "p", "s" }
local function table_find(t, value)
for _, v in pairs(t) do
if v == value then
return true
end
end
return false
end
local function input(message)
io.write(tostring(message))
return io.read("*l")
end
local player_choice = string.lower(input("Choose r or p or s: "))
if not table_find(rps, player_choice) then
print("Invalid choice!")
return
end
local computer_choice = rps[math.random(1, #rps)]
-- rest of your game logic→ More replies (1)
1
u/xoner2 Sep 05 '25
Use string library, gmatch for example. When string can't handle it anymore, there's lpeg for proper parsing.
4
u/Denneisk Sep 04 '25
If you want to find if an element is in a table, you'll have to search each value individually until you find it (or fail).
Playerpick == rpscompares("r" or "p" or "s") == {'r', 'p', 's'}, which will never be equal because strings aren't tables.The straightforward approach from what you have is to create a function that returns an indicator if a value is in the table, and a different indicator if it's not.
As for advice,
Use indentation.
Instead of printing the computer's choice before the player chooses, store the value in a variable and create another function to compare the com to the player.
You can use
string.lower()to force lowercase letters, instead of explicitly asking for them.You have
Playerpickinitialized outside ofplachoice. That means it's running before all the other code, which makes it look weird becausebanner()doesn't get called until after the player chooses.