1

我正在编写一个非常简单的轮盘赌模拟器,只专注于红/黑投注(基本上就像正面或反面的游戏)。

我遇到的问题是跨函数调用变量。

这是代码(我确定它也有其他问题,但我现在专注于这个问题):

import random

# Defines initial amounts of money and losses
money = 50
losses = 0

# Starts the sim
def roulette_sim():
    print "How much do you want to bet?"
    bet = int(raw_input("> "))   
    if bet > money:
        bet_too_much()
    else:
        red_or_black()


# Prevents one from betting more money than one has
def bet_too_much():
    print "You do not have all that money. Please bet again." 
    raw_input("Press ENTER to continue> ")
    roulette_sim()

# Asks user to select red or black, starts the sim, modifies money/losses
def red_or_black():
    print "OK, you bet %r" %  (bet)
    print "Red or black?"
    answer = raw_input("> ")
    number = random.randint(1, 2)
    if number == 1 and answer == "red":
        print "You win!"
        money += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()
    elif number == 2 and answer == "black":
        print "You win!"
        money += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()
    else:
        print "You lost!"
        money -= bet
        losses += bet
        print "You now have %r money" % (money)
        print "Your losses are %r" % (losses)
        replay()

# Asks user whether he/she wants to play again
def replay():
    print "Do you want to play again?"
    play_again = raw_input("y/n> ")
    if play_again == "y":
        roulette_sim()
    else:
        print "OK, bye loser!"


roulette_sim()

所以,我得到NameError: global name 'bet' is not defined了,我可以通过使用来避免global,但我宁愿不诉诸于此。roulette_sim除了通过 using 之外,我如何在其他函数中调用这个变量,以及用户分配给它的值global

我想同样的问题也适用于money变量。

我目前对 Python 有非常基本的了解,因此对于任何错误,我深表歉意。

谢谢

4

3 回答 3

4

使用一个类:

import random

class RouletteSim(object):
    def __init__(self):
        # Defines initial amounts of money and losses
        self.money = 50
        self.losses = 0

    # Starts the sim
    def roulette_sim(self):
        print "How much do you want to bet?"
        bet = int(raw_input("> "))
        if bet > self.money:
            self.bet_too_much()
        else:
            self.red_or_black(bet)

    # Prevents one from betting more money than one has
    def bet_too_much(self):
        print "You do not have all that money. Please bet again."
        raw_input("Press ENTER to continue> ")
        self.roulette_sim()

    # Asks user to select red or black, starts the sim, modifies money/losses
    def red_or_black(self, bet):
        print "OK, you bet %r" %  (bet)
        print "Red or black?"
        answer = raw_input("> ")
        number = random.randint(1, 2)
        if number == 1 and answer == "red":
            print "You win!"
            self.money += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()
        elif number == 2 and answer == "black":
            print "You win!"
            self.money += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()
        else:
            print "You lost!"
            self.money -= bet
            self.losses += bet
            print "You now have %r money" % (self.money)
            print "Your losses are %r" % (self.losses)
            self.replay()

    # Asks user whether he/she wants to play again
    def replay(self):
        print "Do you want to play again?"
        play_again = raw_input("y/n> ")
        if play_again == "y":
            self.roulette_sim()
        else:
            print "OK, bye loser!"

RouletteSim().roulette_sim()
于 2013-09-04T17:12:01.227 回答
2

您可以将值作为参数传递给函数并使函数返回更新的值,例如:

def roulette_sim(money, losses):
    print "How much do you want to bet?"
    bet = int(raw_input("> "))   
    if bet > money:
        return bet_too_much(money, losses)
    else:
        eturn red_or_black(money, losses, bet)

red_or_black它不是修改全局变量moneylosses变量,而是将丢失的 moey 数量传递给使用更新值replay调用的函数。roulette_sim

或者,您可以简单地将所有内容放入一个类中并使用self.money,self.lossesself.bet作为“全局变量”。

但是您可能会注意到这些功能的整体设计很糟糕。他们有复杂的关系并且他们使用递归,这意味着在(可能少于)1000 个赌注之后,您将收到一个RuntimError: Maximum recursion depth exceeded.

您可以重构整个代码以使用循环。只是给出一个想法:

import random



def get_bet():
    bet = float('+inf')
    while bet > money:
        print("How much do you want to bet?")
        bet = int(raw_input("> "))
        if bet > money:
            bet_too_much()
    return bet

def bet_too_much():
    print("you do not have all the money. Please bet again.")
    raw_input("Press ENTER to continue")


def roulette_sim():
    money = 50
    losses = 0
    while True:
        bet = get_bet()
        won = red_or_black(bet)
        money += won
        losses -= won

注意:假设您想编写一个玩家下注的不同游戏。使用您的设计在这个新游戏中重新使用功能真的很hacky。

通过上述设计,您可以自由地重用该get_bet()函数来询问玩家下注等。这只是为使用循环而不是与递归循环紧密耦合函数提供了另一个理由。

于 2013-09-04T17:14:15.177 回答
1

bet 是 roulette_sim 函数中的有效变量,但在 red_or_black 函数中,您首先在

print "OK, you bet %r" %  (bet)

进而

money += bet

和其他无效的,您应该将您的赌注作为参数传递给 red_or_black 调用该函数,如下所示:

red_or_black(bet)   # bet is argument

并将其定义为:

def red_or_black(bet):   # bet is parameter

一切都会好起来的

于 2013-09-04T17:45:52.620 回答