Двадцать одно всем известная карточная игра. Вариантов правил достаточно много. Для простоты и лучшего понимания кода будет придерживаться правил:
- колода 36 карт
- 6, 7, 8, 9, 10 по номиналу
- Валет 2, Дама 3, Король 4, Туз 11
Побеждает тот, кто наберет 21 или больше чем оппонент. Мультиплеер означает, что сначала карты набирает игрок 1, а потом, если игра еще не закончена, игрок 2. Минусом реализации является то, что игрок 2 знает сколько очков набрал первый игрок.
Игра ориентирована на базовый уровень знаний python. Давайте смотреть.
Игра поделена на две функции. В первой мы создаем колоду, а во второй описан игровой процесс.
def deckCreate(): ''' создает колоду карт ''' suits = ['\u2665', '\u2666', '\u2660', '\u2663'] # unicode символы мастей cards = ['6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] all_cards = {j + i for i in suits for j in cards} # заполнение колоды deck = {} for card in all_cards: # присваиваем каждой карте очки # для карт от 6 до 9 номинал - первый символ # для карты 10 номинал первые два символа # для картинок J - 2, Q - 3, K - 4, A - 11 if len(card) == 2: if card[0] == 'A': deck[card] = 11 elif card[0] == 'K': deck[card] = 4 elif card[0] == 'Q': deck[card] = 3 elif card[0] == 'J': deck[card] = 2 else: deck[card] = card[0] else: deck[card] = card[:2] return deck
Чтобы как-то украсить игру через консоль добавим символы мастей. Они есть в unicode таблице. И чтобы не заполнять колоду вручную просто сложим каждый элемент из массива мастей с каждой картой из другого массива. Для этого воспользуемся, возможно, сложной для понимания с первого взгляда конструкцией
all_cards = {j + i for i in suits for j in cards}
Теперь все что нам остается это для каждой карты назначить номинал. В результат функции — словарь из карт с номиналом. Тип данных словарь выбран не просто так. Дело в тома что данные в нем лежат не упорядоченно и извлекая элемент из него нет необходимости пользоваться функцией random модуля math.
def play(): ''' игровой процесс ''' currentPlayer = 'Игрок 1:' currentSum = sum1 = sum2 = 0 hand = '' deck = deckCreate() while True: action = input(currentPlayer + ' Берем карту или хватит? Б-берем, Х-хватит: ') if action.lower() == 'б': card = deck.popitem() currentSum += int(card[1]) hand += card[0] + ' ' print(currentPlayer, hand, 'Сумма очков = ' + str(currentSum)) if currentSum > 21: print('Поражение ' + currentPlayer) break elif currentSum == 21: print('Победа ' + currentPlayer) break # переход хода к другом игроку или конец игры if action.lower() == 'х': if currentPlayer != 'Игрок 2:': sum1 = currentSum currentSum = 0 hand = '' currentPlayer = 'Игрок 2:' else: sum2 = currentSum if sum1 > sum2: print('Победа' + 'Игрок 1') elif sum1 < sum2: print('Победа' + 'Игрок 2') else: print('Ничья') break
В бесконечном цикле while True игроку предлагается брать карты пока он не выиграет набрав 21 очко или не проиграет — набрав больше 21 очка. Игрок может остановиться нажав букву ‘x’. В этом случае ход переходит к другому игроку и повторяет те же действия. После чего определяется победитель.
Интересным моментом в коде является метод lower(). Он переводит ввод с клавиатуры в нижний регистр. Тем самым пользователь может написать «Б» или «б» и программа поймет. Второй момент это card = deck.popitem(). Случайным образом извлекает из словаря карту. Ну и команда break прерывает бесконечный цикл while True
Ну и последнее необходимо взывать программу
play()