I'm trying to make a rock-paper-scissors game, and am trying to verify the input.
def player1():
x = (raw_input("please select: Rock(r)/Paper(p)/Scissors(s): ")).lower()
if x == 'r' or x == 'p' or x == 's' or x == 'rock' or x == 'paper' or x == 'scissors':
return x[0]
else:
print "Error - wrong input!"
player1() #I know I can run a While loop, but I need to run it this way.
print(player1())
If I enter the right input on the first try, everything works fine.
But if I enter wrong input on first try, and enter the right input on the second time, I get None
in the output, instead of the first letter of the RPS options.
What am I missing?
In the
else
branch your function (the first call to your function, in particular) doesn’treturn
anything. In Python functions that do notreturn
anything always returnNone
implicitly.You're going to want to loop on input. What you're doing currently is recursively calling
player1
, and the recursive case doesn't have an explicit return value (hence,None
is returned).The way you do this is simple: while there is invalid input, prompt again. I'm using a modified version of this in the vein of the "while True break" style; it accomplishes the same goal. We loop indefinitely, and if the condition we want is valid, we return; otherwise, we prompt for input and loop again.
As an alternative to that
if
statement, there is a slightly more clean way to express it via thein
operator.As an addendum to your original question (as it says that you have to do it recursively), I must strongly caution you against doing any input evaluation through recursion. Python has a call stack size of around 1,000, which means that you have a very finite (yet reasonably large) amount of tries before the program irrecoverably crashes.
Not just that, but your operation stack will be unnecessarily filled with method calls that behave in a similar fashion to a loop. For memory's sake in addition to the absolute recursion ceiling, do not use recursion for this.
If you absolutely must, and again I strongly advise against doing this, then you simply have to return from your iterative case.
I'm adding this answer for completeness sake, as you do ask for a recursive solution. Here is my solution that is closest to yours:
As you can see, all you've forgotten is a return statement. A more readable way might be:
It would be even cleaner with a do while loop, but python lacks that construct.
An improved version of @Makoto's example:
This is a little more concise than many
or
expressions which gets a bit unwieldy if you have a lot of conditions you want to check!A little explanation:
An even more generalized version of this which becomes reusable:
Example: (reusable, non-recursion:)
Demo:
PS: Sorry I didn't answer your question using recursion. IHMO this is not a good use-case for recursion. Oh well :) However; this is pretty easy to change:
Example: (reusable, recursive)