砰!游戏不能正常工作

时间:2013-12-27 07:53:30

标签: python

我是Python的新手。我建造了一款名为BANG的超棒游戏!这个游戏让你对着电脑,并给你三个选择:拍摄,重装或贴上你的盾牌。计算机每回合随机选择一个选项。然后,摊牌发生。例如,如果您在重新加载计算机时进行拍摄,则计算机将会死机。偶尔可能会赢得额外的生命。

但是,代码无法正常运行。当我告诉计算机打印某些东西时,在某些情况下它会打印它,在其他情况下它不打印。例如,当我使用我唯一的子弹拍摄时,计算机不会打印其动作。此外,有时计算机没有子弹射击,导致子弹水平下降到-1:我认为我已经解决了这个问题,让计算机在不同的子弹条件下随机化了不同的范围。

有人可以帮帮我,为我测试代码吗?

import random

print "Welcome to the Wild West. You see a wild man come towards you. He has a loaded gun in his hand."

bullets = 0
bullets_comp = 3
lives = 1

for turn in range(200):
    if bullets_comp == 0:
        comp_move = random.randint(0,2)        
    elif bullets_comp > 0:
        comp_move = random.randint(0,3)  
    #0 will be reload, 1 wil be shield, 2 will be shoot

    life_chance = random.randint(0,6)
    if life_chance == 3:
        lives = lives + 1
        print "An angel descends randomly and gives you a life!"

    guess = raw_input('What do you choose to do: Reload, Shield, or Shoot?')

    if guess == 'reload' or guess == 'Reload':
        print 'You reload.'
        if comp_move == 0:
            bullets_comp = bullets_comp + 1
            print 'Your opponent reloads.'
        elif comp_move == 1:
            print 'Your opponent raises his shield.'
        elif comp_move == 2:
            if lives == 1:
                print 'Your opponent shoots...YOU DIE!'
                break
            if lives > 1:
                print 'Your opponent shoots...you lose a life.'
                lives = lives - 1


        bullets = bullets + 1

    elif guess == 'Shield' or guess == 'shield':
        print 'You protect yourself.'
        if comp_move == 0:
            bullets_comp = bullets_comp + 1
            print 'Your opponent reloads.'
        elif comp_move == 1:
            print 'Your opponent raises his shield.'
        elif comp_move == 2:
            print 'Your opponent shoots...but you are protected!'
            bullets_comp = bullets_comp - 1

    elif guess == 'Shoot' or guess == 'shoot':
        if bullets == 0:
            print 'You have no bullets!'
        elif bullets > 0:
            print 'You shoot.'
            if comp_move == 0:
                print 'Your opponent reloads.'
                print 'You kill your opponent! Congratulations!'
                break
            elif comp_move == 1:
                print '... but your opponent raises his shield.'
                bullets = bullets - 1
            elif comp_move == 2:
                print 'Your bullets meet each other halfway through the air and combust.'
                bullets_comp = bullets_comp - 1

        bullets = bullets - 1



    else:
        print "You can't do that mate!"

    print 'You have %d bullets and %d lives left' % (bullets, lives)
    print 'Your opponent has %d bullets' %  (bullets_comp)

    print """


    """

4 个答案:

答案 0 :(得分:1)

针对Python 3.3进行了更新,修复了一些问题。

import random

print ("Welcome to the Wild West. You see a wild man come towards you. He has a loaded gun in his hand.")

bullets = 0
bullets_comp = 3
lives = 1
playing = True

有一个退出循环的布尔变量更简洁。之前的比赛在200转后结束,没有任何解释。如果你的意思是有时间限制,那就更明确了。

while playing:

让我们在开始时有状态报告,因为从你的枪没有加载的介绍中并不明显。

    print ("You have",bullets," bullets and ",lives," lives left")
    print ("Your opponent has ",bullets_comp," bullets")

可能是Python 3改变了randInt的工作方式。

    if bullets_comp == 0:
        comp_move = random.randint(0,1)        
    elif bullets_comp > 0:
        comp_move = random.randint(0,2)  
    #0 will be reload, 1 wil be shield, 2 will be shoot

    life_chance = random.randint(0,6)
    if life_chance == 3:
        lives = lives + 1
        print ("An angel descends randomly and gives you a life!")

使用单字母代码进行移动 - 为避免字母S发生冲突,我们将Shoot更改为Fire。将我们的移动存储在变量中可以避免重度嵌套。

    your_move = -1
    while your_move == -1:
        guess = input('What do you choose to do: (R)eload, (S)hield, or (F)ire?')
        if guess == 'r':
            your_move = 0
        elif guess == 's':
            your_move = 1
        elif guess == 'f':
            your_move = 2

现在报告移动。由于射击是对手行动的唯一举动,因此可以在一个地方报道和平动作。

        if your_move == 0:
            print("You reload.")
            bullets = bullets + 1
        elif your_move == 1:
            print("You raise your shield.")
        else:
            assert your_move == 2
            if (bullets == 0):
                print("You fire your empty gun. D'oh.")
                your_move = 0

请注意,我们在此处更改了你的_move,因此玩家不会在下一步中被拍摄。原版允许玩家发射空枪并因此失去转弯,因此我认为这是有意的,并且不应该在移动验证时被抓住。

            else:
                bullets = bullets - 1
                print("You fire.")

        if comp_move == 0:
            print("Your opponent reloads.")
            bullets_comp = bullets_comp + 1
        elif comp_move == 1:
            print("Your opponent raises his shield.")
        else:

使用else + assert而不是elif意味着在非bug的代码中永远不会发生的条件将不会在发布版本中进行测试。请记住,使用elif意味着如果出现意外情况会使调试变得困难,任何事都不会发生。

            assert comp_move == 2
            assert bullets_comp > 0
            bullets_comp = bullets_comp - 1
            print("Your opponent fires.")

现在,如果有人解雇我们确实需要比较这两个动作..

        if your_move == 2:
            if comp_move == 2:
                print("Your bullets meet each other in the air and explode.")
            elif comp_move == 1:
                print("Your bullet hits your opponent's shield.")
            else:
                assert comp_move == 0
                print("You kill your opponent! Congratulations!")
                playing = False
        elif comp_move == 2:
            if your_move == 1:
                print("Your opponent's bullet hits your shield.")
            else:
                assert your_move == 0
                print("Your opponent shoots you..",end="")
                if (lives>1):
                    print(".. you lose a life.")
                    lives = lives - 1
                else:
                    print(".. and you die.")
                    playing = False

请注意,游戏设计也可以改进。目前,玩家总能获胜,因为盾牌100%有效,最终天使给予无限次的生命。这就是为什么我认为时间限制可能是故意的。

答案 1 :(得分:0)

  • 如果您重新加载并且计算机正在拍摄,则不会从bullets_comp中减去。
  • 您在多个地方减去bullets。如果你射击并且你的对手抬起他的盾牌则需要两颗子弹。
  • 如果你试图在没有子弹的情况下进行射击,那么无论如何它都会带走子弹。

答案 2 :(得分:0)

我删除了var" bullet"的多重减法。并修复其余部分:

import random

print "Welcome to the Wild West. You see a wild man come towards you. He has a loaded gun in his hand."

bullets = 0
bullets_comp = 3
lives = 1

for turn in range(200):
    if bullets_comp == 0:
        comp_move = random.randint(0,1)    #edited to (0,1) becuase when it got 2 the computer shot with no bullets.
    elif bullets_comp > 0:
        comp_move = random.randint(0,2)  #edited to (0,2) - when you get 3, the computer doen't do anything.
    #0 will be reload, 1 wil be shield, 2 will be shoot

    life_chance = random.randint(0,6)
    if life_chance == 3:
        lives = lives + 1
        print "An angel descends randomly and gives you a life!"

    guess = raw_input('What do you choose to do: Reload, Shield, or Shoot?')
    if guess == 'reload' or guess == 'Reload':
        print 'You reload.'
        if comp_move == 0:
            bullets_comp = bullets_comp + 1
            print 'Your opponent reloads.'
        elif comp_move == 1:
            print 'Your opponent raises his shield.'
        elif comp_move == 2:
            if lives == 1:
                print 'Your opponent shoots...YOU DIE!'
                break
            if lives > 1:
                print 'Your opponent shoots...you lose a life.'
                lives = lives - 1
        bullets = bullets + 1

    elif guess == 'Shield' or guess == 'shield':
        print 'You protect yourself.'
        if comp_move == 0:
            bullets_comp = bullets_comp + 1
            print 'Your opponent reloads.'
        elif comp_move == 1:
            print 'Your opponent raises his shield.'
        elif comp_move == 2:
            print 'Your opponent shoots...but you are protected!'
            bullets_comp = bullets_comp - 1

    elif guess == 'Shoot' or guess == 'shoot':
        if bullets == 0:
            print 'You have no bullets!'
        elif bullets > 0:
            print 'You shoot.'
            if comp_move == 0:
                print 'Your opponent reloads.'
                print 'You kill your opponent! Congratulations!'
                break
            elif comp_move == 1:
                print '... but your opponent raises his shield.'
            elif comp_move == 2:
                print 'Your bullets meet each other halfway through the air and combust.'
                bullets_comp = bullets_comp - 1
            bullets = bullets - 1 #Edited - now the subtruction is in the "elif bullets > 0:" so you won't subtruct when you have no bullets 



    else:
        print "You can't do that mate!"

    print 'You have %d bullets and %d lives left' % (bullets, lives)
    print 'Your opponent has %d bullets' %  (bullets_comp)

    print """


    """

答案 3 :(得分:0)

我重构了你的代码,如果我去了很远,我道歉。简而言之,我建议将bulletlives操作保留在极少数部分。这将防止错误加倍或减少。在我的代码版本中,我将bullet操作隔离到Player类中。

import cmd
import random
import logging
try:
    import pyreadline as readline
except ImportError:
    pass

SHIELD='shield'
RELOAD='reload'
SHOOT='shoot'


class OutOfLivesException(Exception):
    pass

class Player():

    def __init__(self, name, lives, bullets):
        self.name = name
        self.lives = lives
        self.bullets = bullets
        self.shield_enabled = False

    def reload(self):
        logging.info('%s reloads' % self.name)
        self.bullets = self.bullets + 1

    def has_bullets(self):
        return self.bullets > 0

    def shoot(self, opponent=None):
        if self.has_bullets():
            self.bullets = self.bullets - 1
            if opponent:
                logging.info('%s shoots %s' % (self.name,opponent.name))
                opponent.take_hit()
            else:
                logging.info('%s shoots' % self.name)
        else:
            logging.info('%s has no bullets' % self.name)

    def enable_shield(self):
        logging.info('%s raises shield' % self.name)
        self.shield_enabled = True

    def disable_shield(self):
        self.shield_enabled = False

    def take_hit(self):
        if self.shield_enabled:
            logging.info('%s is protected by shield' % self.name)
            return False

        self.lives = self.lives - 1
        logging.info('%s is hit' % self.name)
        if self.lives <= 0:
            logging.info('%s dies' % self.name)
            raise OutOfLivesException()
        return True

    def __str__(self):
        return '%s has %d bullets and %d lives left' % (self.name, self.bullets, self.lives)


class TurnManager:

    def __init__(self, computer, human):
        self.computer = computer
        self.human = human

    def next_turn(self, computer_action, human_action):
        self._process_pre_turn()
        result = self._process_turn(computer_action, human_action)
        self._process_post_turn()
        return result

    def _run_angel(self, player):
        life_chance = random.randint(0, 6)
        if life_chance == 3:
            player.lives = player.lives + 1
            logging.info(
                "An angel descends randomly and gives %s a life!" % player.name)

    def _display_state(self):
        logging.info(str(self.computer))
        logging.info(str(self.human))

    def _process_pre_turn(self):
        self._run_angel(self.human)

    def _process_turn(self, computer_action, human_action):
        # handle shields
        if(computer_action == SHIELD):
            self.computer.enable_shield()
        if(human_action == SHIELD):
            self.human.enable_shield()

        # handle reloads
        if(computer_action == RELOAD):
            self.computer.reload()
        if(human_action == RELOAD):
            self.human.reload()

        # handle shooting
        if human_action == SHOOT and human_action == computer_action and self.computer.has_bullets() and self.human.has_bullets():
            self.computer.shoot()
            self.human.shoot()
            logging.info(
                'Your bullets meet each other halfway through the air and combust.')
        else:
            if(computer_action == SHOOT):
                try:
                    self.computer.shoot(self.human)
                except OutOfLivesException:
                    return True  # returning true causes Cmd to stop looping
            if(human_action == SHOOT):
                try:
                    self.human.shoot(self.computer)
                except OutOfLivesException:
                    return True  # returning true causes Cmd to stop looping

        self._display_state()

    def _process_post_turn(self):
        # reset shields
        self.computer.disable_shield()
        self.human.disable_shield()


class Bang(cmd.Cmd):

    """Implementation of "Bang" using cmd.Cmd"""

    def emptyline(self):
        pass

    def do_EOF(self, line):
        return True

    def __init__(self, turn_manager):
        cmd.Cmd.__init__(self)

        self.intro = "Welcome to the Wild West. You see a wild man come towards you. He has a loaded gun in his hand."
        self.prompt = "What do you choose to do: Reload, Shield, or Shoot?"

        self.turn_manager = turn_manager

    def process_turn(self, human_action):
        computer_action = random.choice((RELOAD, SHIELD, SHOOT))
        return self.turn_manager.next_turn(computer_action, human_action)

    #
    # RELOAD
    #
    def do_reload(self, line):
        "Reload gun"
        return self.process_turn(RELOAD)

    #
    # SHIELD
    #
    def do_shield(self, line):
        "Cover with Shield"
        return self.process_turn(SHIELD)

    #
    # SHOOT
    #
    def do_shoot(self, line):
        "Shoot the opponent"
        return self.process_turn(SHOOT)


if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO,
                        format='\t%(message)s')

    computer = Player('Computer', 1, 3)
    human = Player('Human', 1, 0)

    turn_manager = TurnManager(computer, human)
    bang = Bang(turn_manager)
    bang.cmdloop()