Skip to content

Latest commit

 

History

History
194 lines (152 loc) · 7.52 KB

File metadata and controls

194 lines (152 loc) · 7.52 KB

七十五、三卡蒙特

原文: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)会怎么样?