Постоянный выбор ничего не делая - PullRequest
0 голосов
/ 02 марта 2019

Итак, я пытаюсь сделать простую игру в блэкджек на python 3, и все прекрасно работает, за исключением того, что я терпеть не могу.Если я введу 2, он ничего не сделает.Заранее спасибо.РЕДАКТИРОВАТЬ 1: Удар работает хорошо.РЕДАКТИРОВАТЬ 2: Написал весь сценарий, чтобы вы могли воспроизвести проблему, с которой я столкнулся, как предложил @roganjosh.

from random import shuffle
import sys


def deal(deck, player, dealer):
    shuffle(deck)

    for _ in range(2):
        player.append(deck.pop())
        dealer.append(deck.pop())

def score(hand):
    non_aces = [c for c in hand if c != 'A']
    aces = [c for c in hand if c == 'A']

    sum = 0

    for card in non_aces:
        if card in 'JQK':
            sum += 10
        else:
            sum += int(card)

    for card in aces:
        if sum <= 10:
            sum += 11
        else:
            sum += 1

    return sum

def display_info(player, dealer, stand):
    print("Your cards: [{}] ({})".format(']['.join(player), score(player)))
    if stand:
        print("Dealer cards: [{}] ({})".format(']['.join(dealer), score(dealer)))
    else:
        print("Dealer cards: [{}] [?]".format(dealer[0]))

def results(player, dealer, hand, stand):
    if score(player) == 21 and hand:
        print("Blackjack! You won!")    
        sys.exit()    
    elif score(player) > 21:
        print("Busted. You lost!")   
        sys.exit()     
    if stand:
        if score(dealer) > 21:
            print("Dealer busted. You won!")
        elif score(player) > score(dealer):
            print("You beat the dealer! You won!")
        elif score(player) < score(dealer):
            print("You lost!")
        else:
            print("Push. Nobody wins or losses.")
        sys.exit()

def hit_stand(deck, player, dealer, hand, stand):
    print("What would you like to do")
    print("[1] - Hit\n[2] - Stand")
    choice = input("> ")
    hand = False
    if choice == '1':
        player.append(deck.pop())
    elif choice == '2':
        stand = True
        while score(dealer) <= 16:
            dealer.append(deck.pop())

if __name__ == '__main__':
    deck = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']*4
    player = []
    dealer = []
    standing = False
    first_hand = True
    deal(deck, player, dealer)
    while True:
        display_info(player, dealer, standing)
        results(player, dealer, first_hand, standing)
        hit_stand(deck, player, dealer, first_hand, standing)

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Ответ @roganjosh правильный, но я хотел добавить еще одну заметку, потому что я думаю, что это действительно важный момент о том, как работает Python.Это то, что люди, пришедшие из C / C ++ / Java (то есть почти все мы), должны не учиться при использовании Python.

Как я уже говорил в комментариях выше, в исходном кодеот Марии Лауры, похоже, что вызов hit_stand предназначен для использования некоторых переменных (например, stand) в качестве выходных переменных, а в Python у нас не может быть "выходных переменных" в вызове функции.Но Мария Лаура упомянула, что «удар работает хорошо», что означает, что параметр player изменялся.Итак, если у нас не может быть «выходных переменных», то почему значение player модифицируется функцией hit_stand?

Когда код вызывает hit_stand, пятьобъекты передаются в функцию:

  • Объект списка, которому присваивается имя deck,
  • Объект списка, которому присваивается имя player,
  • Объект списка, которому присваивается имя dealer,
  • Логический объект, которому присваивается имя hand,
  • Логический объект, которому присваиваетсяимя stand

Код за пределами этой функции также имеет имена (deck, player, dealer, first_hand, standing), указывающие на эти же пять объектов.В коде hit_stand метод .append() вызывается для объектов списка player и dealer, а метод .pop() вызывается для объекта deck, поэтому все эти объекты мутируют.Имена из вызывающей области по-прежнему указывают на те же объекты, поэтому эти имена теперь будут видеть эти изменения.

История для hand и stand отличается.Внутри функции hit_stand hand и stand назначаются новые значения с помощью оператора =.Как отмечалось в этой превосходной статье Фредрика Лунда , оператор = в Python не «изменяет» переменную, он просто берет объект и связывает его с именем. Сами объекты не изменились, вместо этого они были заменены новыми логическими объектами. Таким образом, переменная standing во внешней области все еще указывает на свой исходный логический объект, а переменная stand внутри функцииуказывает на совершенно новый логический объект, отличный от внешнего объекта.Мы ничего не можем сделать с переменными hand и stand, которые будут видны во внешней области, не может быть такой вещи, как «передача по ссылке» или «выходной параметр», как у нас в других языках.

Поначалу эта концепция может показаться очень чуждой, пока мы не изучим то, что узнали в нашем обучении C / C ++ / Java.

0 голосов
/ 02 марта 2019

Вы не проверяете результат после того, как игрок решил встать.Поскольку вы только deal() один раз перед циклом while True, вы просто получите бесконечное условие, если вы решите стоять несколько раз.Подсчитайте счет после того, как дилер забрал все свои карты.

def hit_stand(deck, player, dealer, hand, stand):
    print("What would you like to do")
    print("[1] - Hit\n[2] - Stand")
    choice = input("> ")
    hand = False
    if choice == '1':
        player.append(deck.pop())
    elif choice == '2':
        stand = True
        while score(dealer) <= 16:
            print(score(dealer))
            dealer.append(deck.pop())
        display_info(player, dealer, stand)
        results(player, dealer, first_hand, stand) # HERE

На несколько не связанной ноте вылет из игры после определения окончательного результата не очень элегантен.Вы захотите взглянуть на лучшую конструкцию, чем while True: и sys.exit() для управления потоком, но это упражнение для вас.

Наконец, вам не следует использовать sum в качестве имени переменной внутри score() потому что это встроенная функция, которую вы переопределяете.Используйте что-то вроде total, чтобы не рисковать маскированием самой встроенной функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...