Python练习案例_Pico Fermi Bagels猜数字游戏

案例介绍--《Python编程快速上手2》

在Pico Fermi Bagels这个逻辑推理游戏中,
你要根据线索猜出一个三位数。
游戏会根据你的猜测给出以下提示之一:如果你猜对一位数字但数字位置不对,则会提示“Pico”;
如果你同时猜对了一位数字及其位置,则会提示“Fermi”;
如果你猜测的数字及其位置都不对,则会提示“Bagels”。
你有10次猜数字机会。

案例完整代码

import random

NUM_DIGITS = 3  # (!) 请试着将3设置为1或10
MAX_GUESSES = 10  # (!) 请试着将10设置为1或100


def main():
    print('''Bagels, a deductive logic game.
By Al Sweigart al@inventwithpython.com

I am thinking of a {}-digit number with no repeated digits.
Try to guess what it is. Here are some clues:
When I say:    That means:
Pico         One digit is correct but in the wrong position.
Fermi        One digit is correct and in the right position.
Bagels       No digit is correct.

For example, if the secret number was 248 and your guess was 843, the
clues would be Fermi Pico.'''.format(NUM_DIGITS))

    while True:  # 主循环
        # secretNum存储了玩家所要猜测的秘密数字
        secretNum = getSecretNum()
        print('I have thought up a number.')
        print(' You have {} guesses to get it.'.format(MAX_GUESSES))

        numGuesses = 1
        while numGuesses <= MAX_GUESSES:
            guess = ''
            # 保持循环,直到玩家输入正确的猜测数字
            while len(guess) != NUM_DIGITS or not guess.isdecimal():
                print('Guess #{}: '.format(numGuesses))
                guess = input('> ')

            clues = getClues(guess, secretNum)
            print(clues)
            numGuesses += 1

            if guess == secretNum:
                break  # 玩家猜对了数字,结束当前循环
            if numGuesses > MAX_GUESSES:
                print('You ran out of guesses.')
                print('The answer was {}.'.format(secretNum))

        # 询问玩家是否想再玩一次
        print('Do you want to play again? (yes or no)')
        if not input('> ').lower().startswith('y'):
            break
        print('Thanks for playing!')


def getSecretNum():
    """返回唯一一个长度为NUM_DIGITS且由随机数字组成的字符串"""
    numbers = list('0123456789')  # 创建数字0~9的列表
    random.shuffle(numbers)  # 将它们随机排列

    # 获取秘密数字列表中的前NUM_DIGITS位数字
    secretNum = ''
    for i in range(NUM_DIGITS):
        secretNum += str(numbers[i])
    return secretNum


def getClues(guess, secretNum):
    """返回一个由Pico、Fermi、Bagels组成的字符串,用于猜测一个三位数"""
    if guess == secretNum:
        return 'You got it!'

    clues = []

    for i in range(len(guess)):
        if guess[i] == secretNum[i]:
            # 正确的数字位于正确的位置
            clues.append('Fermi')
        elif guess[i] in secretNum:
            # 正确的数字不在正确的位置
            clues.append('Pico')
    if len(clues) == 0:
        return 'Bagels'  # 没有正确的数字
    else:
        # 将clues列表按字母顺序排序,使其不会泄露数字的信息
        clues.sort()
        # 返回一个由clues列表中所有元素组成的字符串
        return ' '.join(clues)

 # 程序运行入口(如果不是作为模块导入的话)
if __name__ == '__main__':
    main()

知识点

format()函数

format函数可以将括号中的字符串传入到前面的{}里
print('你的机会:{}'.format(MAX_GUESSES))

isdecimal()函数

isdecimal函数用于判断字符串是否只包含数字,返回Bool值
while len(guess) != NUM_DIGITS or not guess.isdecimal():

函数链式调用

这段判断中连续调用了三个函数,

 if not input('>').lower().startswith('Y'):  
            break  
        print('感谢游玩')  

startswith()函数

这个函数保证了用户输入的字符串中只要有y就会返回Ture

list()函数

这个函数会拆分传入的字符串并拆分为列表,numbers = list('012')等同于number=['0','1','2']
numbers = list('0123456789')

shuffle()函数

shuffle()由random()调用,意为随机.重新排列
import random

# 创建一个包含数字的列表  
numbers = [1, 2, 3, 4, 5]  
# 输出原始列表  
print("Original list:", numbers)   
# 使用 shuffle() 函数打乱列表  
random.shuffle(numbers)  
# 输出打乱后的列表  
print("Shuffled list:", numbers)

insert()函数

insert() 方法接受两个参数:第一个是插入位置的索引,第二个是要插入的元素

join()函数

功能类似字符串拼接,只要是可迭代对象都可以

# 使用空字符串作为分隔符连接列表中的元素  
words = ['Hello', 'world']  
sentence = ''.join(words)  
print(sentence)  # 输出:'Helloworld'  
  
# 使用空格作为分隔符连接列表中的元素  
words = ['Hello', 'world']  
sentence = ' '.join(words)  
print(sentence)  # 输出:'Hello world'  
  
# 使用逗号作为分隔符连接列表中的元素  
fruits = ['apple', 'banana', 'cherry']  
fruit_list = ', '.join(fruits)  
print(fruit_list)  # 输出:'apple, banana, cherry'  
  
# 连接字符串列表  
characters = ['P', 'y', 't', 'h', 'o', 'n']  
word = ''.join(characters)  
print(word)  # 输出:'Python'  
  
# 尝试连接非字符串元素会抛出TypeError  
numbers = [1, 2, 3]  
# result = ''.join(numbers)  # 这会抛出 TypeError  
  
# 如果需要连接非字符串元素,可以首先将它们转换为字符串  
numbers = [1, 2, 3]  
result = ''.join(str(num) for num in numbers)  
print(result)  # 输出:'123'

德摩根定律

非(P 且 Q) = (非 P) 或 (非 Q)
非(P 或 Q) = (非 P) 且 (非 Q)
while len(guess) != NUM_DIGITS or not guess.isdecimal():
德摩根定律转写
while not (len(guess) == NUM_DIGITS and guess.isdecimal()):

多光标操作

在遇到想要删除多行开头一样的东西时,一行行删除会非常繁琐

方法1

按住'ALT',然后'鼠标点击'选中相应的行,'上下键'可以移动光标

方法2

选中想要删除的内容,然后'Ctrl+Shift+L'召出多行光标然后就可以删除了,'上下键'一样可以移动光标,这种方法可以解决大批量代码的情况

posted @   荒坂株式会社  阅读(59)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示