Простой В Python 3 Блэкджек


Я обманул всех вокруг и добавление новых функций в течение нескольких дней(тузы высокая/низкая, поговорки для дилера и т. д.). Однако я довольно неопытный и мне интересно, если любой из моих код можно заменить существующие функции или тому подобное.

import random
from random import shuffle

count = 0

def deck(money):
    print('You sit at the dealer\'s table. You have $' + str(money) + '.')
    card_values = ['Ace High', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']
    suits = ['Spades', 'Clubs' ,'Hearts', 'Diamond']
    deck = []
    for i in range(0, 4):
        for n in range(0, len(card_values)):
            card = [card_values[n],suits[i]]
            deck.append(card)
    shuffle(deck)
    start_deal(deck,[],0,[],0,money)


def print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money):

    print("------------------------------------")
    print("Your hand: {0}".format(player_hand))
    print("Your count: {0}".format(player_count))
    print("Your bet: ${0}".format(bet))
    print("Your money: ${0}".format(money))
    print("Dealer's hand: {0}".format(dealer_hand))
    print("Dealer's count: {0}".format(dealer_count))
    print("Number of cards in deck: {0}".format(len(deck)))
    print("------------------------------------")



def start_deal(deck, player_hand, player_count, dealer_hand, dealer_count, money):
    global count
    count += 1
    if count >= 500:
        print('Your kids miss you')

    bet = int(input('Dealer : So what\'re ya bringing to the table?\n'))
    while bet > money:
        bet = int(input('Dealer : You can\'t bet what you don\'t have kid.\n'))
    money -= bet
    for i in range(0,2):
        results = dealing(deck, player_hand, player_count)
        deck = results[0]
        player_hand = results[1]
        player_count = results [2]

        results = dealing(deck, dealer_hand, dealer_count)
        deck = results[0]
        dealer_hand = results[1]
        dealer_count = results [2]

    if dealer_count == 21:
        print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
        if player_count == 21:
            end_game(player_count, dealer_count, 2, money, bet)
        else:
            end_game(player_count, dealer_count, 1, money, bet)
    if  player_count == 21:
        print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
        end_game(player_count, dealer_count, 3, money, bet)
    else:
        player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, True, money, bet)

def dealing(deck, hand, count):
    if deck[0][0] in [2, 3, 4, 5, 6, 7, 8, 9, 10]:
            count += deck[0][0]
    elif deck[0][0] == 'Ace High':
        if count > 10:
            count += 1
            deck[0][0] = 'Ace Low'
        else:
            count += 11
    else:
        count += 10
    hand.append(deck[0])
    del deck[0]
    return(deck, hand, count)


def player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, intro, money, bet):
    print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
    if intro == True:
        sayings = ['So, hit or stand?', 'Whatcha feelin? hit or stand?','Ouch, if I were you, I\'d stand.',
                   'If I had those cards I\'d hit.','Feeling lucky enough to hit? Or you gonna stand.', 'Get better mate, take a hit.']    
        choice = input('Dealer : ' + sayings[random.randint(0,len(sayings) - 1)] + '\nYour choice: ')
    else:
        choice = input('Your choice: ')

    if choice == 'hit':
        results = dealing(deck, player_hand, player_count)
        deck = results[0]
        player_hand = results[1]
        player_count = results [2]


        if player_count <= 21:
            player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, True, money, bet)
        else:
            for i in range(0,len(player_hand)):
                if player_hand[i][0] == 'Ace High':
                    player_hand[i][0] = 'Ace Low'
                    player_count = player_count - 10
                    player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, True, money, bet)
            print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
            end_game(player_count, dealer_count, 0, money, bet)

    elif choice == 'stand':
        dealer_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet)

    else:
        retorts = ['You\'re slurring your words a lot there, too much to drink?', 'Didn\'t catch that',
                   'What?', 'Did you just sneeze?', 'You studying pig latin, or did I miss hear you?']
        print('Dealer : ' + retorts[random.randint(0,len(retorts) - 1)] + '\n')
        player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, False, money, bet)


def dealer_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet):

    magic_num = random.randint(10,17)

    if dealer_count >= magic_num:
        print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)

    while dealer_count < magic_num or player_count > dealer_count:
        results = dealing(deck, dealer_hand, dealer_count)
        deck = results[0]
        dealer_hand = results[1]
        dealer_count = results [2]
        print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)

    end_game(player_count, dealer_count, 0, money, bet)


def end_game(player_count, dealer_count, db, money, bet):
    if db == 1:
        print('Dealer blackjack, table busts.')
        bet = 0
    elif db == 2:
        print('Dealer and Player blackjack. Push.')
    elif db == 3:
        print('Natural blackjack, you win!')
        bet = bet*2
    elif player_count > 21:
        print('You lost!')
        bet = 0
    elif dealer_count > 21:
        print('Dealer busts, you won!')
        bet = bet*2
    elif player_count == dealer_count:
        print('It\'s a tie!')
    elif dealer_count < player_count:
        print('You won!')
        bet = bet*2
    else:
        print('You lost!')
        bet = 0
    money += bet
    print('You now have $' + str(money) + '.')
    another = input('Dealer : Another round?\n')
    if another == 'yes':
        if money > 0:
            deck(money)
        else:
            print('Dealer: Look\'s like you\'re a bit low on cash there son.\nGame Over')
    else:
        print('You left the table with $' + str(money) + '.')



# Had fun.


295
8
задан 22 февраля 2018 в 09:02 Источник Поделиться
Комментарии
1 ответ

Diclaimer: комментарии в ответ на этот вопрос будет в довольно случайном порядке. Кроме того, из-за случайных и Интерактивного аспектов кода, мои комментарии не очень хорошо протестирован.

Распаковка итерируемый

В dealing функции возвращать несколько элементов. Вы всегда храните их в переменную, потом каждый член по отдельности с помощью [index] синтаксис. Более лаконичный способ сделать это с помощью распаковки Iterable и писать что-то вроде:

    deck, player_hand, player_count = dealing(deck, player_hand, player_count)
deck, dealer_hand, dealer_count = dealing(deck, dealer_hand, dealer_count)

Это также применяется внутрь dealing функция, которая может быть написана:

def dealing(deck, hand, count):
card_value, card_suit = deck[0]
if card_value in [2, 3, 4, 5, 6, 7, 8, 9, 10]:
count += card_value
elif card_value == 'Ace High':
if count > 10:
count += 1
card_value = 'Ace Low'
else:
count += 11
else:
count += 10
hand.append([card_value, card_suit])
del deck[0]
return(deck, hand, count)

Используя право функции/метода

В dealingВы первую карту из колоды затем извлеките ее из колоды. Вы могли бы сделать это в один шаг, используя my_list.pop(0).

Ты напишешь что-то вроде:

def dealing(deck, hand, count):
card_value, card_suit = deck.pop(0)

В player_turn (и другие места), можно использовать сочетание [indexing], randint и len чтобы получить случайный элемент из списка. Это частая проблема, достаточно иметь чистое решение: random.choice(my_list).

Помочь пользователю

Всякий раз, когда вы просите пользователя ввести что, это может помочь, чтобы дать ему список опций, и, когда это возможно, по умолчанию.

Например:

another = input('Dealer : Another round? (\'yes\' to continue, anything else to stop)\n')

или

if intro == True:
sayings = ['So, hit or stand?', 'Whatcha feelin? hit or stand?','Ouch, if I were you, I\'d stand.',
'If I had those cards I\'d hit.','Feeling lucky enough to hit? Or you gonna stand.', 'Get better mate, take a hit.']
prompt = 'Dealer : ' + random.choice(sayings) + '\n'
else:
prompt = ''

choice = input(prompt + 'Your choice: (\'hit\' or \'stand\') ')

(Я взял этот шанс, чтобы разложить на множители общие части)

Сравнение литералов булевых

Когда вы знаете, что значение имеет тип boolean, if value == True эквивалентно короче и элегантнее if value. В вашем случае, эта if intro == True становится if intro.

Рекурсия и ввода пользователя

В player_turnнеправильный ввод данных пользователем осуществляется путем вызова той же функции снова и снова. Это разного рода недостатки. С точки читаемость зрения, вы могли бы иметь более прямой вперед решение. С технической точки зрения, каждый неверный ввод приводит к другому уровню вызовов функций. Это не такая большая проблема, пока вы не достигнете максимальной глубины (тогда ваша программа рухнет), вы хотите отлаживать вашу программу на чтение трассировки стека (тогда он является непригодным для использования из-за количества ненужных и похожих линий).

Более четкое решение заключается в использовании while петли постоянно спрашивать пользователя, если он/она дает правильный ответ.

   choices = ['hit', 'stand']
while True:
choice = input(prompt + 'Your choice: (\'hit\' or \'stand\') ')
if choice not in choices:
retorts = ['You\'re slurring your words a lot there, too much to drink?', 'Didn\'t catch that',
'What?', 'Did you just sneeze?', 'You studying pig latin, or did I miss hear you?']
print('Dealer : ' + random.choice(retorts) + '\n')
else:
break

if choice == 'hit':
etc
else: # 'stand'
etc

Это также устраняет необходимость для intro аргумент ли это нужный вход просят в первый раз или нет.

def player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet):
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
sayings = ['So, hit or stand?', 'Whatcha feelin? hit or stand?','Ouch, if I were you, I\'d stand.',
'If I had those cards I\'d hit.','Feeling lucky enough to hit? Or you gonna stand.', 'Get better mate, take a hit.']
prompt = 'Dealer : ' + random.choice(sayings) + '\n'

choices = ['hit', 'stand']
while True:
choice = input(prompt + 'Your choice: (\'hit\' or \'stand\') ')
if choice not in choices:
retorts = ['You\'re slurring your words a lot there, too much to drink?', 'Didn\'t catch that',
'What?', 'Did you just sneeze?', 'You studying pig latin, or did I miss hear you?']
print('Dealer : ' + random.choice(retorts) + '\n')
prompt = ""
else:
break

Такого же рода проблема появляется с start_deal звоню end_game которая сама себя называет start_deal. Кроме того, из-за всех этих рекурсивных вызовов (прямые или косвенные), у вас есть скрытые проблемы в текущий поток управления. Например start_deal может в конечном итоге звонят напрямую end_game более чем один раз. Это приводит к ситуации, когда пользователь хочет, чтобы остановить воспроизведение, еще одна игра запускается.

Избавление от рекурсии с более простых решений, таких как петли, интересное домашнее задание (на самом деле, более, чем тренировка, это определенно лучший способ ваш код может быть улучшен).

Возвращение или обновление - нужно выбрать (и документа)

На данный момент dealing берет (deck, hand, count) как ввод, обновляет их (или нет) и вернуть их. Это делает функцию странным использовать: как пользователь, я полагаю, рассчитывать на то, что данные были правильно обновлены или я должен полагаться на полученные данные. Хорошая вещь заключается в том, что, похоже, вы решили опираться на данные и быть последовательными в этом.

Вы код можно сделать более кратким, но не может быть яснее и четко (в функции строкой документации, например), что входной обновляется и что возвращаемое значение не только новый граф (потому что целые числа не меняется).

Другой способ делать вещи можно сказать, что dealing функция не нужна deck в качестве параметра, только открытку и голову. То, что ты напишешь что-то вроде:

player_hand, player_count = dealing(deck.pop(0), player_hand, player_count)

Это выглядит немного как половина решения, но это не так плохо...

Еще более интересный способ справиться с этим может быть более объектно-ориентированный подход и определение классов (или одного класса) для представления нескольких объектов вы работаете с и способ их использования. Например, простое решение может быть использовать значения, которые вы держите пересылка от одной функции к другой (deck, player_hand, player_count, dealer_hand, dealer_count, bet, money) как члены класса.

Тип данных

На данный момент, карт представлен список, содержащий значения и масти. Хотя это технически правильно, я бы предпочел использовать для этого кортежа. Я настоятельно рекомендую читать Нэд Батчелдер статьи о списках и кортежах.

Петли, как родной

В Python, вы обычно не нужно сделать элементы из объекта по индексу. Что вы хотите, как правило для перебора различных элементов. Я настоятельно рекомендую читать/смотреть Нэд Батчелдер говорить называемая "петля как родной". (На данном этапе, я могу признаться, что с моей точки зрения, любая статья Нед Батчелдер, о Python или нет, стоит читать, и не один раз).

В вашем случае deck функции будет:

VALUES = ['Ace High', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']
SUITS = ['Spades', 'Clubs' ,'Hearts', 'Diamond']

def deck(money):
print('You sit at the dealer\'s table. You have $' + str(money) + '.')
deck = []
for s in SUITS:
for v in VALUES:
deck.append((v, s))

Кроме того, это может быть переписано в простой форме, используя список осмысления:

def deck(money):
print('You sit at the dealer\'s table. You have $' + str(money) + '.')
deck = [(val, suit) for suit in SUITS for val in VALUES]
shuffle(deck)
start_deal(deck,[],0,[],0,money)

Это может также применяться в player_turn.

Оставлять его здесь.

Я давал много комментариев. Много комментариев можно дать, но прежде чем зайти слишком далеко, я считаю, что это лучшее, что вы думаете о несколько комментариев, которые я оставил для вас, чтобы принять во внимание, о том, как реорганизовать логику, С или без объектно-ориентированное программирование. Я думаю, пытаясь объяснить правила игры, чтобы сами могли помочь Вам разобраться в довольно сложных вложенных вызовов функций.

На этом этапе код выглядит как:

import random
from random import shuffle

count = 0

VALUES = ['Ace High', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Jack', 'Queen', 'King']
SUITS = ['Spades', 'Clubs' ,'Hearts', 'Diamond']

def deck(money):
print('You sit at the dealer\'s table. You have $' + str(money) + '.')
deck = [(val, suit) for suit in SUITS for val in VALUES]
shuffle(deck)
start_deal(deck,[],0,[],0,money)

def print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money):

print("------------------------------------")
print("Your hand: {0}".format(player_hand))
print("Your count: {0}".format(player_count))
print("Your bet: ${0}".format(bet))
print("Your money: ${0}".format(money))
print("Dealer's hand: {0}".format(dealer_hand))
print("Dealer's count: {0}".format(dealer_count))
print("Number of cards in deck: {0}".format(len(deck)))
print("------------------------------------")

def start_deal(deck, player_hand, player_count, dealer_hand, dealer_count, money):
global count
count += 1
if count >= 500:
print('Your kids miss you')

bet = int(input('Dealer : So what\'re ya bringing to the table?\n'))
while bet > money:
bet = int(input('Dealer : You can\'t bet what you don\'t have kid.\n'))
money -= bet
for i in range(0,2):
deck, player_hand, player_count = dealing(deck, player_hand, player_count)
deck, dealer_hand, dealer_count = dealing(deck, dealer_hand, dealer_count)

if dealer_count == 21:
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
if player_count == 21:
end_game(player_count, dealer_count, 2, money, bet)
else:
end_game(player_count, dealer_count, 1, money, bet)
if player_count == 21:
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
end_game(player_count, dealer_count, 3, money, bet)
else:
player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet)

def dealing(deck, hand, count):
card_value, card_suit = deck.pop(0)
if card_value in [2, 3, 4, 5, 6, 7, 8, 9, 10]:
count += card_value
elif card_value == 'Ace High':
if count > 10:
count += 1
card_value = 'Ace Low'
else:
count += 11
else:
count += 10
hand.append([card_value, card_suit])
return(deck, hand, count)

def player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet):
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
sayings = ['So, hit or stand?', 'Whatcha feelin? hit or stand?','Ouch, if I were you, I\'d stand.',
'If I had those cards I\'d hit.','Feeling lucky enough to hit? Or you gonna stand.', 'Get better mate, take a hit.']
prompt = 'Dealer : ' + random.choice(sayings) + '\n'

choices = ['hit', 'stand']
while True:
choice = input(prompt + 'Your choice: (\'hit\' or \'stand\') ')
if choice not in choices:
retorts = ['You\'re slurring your words a lot there, too much to drink?', 'Didn\'t catch that',
'What?', 'Did you just sneeze?', 'You studying pig latin, or did I miss hear you?']
print('Dealer : ' + random.choice(retorts) + '\n')
prompt = ""
else:
break

if choice == 'hit':
deck, player_hand, player_count = dealing(deck, player_hand, player_count)

if player_count <= 21:
player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet)
else:
for i in range(0,len(player_hand)):
if player_hand[i][0] == 'Ace High':
player_hand[i][0] = 'Ace Low'
player_count = player_count - 10
player_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet)
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)
end_game(player_count, dealer_count, 0, money, bet)
else:
dealer_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet)

def dealer_turn(deck, player_hand, player_count, dealer_hand, dealer_count, money, bet):

magic_num = random.randint(10,17)

if dealer_count >= magic_num:
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)

while dealer_count < magic_num or player_count > dealer_count:
deck, dealer_hand, dealer_count = dealing(deck, dealer_hand, dealer_count)
print_game_status(deck, player_hand, player_count, dealer_hand, dealer_count, bet, money)

end_game(player_count, dealer_count, 0, money, bet)

def end_game(player_count, dealer_count, db, money, bet):
if db == 1:
print('Dealer blackjack, table busts.')
bet = 0
elif db == 2:
print('Dealer and Player blackjack. Push.')
elif db == 3:
print('Natural blackjack, you win!')
bet = bet*2
elif player_count > 21:
print('You lost!')
bet = 0
elif dealer_count > 21:
print('Dealer busts, you won!')
bet = bet*2
elif player_count == dealer_count:
print('It\'s a tie!')
elif dealer_count < player_count:
print('You won!')
bet = bet*2
else:
print('You lost!')
bet = 0
money += bet
print('You now have $' + str(money) + '.')
another = input('Dealer : Another round? (\'yes\' to continue, anything else to stop)\n')
if another == 'yes':
if money > 0:
deck(money)
else:
print('Dealer: Look\'s like you\'re a bit low on cash there son.\nGame Over')
else:
print('You left the table with $' + str(money) + '.')

deck(400)

# Had fun.

4
ответ дан 23 февраля 2018 в 12:02 Источник Поделиться