Python 小型项目大全 71~75

七十一、声音模拟

原文:http://inventwithpython.com/bigbookpython/project71.html

类似于西蒙电子玩具,这款识记游戏使用第三方playsound模块,播放四种不同的声音,分别对应键盘上的ASDF键。当你成功地重复游戏给你的图案时,图案会变得越来越长。你的短期记忆中能容纳多少声音?

如果你看一下代码,你会看到playsound.playsound()函数被传递了要播放的声音的文件名。您可以从以下网址下载声音文件:

inventwithpython.com/soundA.wav

inventwithpython.com/soundS.wav

inventwithpython.com/soundD.wav

inventwithpython.com/soundF.wav

在运行程序之前,将这些文件放在与soundmimic.py相同的文件夹中。关于playsound模块的更多信息可以在pypi.org/project/playsound找到。macOS 上的用户还必须安装来自pypi.org/project/pyobjcpyobjc模块才能让playsound工作。

运行示例

当您运行soundmimic.py时,输出将如下所示:

Sound Mimic, by Al Sweigart email@protected
Try to memorize a pattern of A S D F letters (each with its own sound)
as it gets longer and longer.
Press Enter to begin...
`<screen clears>`
Pattern: S
`<screen clears>`
Enter the pattern:
> s
Correct!
`<screen clears>`
Pattern: S F
`<screen clears>`
Enter the pattern:
> sf
Correct!
`<screen clears>`
Pattern: S F F
`<screen clears>`
Enter the pattern:
> sff
Correct!
`<screen clears>`
Pattern: S F F D
`--snip--`

工作原理

这个程序导入了playsound模块,可以播放声音文件。该模块有一个函数playsound(),您可以向它传递一个wav.mp3文件的文件名来播放它。在每一轮游戏中,程序会在pattern列表中添加一个随机选择的字母(ASDF),并播放列表中的声音。随着pattern列表越来越长,玩家必须记住的声音文件的模式也越来越多。

"""Sound Mimic, by Al Sweigart email@protected
A pattern-matching game with sounds. Try to memorize an increasingly
longer and longer pattern of letters. Inspired by the electronic game,
Simon.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: short, beginner, game"""

import random, sys, time

# Download the sound files from these URLs (or use your own):
# https://inventwithpython.com/soundA.wav
# https://inventwithpython.com/soundS.wav
# https://inventwithpython.com/soundD.wav
# https://inventwithpython.com/soundF.wav

try:
    import playsound
except ImportError:
    print('The playsound module needs to be installed to run this')
    print('program. On Windows, open a Command Prompt and run:')
    print('pip install playsound')
    print('On macOS and Linux, open a Terminal and run:')
    print('pip3 install playsound')
    sys.exit()


print('''Sound Mimic, by Al Sweigart email@protected
Try to memorize a pattern of A S D F letters (each with its own sound)
as it gets longer and longer.''')

input('Press Enter to begin...')

pattern = ''
while True:
    print('\n' * 60)  # Clear the screen by printing several newlines.

    # Add a random letter to the pattern:
    pattern = pattern + random.choice('ASDF')

    # Display the pattern (and play their sounds):
    print('Pattern: ', end='')
    for letter in pattern:
        print(letter, end=' ', flush=True)
        playsound.playsound('sound' + letter + '.wav')

    time.sleep(1)  # Add a slight pause at the end.
    print('\n' * 60)  # Clear the screen by printing several newlines.

    # Let the player enter the pattern:
    print('Enter the pattern:')
    response = input('> ').upper()

    if response != pattern:
        print('Incorrect!')
        print('The pattern was', pattern)
    else:
        print('Correct!')

    for letter in pattern:
        playsound.playsound('sound' + letter + '.wav')

    if response != pattern:
        print('You scored', len(pattern) - 1, 'points.')
        print('Thanks for playing!')
        break

    time.sleep(1) 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果删除或注释掉第 47 行的print('\n' * 60)会发生什么?
  2. 如果把第 62 行的response != pattern改成False会怎么样?

七十二、海绵宝宝大小写

原文:http://inventwithpython.com/bigbookpython/project72.html

你可能见过“嘲讽海绵宝宝”表情包:一张海绵宝宝的照片,其文字说明在大写和小写字母之间交替,以表示讽刺,就像这样:使用海绵宝宝表情包不会让你变得机智。由于某些随机性,文本有时不会交替大写。

这个短程序使用upper()lower()字符串方法将您的消息转换成“海绵宝宝大小写”程序,还被设置成其他程序可以用import将其作为模块导入,然后调用spongecase.englishToSpongecase()函数。

运行示例

当您运行spongecase.py时,输出将如下所示:

sPoNgEcAsE, bY aL sWeIGaRt email@protected

eNtEr YoUr MeSsAgE:
> Using SpongeBob memes does not make you witty.

uSiNg SpOnGeBoB MeMeS dOeS NoT mAkE YoU wItTy.
(cOpIed SpOnGeTexT to ClIpbOaRd.)

工作原理

这个程序中的代码在第 35 行使用了一个for循环来遍历message字符串中的每个字符。useUpper变量包含一个布尔变量,指示字符应该大写(如果True)还是小写(如果False)。第 46 和 47 行在 90%的迭代中切换useUpper中的布尔值(即,将其设置为相反的值)。这意味着大小写几乎总是在大写和小写之间切换。

"""sPoNgEcAsE, by Al Sweigart email@protected
Translates English messages into sPOnGEcAsE.
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: tiny, beginner, word"""

import random

try:
   import pyperclip  # pyperclip copies text to the clipboard.
except ImportError:
    pass  # If pyperclip is not installed, do nothing. It's no big deal.


def main():
    """Run the Spongecase program."""
    print('''sPoNgEtExT, bY aL sWeIGaRt email@protected

eNtEr YoUr MeSsAgE:''')
    spongecase = englishToSpongecase(input('> '))
    print()
    print(spongecase)

    try:
        pyperclip.copy(spongecase)
        print('(cOpIed SpOnGeCasE to ClIpbOaRd.)')
    except:
        pass  # Do nothing if pyperclip wasn't installed.


def englishToSpongecase(message):
    """Return the spongecase form of the given string."""
    spongecase = ''
    useUpper = False

    for character in message:
        if not character.isalpha():
            spongecase += character
            continue

        if useUpper:
            spongecase += character.upper()
        else:
            spongecase += character.lower()

        # Flip the case, 90% of the time.
        if random.randint(1, 100) <= 90:
            useUpper = not useUpper  # Flip the case.
    return spongecase


# If this program was run (instead of imported), run the game:
if __name__ == '__main__':
    main() 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把第 46 行的random.randint(1, 100)改成random.randint(80, 100)会怎么样?
  2. 如果删除或注释掉第 47 行的useUpper = not useUpper会发生什么?

七十三、数独谜题

原文:http://inventwithpython.com/bigbookpython/project73.html

数独是报纸和手机应用中流行的益智游戏。数独棋盘是一个9 × 9的格子,玩家必须将数字 1 到 9 放置一次,并且只能放置一次,在每行、每列和3 × 3的子格子中。游戏开始时,一些空格已经用数字填满,称为预设。一个格式良好的数独谜题将只有一个可能的有效解。

运行示例

当您运行sudoku.py时,输出如下:

Sudoku Puzzle, by Al Sweigart email@protected
`--snip--`
   A B C   D E F   G H I
1  . . . | . . . | . . .
2  . 7 9 | . 5 . | 1 8 .
3  8 . . | . . . | . . 7
   ------+-------+------
4  . . 7 | 3 . 6 | 8 . .
5  4 5 . | 7 . 8 | . 9 6
6  . . 3 | 5 . 2 | 7 . .
   ------+-------+------
7  7 . . | . . . | . . 5
8  . 1 6 | . 3 . | 4 2 .
9  . . . | . . . | . . .

Enter a move, or RESET, NEW, UNDO, ORIGINAL, or QUIT:
(For example, a move looks like "B4 9".)
`--snip--`

工作原理

SudokuGrid类的对象是表示数独网格的数据结构。您可以调用它们的方法来修改网格,或者检索有关网格的信息。例如,makeMove()方法在网格上放置一个数字,resetGrid()方法将网格恢复到原始状态,如果所有解决方案的数字都已放置在网格上,isSolved()将返回True

从第 141 行开始,程序的主要部分为这个游戏使用了一个SudokuGrid对象及其方法,但是您也可以将这个类复制并粘贴到您创建的其他数独程序中,以重用它的功能。

"""Sudoku Puzzle, by Al Sweigart email@protected
The classic 9x9 number placement puzzle.
More info at https://en.wikipedia.org/wiki/Sudoku
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, game, object-oriented, puzzle"""

import copy, random, sys

# This game requires a sudokupuzzle.txt file that contains the puzzles.
# Download it from https://inventwithpython.com/sudokupuzzles.txt
# Here's a sample of the content in this file:
# ..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3..
# 2...8.3...6..7..84.3.5..2.9...1.54.8.........4.27.6...3.1..7.4.72..4..6...4.1...3
# ......9.7...42.18....7.5.261..9.4....5.....4....5.7..992.1.8....34.59...5.7......
# .3..5..4...8.1.5..46.....12.7.5.2.8....6.3....4.1.9.3.25.....98..1.2.6...8..6..2.

# Set up the constants:
EMPTY_SPACE = '.'
GRID_LENGTH = 9
BOX_LENGTH = 3
FULL_GRID_SIZE = GRID_LENGTH * GRID_LENGTH


class SudokuGrid:
   def __init__(self, originalSetup):
       # originalSetup is a string of 81 characters for the puzzle
       # setup, with numbers and periods (for the blank spaces).
       # See https://inventwithpython.com/sudokupuzzles.txt
       self.originalSetup = originalSetup

       # The state of the sudoku grid is represented by a dictionary
       # with (x, y) keys and values of the number (as a string) at
       # that space.
       self.grid = {}
       self.resetGrid()  # Set the grid state to its original setup.
       self.moves = []  # Tracks each move for the undo feature.

   def resetGrid(self):
       """Reset the state of the grid, tracked by self.grid, to the
       state in self.originalSetup."""
       for x in range(1, GRID_LENGTH + 1):
           for y in range(1, GRID_LENGTH + 1):
               self.grid[(x, y)] = EMPTY_SPACE

       assert len(self.originalSetup) == FULL_GRID_SIZE
       i = 0  # i goes from 0 to 80
       y = 0  # y goes from 0 to 8
       while i < FULL_GRID_SIZE:
           for x in range(GRID_LENGTH):
               self.grid[(x, y)] = self.originalSetup[i]
               i += 1
           y += 1

   def makeMove(self, column, row, number):
       """Place the number at the column (a letter from A to I) and row
       (an integer from 1 to 9) on the grid."""
       x = 'ABCDEFGHI'.find(column)  # Convert this to an integer.
       y = int(row) - 1

       # Check if the move is being made on a "given" number:
       if self.originalSetup[y * GRID_LENGTH + x] != EMPTY_SPACE:
           return False

       self.grid[(x, y)] = number  # Place this number on the grid.

       # We need to store a separate copy of the dictionary object:
       self.moves.append(copy.copy(self.grid))
       return True

   def undo(self):
       """Set the current grid state to the previous state in the
       self.moves list."""
       if self.moves == []:
           return  # No states in self.moves, so do nothing.

       self.moves.pop()  # Remove the current state.

       if self.moves == []:
           self.resetGrid()
       else:
           # set the grid to the last move.
           self.grid = copy.copy(self.moves[-1])

   def display(self):
       """Display the current state of the grid on the screen."""
       print('   A B C   D E F   G H I')  # Display column labels.
       for y in range(GRID_LENGTH):
           for x in range(GRID_LENGTH):
               if x == 0:
                   # Display row label:
                   print(str(y + 1) + '  ', end='')

               print(self.grid[(x, y)] + ' ', end='')
               if x == 2 or x == 5:
                   # Display a vertical line:
                   print('| ', end='')
           print()  # Print a newline.

           if y == 2 or y == 5:
                # Display a horizontal line:
                print('   ------+-------+------')

    def _isCompleteSetOfNumbers(self, numbers):
        """Return True if numbers contains the digits 1 through 9."""
        return sorted(numbers) == list('123456789')

    def isSolved(self):
        """Returns True if the current grid is in a solved state."""
        # Check each row:
        for row in range(GRID_LENGTH):
            rowNumbers = []
            for x in range(GRID_LENGTH):
                number = self.grid[(x, row)]
                rowNumbers.append(number)
            if not self._isCompleteSetOfNumbers(rowNumbers):
                return False

        # Check each column:
        for column in range(GRID_LENGTH):
            columnNumbers = []
            for y in range(GRID_LENGTH):
                number = self.grid[(column, y)]
                columnNumbers.append(number)
            if not self._isCompleteSetOfNumbers(columnNumbers):
                return False

        # Check each box:
        for boxx in (0, 3, 6):
            for boxy in (0, 3, 6):
                boxNumbers = []
                for x in range(BOX_LENGTH):
                    for y in range(BOX_LENGTH):
                        number = self.grid[(boxx + x, boxy + y)]
                        boxNumbers.append(number)
                if not self._isCompleteSetOfNumbers(boxNumbers):
                    return False

        return True


print('''Sudoku Puzzle, by Al Sweigart email@protected

Sudoku is a number placement logic puzzle game. A Sudoku grid is a 9x9
grid of numbers. Try to place numbers in the grid such that every row,
column, and 3x3 box has the numbers 1 through 9 once and only once.

For example, here is a starting Sudoku grid and its solved form:

    5 3 . | . 7 . | . . .     5 3 4 | 6 7 8 | 9 1 2
    6 . . | 1 9 5 | . . .     6 7 2 | 1 9 5 | 3 4 8
    . 9 8 | . . . | . 6 .     1 9 8 | 3 4 2 | 5 6 7
    ------+-------+------     ------+-------+------
    8 . . | . 6 . | . . 3     8 5 9 | 7 6 1 | 4 2 3
    4 . . | 8 . 3 | . . 1 --> 4 2 6 | 8 5 3 | 7 9 1
    7 . . | . 2 . | . . 6     7 1 3 | 9 2 4 | 8 5 6
    ------+-------+------     ------+-------+------
    . 6 . | . . . | 2 8 .     9 6 1 | 5 3 7 | 2 8 4
    . . . | 4 1 9 | . . 5     2 8 7 | 4 1 9 | 6 3 5
    . . . | . 8 . | . 7 9     3 4 5 | 2 8 6 | 1 7 9
''')
input('Press Enter to begin...')


# Load the sudokupuzzles.txt file:
with open('sudokupuzzles.txt') as puzzleFile:
    puzzles = puzzleFile.readlines()

# Remove the newlines at the end of each puzzle:
for i, puzzle in enumerate(puzzles):
    puzzles[i] = puzzle.strip()

grid = SudokuGrid(random.choice(puzzles))

while True:  # Main game loop.
    grid.display()

    # Check if the puzzle is solved.
    if grid.isSolved():
        print('Congratulations! You solved the puzzle!')
        print('Thanks for playing!')
        sys.exit()

    # Get the player's action:
    while True:  # Keep asking until the player enters a valid action.
        print()  # Print a newline.
        print('Enter a move, or RESET, NEW, UNDO, ORIGINAL, or QUIT:')
        print('(For example, a move looks like "B4 9".)')

        action = input('> ').upper().strip()

        if len(action) > 0 and action[0] in ('R', 'N', 'U', 'O', 'Q'):
            # Player entered a valid action.
            break

        if len(action.split()) == 2:
            space, number = action.split()
            if len(space) != 2:
                continue

            column, row = space
            if column not in list('ABCDEFGHI'):
                print('There is no column', column)
                continue
            if not row.isdecimal() or not (1 <= int(row) <= 9):
                print('There is no row', row)
                continue
            if not (1 <= int(number) <= 9):
                print('Select a number from 1 to 9, not ', number)
                continue
            break  # Player entered a valid move.

    print()  # Print a newline.

    if action.startswith('R'):
        # Reset the grid:
        grid.resetGrid()
        continue

    if action.startswith('N'):
        # Get a new puzzle:
        grid = SudokuGrid(random.choice(puzzles))
        continue

    if action.startswith('U'):
        # Undo the last move:
        grid.undo()
        continue

    if action.startswith('O'):
        # View the original numbers:
        originalGrid = SudokuGrid(grid.originalSetup)
        print('The original grid looked like this:')
        originalGrid.display()
        input('Press Enter to continue...')

    if action.startswith('Q'):
        # Quit the game.
        print('Thanks for playing!')
        sys.exit()

    # Handle the move the player selected.
    if grid.makeMove(column, row, number) == False:
        print('You cannot overwrite the original grid\'s numbers.')
        print('Enter ORIGINAL to view the original grid.')
        input('Press Enter to continue...') 

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 删除或重命名sudokuzicks.txt文件并运行程序会出现什么错误?
  2. 如果把第 91 行的str(y + 1)改成str(y)会怎么样?
  3. 如果把第 99 行的if y == 2 or y == 5:改成if y == 1 or y == 6:会怎么样?

七十四、文本到语音转换器

原文:http://inventwithpython.com/bigbookpython/project74.html

这个程序演示了第三方模块pyttsx3的使用。您输入的任何消息都会被操作系统的文本到语音转换功能大声朗读出来。虽然计算机生成的语音是计算机科学的一个极其复杂的分支,但pyttsx3模块为它提供了一个简单的接口,使这个小程序适合初学者。一旦你学会了如何使用这个模块,你就可以把生成的语音添加到你自己的程序中。

关于pyttsx3模块的更多信息可以在pypi.org/project/pyttsx3找到。

运行示例

当您运行texttospeechtalker.py时,输出如下:

Text To Speech Talker, by Al Sweigart email@protected
Text-to-speech using the pyttsx3 module, which in turn uses
the NSSpeechSynthesizer (on macOS), SAPI5 (on Windows), or
eSpeak (on Linux) speech engines.

Enter the text to speak, or QUIT to quit.
> Hello. My name is Guido van Robot.
`<computer speaks text out loud>`
> quit
Thanks for playing!

工作原理

这个程序很短,因为pyttsx3模块处理所有的文本到语音代码。要使用该模块,请按照本书介绍中的说明进行安装。一旦你这样做了,你的 Python 脚本可以用import pyttsx3导入它并调用pyttsc3.init()函数。这将返回一个代表文本到语音转换引擎的Engine对象。这个对象有一个say()方法,当您运行runAndWait()方法时,您可以将一个文本字符串传递给它,以便计算机朗读。

"""Text To Speech Talker, by Al Sweigart email@protected
An example program using the text-to-speech features of the pyttsx3
module.
View this code at https://nostarch.com/big-book-small-python-projects
Tags: tiny, beginner"""

import sys

try:
    import pyttsx3
except ImportError:
    print('The pyttsx3 module needs to be installed to run this')
    print('program. On Windows, open a Command Prompt and run:')
    print('pip install pyttsx3')
    print('On macOS and Linux, open a Terminal and run:')
    print('pip3 install pyttsx3')
    sys.exit()

tts = pyttsx3.init()  # Initialize the TTS engine.

print('Text To Speech Talker, by Al Sweigart email@protected')
print('Text-to-speech using the pyttsx3 module, which in turn uses')
print('the NSSpeechSynthesizer (on macOS), SAPI5 (on Windows), or')
print('eSpeak (on Linux) speech engines.')
print()
print('Enter the text to speak, or QUIT to quit.')
while True:
    text = input('> ')

    if text.upper() == 'QUIT':
        print('Thanks for playing!')
        sys.exit()

    tts.say(text)  # Add some text for the TTS engine to say.
    tts.runAndWait()  # Make the TTS engine say it. 

探索程序

这是一个基础程序,所以没有太多的选项来定制它。相反,考虑一下你的其他程序会从文本到语音转换中受益。

七十五、三卡蒙特

原文:http://inventwithpython.com/bigbookpython/project75.html

三卡蒙特是一个常见的骗局,对轻信的游客和其他容易的标志。三张扑克牌,其中一张是红心皇后,正面朝下放在一个纸板盒上。庄家迅速重新排列纸牌,然后让马克挑选红心皇后。但是庄家可以使用各种各样的伎俩来隐藏卡片或欺骗,保证受害者永远不会赢。庄家还经常在人群中找到一些骗子,他们与庄家秘密合作,但假装赢了游戏(让受害者认为他们也能赢)或故意输得很惨(让受害者认为他们能做得更好)。

这个程序展示了三张牌,然后快速描述了一系列的交换。最后,它清空屏幕,玩家必须选择一张牌。你能跟上“红娘”吗?对于真正的三卡蒙特体验,您可以启用作弊功能,这将导致玩家总是输,即使他们选择了正确的卡。

运行示例

当您运行threecardmonte.py时,输出将如下所示:

Three-Card Monte, by Al Sweigart email@protected

Find the red lady (the Queen of Hearts)! Keep an eye on how
the cards move.

Here are the cards:
 ___   ___   ___
|J  | |Q  | |8  |
|| || ||
|__J| |__Q| |__8|
Press Enter when you are ready to begin...
swapping left and middle...
swapping right and middle...
swapping middle and left...
swapping right and left...
swapping left and middle...
`--snip--`
`<screen clears>`
Which card has the Queen of Hearts? (LEFT MIDDLE RIGHT)
> middle
 ___   ___   ___
|Q  | |8  | |J  |
|| || ||
|__Q| |__8| |__J|
You lost!
Thanks for playing, sucker!

工作原理

在这个程序中,我们用一个(rank, suit)元组来表示一张扑克牌。等级是代表卡号的字符串,如'2''10''Q''K',花色是心形、梅花、黑桃或菱形表情符号的字符串。因为你不能用键盘输入表情符号,我们将在第 16 到 19 行使用chr()函数调用来产生它们。元组('9', '♦')代表方块 9。

第 28 到 43 行的displayCards()函数解释这些元组并在屏幕上显示 ASCII 艺术画表示,而不是直接打印出来,就像项目 4“21 点”一样。这个函数的cards参数是扑克牌元组的列表,允许在一行中显示多张牌。

"""Three-Card Monte, by Al Sweigart email@protected
Find the Queen of Hearts after cards have been swapped around.
(In the real-life version, the scammer palms the Queen of Hearts so you
always lose.)
More info at https://en.wikipedia.org/wiki/Three-card_Monte
This code is available at https://nostarch.com/big-book-small-python-programming
Tags: large, card game, game"""

import random, time

# Set up the constants:
NUM_SWAPS = 16   # (!) Try changing this to 30 or 100.
DELAY     = 0.8  # (!) Try changing this 2.0 or 0.0.

# The card suit characters:
HEARTS   = chr(9829)  # Character 9829 is '♥'
DIAMONDS = chr(9830)  # Character 9830 is '♦'
SPADES   = chr(9824)  # Character 9824 is '♠'
CLUBS    = chr(9827)  # Character 9827 is '♣'
# A list of chr() codes is at https://inventwithpython.com/chr

# The indexes of a 3-card list:
LEFT   = 0
MIDDLE = 1
RIGHT  = 2


def displayCards(cards):
   """Display the cards in "cards", which is a list of (rank, suit)
   tuples."""
   rows = ['', '', '', '', '']  # Stores the text to display.

   for i, card in enumerate(cards):
       rank, suit = card  # The card is a tuple data structure.
       rows[0] += ' ___  '  # Print the top line of the card.
       rows[1] += '|{} | '.format(rank.ljust(2))
       rows[2] += '| {} | '.format(suit)
       rows[3] += '|_{}| '.format(rank.rjust(2, '_'))


   # Print each row on the screen:
   for i in range(5):
       print(rows[i])


def getRandomCard():
   """Returns a random card that is NOT the Queen of Hearts."""
   while True:  # Make cards until you get a non-Queen of hearts.
       rank = random.choice(list('23456789JQKA') + ['10'])
       suit = random.choice([HEARTS, DIAMONDS, SPADES, CLUBS])

       # Return the card as long as it's not the Queen of Hearts:
       if rank != 'Q' and suit != HEARTS:
           return (rank, suit)


print('Three-Card Monte, by Al Sweigart email@protected')
print()
print('Find the red lady (the Queen of Hearts)! Keep an eye on how')
print('the cards move.')
print()

# Show the original arrangement:
cards = [('Q', HEARTS), getRandomCard(), getRandomCard()]
random.shuffle(cards)  # Put the Queen of Hearts in a random place.
print('Here are the cards:')
displayCards(cards)
input('Press Enter when you are ready to begin...')

# Print the swaps:
for i in range(NUM_SWAPS):
   swap = random.choice(['l-m', 'm-r', 'l-r', 'm-l', 'r-m', 'r-l'])

   if swap == 'l-m':
       print('swapping left and middle...')
       cards[LEFT], cards[MIDDLE] = cards[MIDDLE], cards[LEFT]
   elif swap == 'm-r':
       print('swapping middle and right...')
       cards[MIDDLE], cards[RIGHT] = cards[RIGHT], cards[MIDDLE]
   elif swap == 'l-r':
       print('swapping left and right...')
       cards[LEFT], cards[RIGHT] = cards[RIGHT], cards[LEFT]
   elif swap == 'm-l':
       print('swapping middle and left...')
       cards[MIDDLE], cards[LEFT] = cards[LEFT], cards[MIDDLE]
   elif swap == 'r-m':
       print('swapping right and middle...')
       cards[RIGHT], cards[MIDDLE] = cards[MIDDLE], cards[RIGHT]
   elif swap == 'r-l':
       print('swapping right and left...')
       cards[RIGHT], cards[LEFT] = cards[LEFT], cards[RIGHT]

   time.sleep(DELAY)

# Print several new lines to hide the swaps.
print('\n' * 60)

# Ask the user to find the red lady:
while True:  # Keep asking until LEFT, MIDDLE, or RIGHT is entered.
    print('Which card has the Queen of Hearts? (LEFT MIDDLE RIGHT)')
    guess = input('> ').upper()

    # Get the index in cards for the position that the player entered:
    if guess in ['LEFT', 'MIDDLE', 'RIGHT']:
        if guess == 'LEFT':
            guessIndex = 0
        elif guess == 'MIDDLE':
            guessIndex = 1
        elif guess == 'RIGHT':
            guessIndex = 2
        break

# (!) Uncomment this code to make the player always lose:
#if cards[guessIndex] == ('Q', HEARTS):
#    # Player has won, so let's move the queen.
#    possibleNewIndexes = [0, 1, 2]
#    possibleNewIndexes.remove(guessIndex)  # Remove the queen's index.
#    newInd = random.choice(possibleNewIndexes)  # Choose a new index.
#    # Place the queen at the new index:
#    cards[guessIndex], cards[newInd] = cards[newInd], cards[guessIndex]

displayCards(cards)  # Show all the cards.

# Check if the player won:
if cards[guessIndex] == ('Q', HEARTS):
    print('You won!')
    print('Thanks for playing!')
else:
    print('You lost!')
    print('Thanks for playing, sucker!') 

在输入源代码并运行几次之后,尝试对其进行实验性的修改。标有(!)的注释对你可以做的小改变有建议。你也可以自己想办法做到以下几点:

  • 使用项目 57“进度条”中的退格打印技术,简单显示每条交换信息,然后打印\b字符,在打印下一条信息之前将其删除。
  • 创建一个增加难度的四卡蒙特游戏。

探索程序

试着找出下列问题的答案。尝试对代码进行一些修改,然后重新运行程序,看看这些修改有什么影响。

  1. 如果把第 64 行的[('Q', HEARTS), getRandomCard(), getRandomCard()]改成[('Q', HEARTS), ('Q', HEARTS), ('Q', HEARTS)]会怎么样?
  2. 如果把第 49 行的list('23456789JQKA')改成list('ABCDEFGHIJK')会怎么样?
  3. 如果删除或注释掉第 93 行的time.sleep(DELAY)会怎么样?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/10011.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SSL】ssl证书简介、ssl证书生成工具与ssl证书生成步骤

ssl证书简介、ssl证书生成工具与ssl证书生成步骤一、ssl证书是什么&#xff1f;二、ssl证书生成工具有哪些&#xff1f;2.1、工具一&#xff1a;CFSSL2.2、工具二&#xff1a;OpenSSL2.3、工具三&#xff1a;XCA三、ssl证书有什么用&#xff1f;四、ssl证书生成步骤4.1 步骤1&a…

6基于二阶锥规划的主动配电网最优潮流求解

matlab代码&#xff1a;基于二阶锥规划的主动配电网最优潮流求解 参考文献&#xff1a;主动配电网多源协同运行优化研究_乔珊 摘要&#xff1a;最优潮流研究在配 电网规划运行 中不可或缺 &#xff0c; 且在大量分布式能源接入 的主动配 电网环境下尤 为重要 。传统的启发式算…

【安全防御】防火墙(二)

目录 1、防火墙如何处理双通道协议 2、防火墙如何处理nat 3、防火墙支持哪些NAT&#xff0c;主要应用的场景是什么&#xff1f; 4、当内网PC通过公网域名解析访问内网服务器的时候&#xff0c;会存在什么问题&#xff0c;如何解决&#xff1f;请详细说明 5.防火墙使用VRRP…

2023-04-10 网络流和最大流问题

网络流和最大流问题 1 网络流和最大流问题阐述 网络流基本概念 网络流图中&#xff0c;从源点出发&#xff0c;在满足每条边容量限制的条件下&#xff0c;汇点t最多能接收多少流量 s:sourcet:target 网络流需要满足的限制 容量限制平衡限制&#xff1a;除了源点s和汇点t&a…

第三章 spring IOC与Bean环境搭建与应用

1、手动导入Lib包搭建环境 1.1、下载Apache Common Logging API https://commons.apache.org/proper/commons-logging/download_logging.cgi 1.2、下载spring https://repo.spring.io/ui/native/release/org/springframework/spring/5.3.13/ 名称作用docs包含 Spring 的 …

李宏毅2021春季机器学习课程视频笔记9-再谈宝可梦分类器

宝可梦与数码宝贝很类似。 明显数码宝贝的线条更加复杂&#xff0c;宝可梦更简单&#xff0c;可以从这个角度出发。 利用一些边缘检测工具&#xff08;&#xff43;&#xff41;&#xff4e;&#xff4e;&#xff59;&#xff09;&#xff0c;&#xff45;用来计算线条的复杂程…

CSDN,感谢遇见【我的一周年创作纪念日】

机缘 第一次遇见CSDN已经是7年前的事了&#xff0c;那时的我还是一名初二的学生&#xff0c;由于沉迷于玩具战争这款游戏&#xff08;很遗憾这款游戏已经停服&#xff09;&#xff0c;里面有许多大佬利用各种手段去开挂&#xff0c;所以我意外的接触到了浏览器抓包等计算机技术…

考研数二第十四讲 牛顿-莱布尼茨公式与用定义法求解定积分

牛顿-莱布尼茨公式 牛顿-莱布尼茨公式在微分与积分以及不定积分与定积分之间架起了一座桥梁&#xff0c;因此&#xff0c;这个公式又被称为微积分基本公式。 微积分基本公式的简单推导 在看微积分基本公式之前&#xff0c;我们先来看一个有点特殊的函数&#xff0c;积分上限…

HashMap和HashTable的区别

目录一、HashMap和HashTable的区别二、验证结论1.线程安全和不安全2.继承的父类不同3.对null key和null value的支持不同4.初始化和扩容方式不同一、HashMap和HashTable的区别 1.HashMap方法没有synchronize修饰&#xff0c;线程非安全&#xff0c;HashTable安全 拓展:HashTabl…

OctoClock CDA 2990

CDA 2990 CDA 2990为时钟和PPS分发设备&#xff0c;支持外部一路时钟和PPS输入&#xff0c;最高支持8路时钟和PPS输出。同时CDA 2990可选配带GPS模块版本&#xff0c;可外接GPS天线&#xff0c;支持通过GPS锁定时钟和PPS信号输出。CDA 2990主要用于多台USRP设备进行同步。 CDA…

康耐视Designer-通过康耐视VC5与Omron PLC CJ2MEthernet IP通讯详细设置步骤

测试使用软件版本 Designer Version: 2.7 EDS File Version: 1.01 CX Programmer Version: 9.2 Network Configurator Version: 3.56 测试使用硬件 Cognex Vision Controller VC5 CIC500&CIC2900 OMRON PLC: CJ2M CPU31 PLC端设置 1.在Network Configurator中安装…

算法 二叉树2 || 层序遍历 226.翻转二叉树 101. 对称二叉树 104.二叉树的最大深度 111 二叉树的最小深度 222.完全二叉树的节点个数

102 二叉树的层序遍历 队列先进先出&#xff0c;符合一层一层遍历的逻辑&#xff0c;而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。 而这种层序遍历方式就是图论中的广度优先遍历&#xff0c;只不过我们应用在二叉树上。 迭代法&#xff1a; /*** Definition for …

进来拿!最近疯传的154页微软 GPT-4早期实验报告:探究 AGI进化之路(全中文版)

这应该是&#xff0c;最近一段时间以来&#xff0c;关于 ChatGPT4.0剖析最全面的一份报告。 看懂10%&#xff0c;能帮我们对 ChatGPT 的认识&#xff0c;有一个质的跃升&#xff1b; 看懂50%&#xff0c;你将是分享 ChatGPT 知识领域最顶尖的那一拨人。 这份报告证明了 GPT-4…

若依数据隔离 ${params.dataScope} 替换 优化为sql 替换

若依数据隔离 ${params.dataScope} 替换 优化为sql 替换 安全问题:有风险的SQL查询&#xff1a;MyBatis解决 若依框架的数据隔离是通过 ${params.dataScope} 实现的 但是在代码安全扫描的时候$ 符会提示有风险的SQL查询&#xff1a;MyBatis 所以我们这里需要进行优化参考: M…

5分钟学会Ribbon负载均衡

文章目录一、Ribbon1.1 Ribbon的负载均衡流程&#xff1a;1.2 负载均衡策略1.2.1 内置的负载均衡策略1.2.2 如何修改负载均衡1.3 加载方式一、Ribbon 1.1 Ribbon的负载均衡流程&#xff1a; 获取可用的服务列表&#xff1a;客户端在进行服务调用之前&#xff0c;首先需要获取可…

如何基于ChatGPT+Avatar搭建24小时无人直播间

0 前言 最近朋友圈以及身边很多朋友都在研究GPT开发&#xff0c;做了各种各样的小工具小Demo&#xff0c;AI工具用起来是真的香&#xff01;在他们的影响下&#xff0c;我也继续捣鼓GPT Demo&#xff0c;希望更多的开发者加入一起多多交流。 上一篇结合即时通 IM SDK捣鼓了一个…

SpringAOP入门基础银行转账实例(进阶版)------------事务处理

SpringAOP入门基础银行转账实例**&#xff08;进阶版&#xff09;**------------事务处理 由上一节讲述的通过Connection和QueryRunner对事务进行的处理(详情可以去我之前写的博客文章&#xff1a;https://blog.csdn.net/m0_56245143/article/details/130069160?spm1001.2014…

VMware vSphere 8.0c - 企业级工作负载平台

ESXi 8.0.0 & vCenter Server 8.0.0 GA (General Availability) 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023-03-30, VMware vSphere 8.0c 发…

静态库与动态库

库是已经写好的、成熟的、可复用的代码。在我们的开发的应用中经常有一些公共代码是需要反复使用的&#xff0c;就把这些代码编译为库文件。库可以简单看成一组目标文件的集合&#xff0c;将这些目标文件经过压缩打包之后形成的一个可执行代码的二进制文件。库有两种&#xff1…

Ubuntu硬盘分区、挂载

文章目录1、使用命令查看硬盘情况2、分区3、格式化分区4、挂载手动挂载自动挂载1、使用命令查看硬盘情况 sudo fdisk -l 可以看到这里有个未分区的4T硬盘 如&#xff1a;sdb 这样的是硬盘 sdb1 sdb2 这样的是分区&#xff0c;现在还没分区 2、分区 sudo parted /dev/sdb (s…
最新文章