1
import random
numbers = []
wheel1 = 0
wheel2 = 0
wheel3 = 0
winnings = int(0)
balance = int(50)

def generator(balance):

    number1 = random.random()
    number2 = random.random()
    number3 = random.random()

    if number1 < 0.05:
        wheel1 = "Cherry"
    elif number1 < 0.15:
        wheel1 = "Diamond"
    elif number1 < 0.30:
        wheel1 = "Hearts"    
    elif number1 < 0.65:
        wheel1 = "Spade"    
    elif number1 < 1:
        wheel1 = "Monkey"  

    if number2 < 0.05:
        wheel2 = "Cherry"
    elif number2 < 0.15:
        wheel2 = "Diamond"
    elif number2 < 0.30:
        wheel2 = "Hearts"    
    elif number2 < 0.65:
        wheel2 = "Spade"    
    elif number2 < 1:
        wheel2 = "Monkey"

    if number3 < 0.05:
        wheel3 = "Cherry"
    elif number3 < 0.15:
        wheel3 = "Diamond"
    elif number3 < 0.30:
        wheel3 = "Hearts"    
    elif number3 < 0.65:
        wheel3 = "Spade"    
    elif number3 < 1:
        wheel3 = "Monkey"

    return wheel1
    return wheel2
    return wheel3

def win(generator,balance):

    generator(balance)

    if wheel1 =="Monkey"and wheel2 == "Monkey"and wheel3 == "Monkey":
        print "JACKPOT!"
        winnings = int(50)
        balance + winnings
        print 'JACKPOT!'

    else:
        print 'noice'
        winnings = int(10)
        balance + winnings
        print 'noice'

    return balance


print "Welcome to the International Slot Machine"
print ""
print "Balance: $",balance
print ''
spinyn = (raw_input("Would you like to spin? $5 per spin. Enter y or n:\n"))
while True:
    if spinyn == "y":
        break
    elif spinyn == "n":
        print "Final Balance: $",balance
        print "Thank you for using the International Slot Machine"
        raise SystemExit
    else:
        spinyn = raw_input('\033[31mPlease enter only y or n.\033[0m\n')    
spin = (raw_input("Press enter to spin for $5:\n"))
while True:
    if spin == '':
        balance = balance - 5
        if balance <= 0:
            print ""
            print "Final Balance: $",balance
            print "You have run out of money, the game has now ended."
            raise SystemExit
        print ""
        print "\033[34mResult:\033[0m"
        print "\033[34m-------\033[0m"
        balance = generator(balance)
        print ""
        print win(generator,balance)
        print "New balance:$",balance
        print ""
        spinagain = (raw_input("Would you like to spin again? Press enter to spin again, type anything to exit.\n"))
        while True:
            if spinagain == "":
                break
            else:
                print "Final Balance: $",balance
                print "Thank you for using the International Slot Machine"
                raise SystemExit
    else:
        spin = (raw_input("Please press enter to spin.\n"))

I appreciate any suggestions about the method of selecting a random symbol, but please withhold as there is only one question I have. My question is: In the win function, how do I make it recognise the 3 wheel outputs. I've done what I thought would work however it does not, even when I land on 3 monkeys.

Any other suggestions are welcome. But please keep in mind that is the most important.

Thank you very much in advance.

  • 1
    What does `generator` do in your `win` function? – Ozgur Vatansever Aug 19 '15 at 22:12
  • `import random; random.choice(('Cherry', 'Diamond', 'Hearts', 'Spade', 'Monkey'))`. If you do `choices = ('Cherry', 'Diamond', 'Hearts', 'Spade')` then it's even better. – Wayne Werner Aug 19 '15 at 22:19
  • ozgur beat me to an answer. As for suggestions for the generator, my only thought is that you have a lot of repeating code. It would be easier to maintain your code if you had a function to compute a wheel's value based on the random value rather than copying and pasting for each wheel. – bmhkim Aug 19 '15 at 22:20
  • 1
    @WayneWerner: That doesn't give the same result. random.choice will randomly choose any of the choices, without weighting. Scott's implementation weights outcomes differently (e.g., cherry is pretty unlikely). – bmhkim Aug 19 '15 at 22:21
  • @bmhkim good catch. That can be remedied by putting more or less values in your choices though, e.g. `('Cherry', 'Diamond', 'Diamond', 'Hearts', 'Hearts', 'Hearts')`. – Wayne Werner Aug 19 '15 at 22:22
  • @bmhkim That is exactly right bmhkim, I cannot have random choice as having the same chance between cherry and monkey is illogical. – Scott Miller Aug 19 '15 at 22:23
  • @WayneWerner Sort of. What if you need Cherry to come up 23.2232% of the time? – bmhkim Aug 19 '15 at 22:23
  • @bmhkim Yeah, for that case you would need something a little bit more complicated. – Wayne Werner Aug 19 '15 at 22:25
  • @WayneWerner I think that even in the presented case, your solution is suboptimal. Probability for Cherry: 5%, Diamond: 10%, Hearts: 15%, Spade: 35%, Monkey 35%. Your proposal would require a list (or tuple) that is 20 items long, with each occurrence of an item representing a 5% probability, and with two choices repeating 7 times each. Not great, in my opinion. Plus, when you want to adjust probabilities, you're stuck counting off how many of each item is in the list, as well as the full size of the list in order to determine what the current implementation does. – bmhkim Aug 19 '15 at 22:28
  • @ozgue Where did your answer go? – Scott Miller Aug 19 '15 at 22:47
  • @ScottMiller he deleted it – Wayne Werner Aug 19 '15 at 22:47
  • Your extensive edit to the code have rendered both existing answers irrelevant. The `spin` and `win` functions look OK at first glance, what are your exact symptoms now? – Mark Ransom Aug 20 '15 at 01:03
  • @MarkRansom I have returned the code to the original. Please check it. All I want it to do is recognise wheel 1,2 and 3 as whatever I want it to recognise. There is no error, just when Monkey is returned 3 times, the if statement doesn't recognise it. Also I currently get the cannot concatenate str and int error in balance + winnings. – Scott Miller Aug 20 '15 at 01:23

1 Answers1

0

The problem that you have here is that your concept of scope needs a little help.

This answer is a really good start.

To make a short example of your code, let's just do this:

def generator(balance):
    wheel_1 = 'Monkey'
    wheel_2 = 'Diamond'
    wheel_3 = 'Heart'

    return wheel_1, wheel_2, wheel_3


def win(generator):
    print wheel_1, wheel_2, wheel_3

win(generator)

What you'll get here is a NameError, because wheel_1 (and 2 & 3) don't actually exist within the win function. They only exist within the generator function. So what you need to do is get the values from the generator function, and put them somewhere that 'win' can see. You can actually do this pretty easily, since we're already returning the values from the generator function:

# Note: generator was removed as a parameter.
# We don't need it here, because if Python
# can't find the name `generator` it will look
# in the enclosing scope and find the function
# `generator` there.
def win():
    # What we want to do is *call* `generator` and 
    # assign the results to some variables that *are*
    # in `win`'s scope
    wheel_1, wheel_2, wheel_3 = generator()
    print wheel_1, wheel_2, wheel_3

As you mentioned, you can definitely improve some things in your current code. You've noticed inside your generator function there's code that looks almost exactly the same. When you look at code and you get that feeling, that's what's called a "code smell". That's what happens when your (sub)conscious mind sees some code that it knows could be improved. In this particular case there's a principle called DRY - Don't Repeat Yourself.

You can replace your existing code with the following:

def spin_one():
    number = random.random()

    if number < 0.05:
        result = 'Cherry'
    elif number < 0.15:
        result = 'Diamond'
    elif number < 0.30:
        result = 'Hearts'
    elif number < 0.65:
        result = 'Spade'    
    else:
        result = 'Monkey'

    return result

def generator():
    return spin_one(), spin_one(), spin_one()

And what I might even do is remove the generator call altogether and simply do this:

if all((spin_one() == 'Monkey' for _ in xrange(3))):

You can read the docs on all.

Though, if you want to have more than just win a lot and win a little, then you'd need to keep the values:

wheels = [spin_one() for _ in xrange(3)]

Then you can do:

if all(wheel == 'Monkey' for wheel in wheels):
    # Alternatively, wheels.count('Monkey') == 3
    print 'Jackpot'
elif wheels.count('Hearts') == 2:
    print 'Win'
elif all(wheel == 'Lemon' for wheel in wheels):
    print 'You lose'

And any other kind of winning you might want to add.

Prompt

I don't think this is either better or worse than your current prompt approach, but I used to use it all the time in my C++ course.

def prompt():
    choice = raw_input('(Y)es or (N)o: ').lower()
    if choice == 'y':
        return True
    elif choice == 'n':
        return False
    else:
        print '**ERROR** Please input "y" or "n"'
        return prompt()

It's a nice, simple way to get a handle on recursion :)

Community
  • 1
  • 1
Wayne Werner
  • 49,299
  • 29
  • 200
  • 290
  • `def win(balance): wheel_1, wheel_2, wheel_3 = generator(balance) if wheel1 == wheel2 == wheel3 == "Monkey": print "JACKPOT!" winnings = 50 balance = balance + winnings print 'JACKPOT!'` – Scott Miller Aug 19 '15 at 23:09
  • Sorry I don't know how to format it correctly as a comment. – Scott Miller Aug 19 '15 at 23:11
  • @ScottMiller is there any reason you're passing `balance` to your generator? Unless balance is going to affect your odds, you shouldn't need it there. And yeah you can't do multiline comments ;) – Wayne Werner Aug 19 '15 at 23:20
  • @ScottMiller what problem do you still have? – Wayne Werner Aug 19 '15 at 23:40
  • @ScottMiller Your win function returns None, so print win() will just print None. You don't seem to be updating balance anywhere. Also, there are only three outcomes that produce any sort of result (as indicated by the printing in the win function.) Is that want you want? – saulspatz Aug 19 '15 at 23:51
  • @WayneWerner It returns "TypeError: 'str' object is not callable". Its got something to do with wheels = [spin() for _ in xrange(3)]. – Scott Miller Aug 20 '15 at 00:11
  • Ah, you have a variable named `spin`. You need to rename your function, the string input... or you could just get rid of that variable and the check for` ''` – Wayne Werner Aug 20 '15 at 01:22