Блэкджек на языке Python (используя Черепаха)


Я был программирования для 2ish месяцев и я был программирования Блэкджек на школьном компьютере, потому что мне было скучно. Если вы, ребята, могли бы проверить, чтобы увидеть, если есть любые проблемы с ним, это было бы здорово!

from turtle import *
import random

updater = Turtle()
updater.ht()
updater.speed(0)
updater.up()
updater.goto(30, 0)
speed(0)
playerMoney = 1000
ht()

class Card:

  def __init__(self, number = None, suit = None):
    if suit == None:
      suit = random.choice(['D', "S", 'C', 'H'])
      number = random.choice(['A',2,3,4,5,6,7,8,9,10,'J','Q', 'K'])
      if number in ['K', 'Q', 'J']:
        number = [number, 10]
      else:
        number = [number, number]
    self.suit = suit
    self.number = number

  def getSuit(self):
    return self.suit

  def getNumber(self):
    return self.number[1]

  def writing(self,x,y):
    up()
    goto(x,y)
    down()
    write (self.number[0])
    up()
    right(90)
    forward(25)
    left(90)
    write(self.suit)
    left(90)
    forward(50)
    right(90)

  def ace(self):
    if 'A' in  self.number:
      x = int(input('Would you like your ace to equal 11 or 1?'))
      if x == 11:
        self.number[1] = 11
      elif x ==1:
        self.number[1] = 1
      else:
        ace(self)

def setup(x, y):
  up()
  goto(x, y)
  down()
  for i in range(2):
    for i in range(2):
      forward(50)
      right(90)
      forward(100)
      right(90)
    forward(50)

def drawcard(x, y):
  up()
  goto(x-25, y+30)
  down()
  for i in range(2):
    forward(50)
    right(90)
    forward(100)
    right(90)

def PcardUpdate(x, sum, playerMoney):
  updater.clear()
  updater.goto(30, 20)
  updater.write('Player Card Sum: ' + str(x))
  updater.goto(30, 0)
  updater.write('Dealer Card Sum:' + str(sum))
  updater.goto(30, -20)
  updater.write('Player Money: ' + str(playerMoney))

def bust(x, playerMoney):
  if x > 21:
    print 'BUST'
    return 0

def HitorNah(bob):
  x = -25 + (bob* 50)
  choice = input('Hit or stand?')
  while choice.lower() not in ['hit', 'stand']:
    choice = input('Hit or stand')
  if choice.lower() == 'hit':
    print 'hit it is'
    bob += 1
    XtraCard = Card()
    XtraCard.writing(x,-55)
    drawcard(x, -55)
    XtraCard.ace()
    return [XtraCard.getNumber(), bob]

  elif choice.lower() == 'stand':
    print 'ok'
    return [0, 0]

  else:
    print "I didn't understand"
    HitorNah(bob)

def DHit(bob, playerhand, sum):
  x = -25 + (bob* 50)
  bob += 1
  XtraCard = Card()
  XtraCard.writing(x-55, 100)
  drawcard(x, 120)
  if XtraCard.getNumber() == 'A':
    if sum + 11 > 21:
      return [1, bob]
    elif sum + 11 == 21:
      return [11, bob]
    else: 
      return [11, bob]
  return [XtraCard.getNumber(), bob]

def Dchecker(sum, x):
  if sum > 21:
    return 'dealer bust'
  elif sum > x and sum < 21:
    return 'dealer win'
  elif sum == x:
    return 'push'
  elif sum == 21:
    return 'dealer win'

def howmuch(player1): #how much the player wants to bet
  bet = int(input('How much would you like to bet? (whole number)'))
  while bet > player1:
    bet = int(input('You cant bet more than you have'))
  while bet < 0:
    bet = int(input('How much would you like to bet? (whole number positive)'))
  while bet == 0:
    print 'you cant bet nothing...'
    bet = int(input('How much would you like to bet? (whole number positive)'))
  return bet

def QuitorNah():
  choice = input('Would you like to quit?')
  while choice.lower() not in ['yes', 'no']:
    print "Sorry I didn't understand."
    choice = input('Would you like to quit')
  if choice.lower() == 'yes':
    print 'Ok, bye'
    return 'bye'
  elif choice.lower() == 'no':
    print 'Ok'
    return

def round(playerMoney):
  PcardUpdate(0, 0, playerMoney)
  playerMoney = playerMoney
  bet = howmuch(playerMoney)
  PcardUpdate(0, 0, playerMoney)
  playerMoney -= bet
  counter = [0, 1]
  joe = [0, 1]
  setup(-100, 150)
  setup(-100, -25)

  #dealer cards
  Dcard1 = Card()
  Dcard1.writing(-75, 100)

  #player cards
  Pcard1 = Card()
  Pcard2 = Card()

  #writes the card down
  Pcard1.writing(-75, -55)
  Pcard2.writing(-25, -55)

  #checks to see if Pcard is ace
  Pcard1.ace()
  Pcard2.ace()
  x = Pcard1.getNumber() + Pcard2.getNumber()
  if x == 21:
    print 'Blackjack!'
    playerMoney = playerMoney + 2*bet
    return playerMoney
  PcardUpdate(x, Dcard1.getNumber(), playerMoney)
  while counter != [0,0]:
    counter = HitorNah(counter[1])
    x += counter[0]
    PcardUpdate(x, Dcard1.getNumber(), playerMoney)
    z = bust(x, playerMoney)
    if z == 0:
      return playerMoney

  sum = Dcard1.getNumber()
  if sum == 'A':
    sum = 11
  result = 'bob'

  while result not in ['dealer bust', 'dealer win', 'push']:
    joe = DHit(joe[1], x, sum)
    sum += joe[0]
    PcardUpdate(x, sum, playerMoney)
    result = Dchecker(sum, x)

  if result == 'dealer bust':
    print 'Dealer bust!'
    playerMoney += 2*bet
    return playerMoney

  elif result == 'dealer win':
    print 'Dealer win!'
    return playerMoney

  elif result == 'push':
    print 'Push!'
    playerMoney += bet
    return playerMoney

while True:
  playerMoney = round(playerMoney)
  if playerMoney == 0:
    print 'You ran out of money :('
    break
  lol = QuitorNah()
  clear()
  if lol == 'bye':
    break


Комментарии
1 ответ

Есть хорошие новости и плохие новости.

Для начинающих код, это довольно хорошо написано. Графика и интуитивное управление простое.

Однако, на сайте вы использовали (тринкет.Ио) позволяет вид питона я не видел раньше. Ваш код не удастся, как в Python 2 и 3. Прежде чем что-то делать, надо убедиться, что он работает по крайней мере одна из этих версий, так что вы больше не ограничены странный вкус в странном месте.

Примечание: Если кто-то знает больше о этот вкус на языке Python, пожалуйста, оставьте комментарий.

Это будет обзор в 3 частях:


  1. Заставить его работать в "нормальном" языке Python.

  2. Сгладить странные вещи и несоответствий в коде.

  3. Замечания от пользовательского опыта точки зрения.

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

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


Заставить его работать

Код больше похож на Python 3, чем 2, поэтому давайте остановимся на этом. Главная причина ваш код не будет работать в Python 3, потому что вашего print заявления. В 2, print Это экзотическое заявление. В 3, print() это правильная функция. Так давайте сделаем их всех вызовов функций.

Вот и все!


Странностей и нестыковок

Повторяйте за мной:


Последовательный код читабельный код.
Читабельный код-это код ремонтопригодны.
Кода является хороший код.

Большинство вещей, которые я упомяну записаны в качестве руководства в расширении предложения на Python (ПЭП). Подробнее о тех, кто здесь.

Основные проблемы (в порядке появления, а не значимости):


  1. Ошибки


    1. Вход

    2. Тузы

    3. Случайные карты


  2. Импорт


    1. Заказ

    2. Импорт одеяло


  3. Пробел


    1. Вмятие

    2. Пустые строки

    3. Операторы

    4. Комментарии


  4. Сравнение

  5. Строки

  6. Именования


    1. Незаконные имена

    2. Функции и переменные


  7. Разное


Ошибка

Вход

Ошибка в исходной и питон 3 версии очевидным, когда вы хотите ставить больше денег, чем доступно:

ValueError: invalid literal for int() with base 10: '' on line 142 in main.py

Или, когда входной сигнал не является целочисленным вообще (но, например, с плавающей точкой или строку):

ValueError: invalid literal for int() with base 10: '150.1' on line 140 in main.py

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

Тузы

Когда Туз нарисован, вам проверить, действительно ли игрок хочет туз посчитать как 11 или 1 очко. Я не уверен, что версия блэкджека вы привыкли, но здесь значение туза может менять по своему желанию и не необходимо ставить на ничью. Например, если я изначально получаете туз и 7, я рассмотрю силы, чтобы быть 18 и 8 одновременно. Я должен решить, взять еще одну карту, и это 3, Туз-11, а силы 21. Если он выше 3, Туз превращается в 1, чтобы избежать перебора. Ваша программа не учитывает этого.

Случайные карты

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

Часть игры состоит в том, чтобы знать, какие карты находятся в игре, так что вы можете рассчитать свои шансы. Если у дилера есть Король и у вас есть 2 Короли, каковы шансы дилера имея другого царя? Это становится еще лучше, когда игра с несколькими игроками за одним столом. Чем больше карт на столе, тем меньше вы должны догадаться об остальных карт.

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

Если вы действительно заинтересованы в блэкджек, я рекомендую читать "дом вверх дном" Бена Мезрича (2002). Или смотреть экранизации фильма "21" (2008). Книга намного лучше.


Импорт

Заказ

Порядок импорта:


  1. Стандартный импорт библиотеки

  2. Импорта третьим лицам

  3. Местное импорта приложения

Разве это дело, когда у вас есть только 2 импортных линий? Нет. Это делает держать вещи легче, когда у вас есть 20 из них? Наверняка.

from turtle import *
import random

Превращается в:

import random
from turtle import *

Импорт одеяло

Вы знаете, что вы импортируете, когда вы используете from turtle import *? Вся черепаха. Вам не нужно всю черепаха. Это то, что вам нужно:

from turtle import Turtle, ht, speed, write, clear, up, down, left, right, goto, forward

И да, немного сложновато. И больше, чем 80 символов. Так, для небольших программ, которые только импорт из библиотеки 1 таким образом, нет никаких проблем. Импорт 6 разных библиотеках, которые, как и вы импортируете много вещей, которые вам не нужны. Что будет, если 2 или 3 библиотеки clear функция? Написав, какие из них вам нужны, вы сразу поймете, проблема должна такая вещь произойдет.

Конечно, очевидным решением будет просто импортировав такой:

import random
import turtle

Да, это приведет к несколько больше звонков. updater = Turtle() превращается в updater = turtle.Turtle() и ht() превращается в turtle.ht(). Но когда вы получаете несколько from lib import * высказывания в ваш код, у вас проблемы.


Пробел

Вмятие

В Python отступы важны. Забудьте отступ строки кода, необходимое количество и ваш код будет делать что-то совсем (если его до сих пор вообще ничего). Чтобы заметить проблемы отступ, это помогает, если вмятины достаточно легко ощутимо, но не настолько сильно, что это сделает линии неоправданно долго. 4 места-это хорошо. Если вы предпочитаете использовать вкладки во время программирования, набора вкладок в помещениях редактор с вкладкой длина 4. Если вы не знаете, какой редактор использовать, дать Атом идти. Работает на все.

Пустые строки

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

Например, между импортом и остальной ваш код всегда будет 2 пустые строки. Между методами? Одной пустой строкой. Между глобальными функциями? 2 линии. Между объявлением класса и первый способ? Нулевой линии.

Операторы

Все операторы получают места вокруг них, кроме всего = при присвоении значений по умолчанию. После запятой всегда пробел, но не более одного. Так это:

number = random.choice(['A',2,3,4,5,6,7,8,9,10,'J','Q', 'K'])

Надо было:

number = random.choice(
['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
)

Комментарии

После # для начала замечание, оставить пространство, прежде чем писать реальный комментарий. Оставить (по крайней мере) 2 места до #.

some_var = 'foo'  # like this


Сравнение


"Сравнения с синглтоны как никто всегда должно быть сделано с 'есть' или 'нет', не операторы равенства."

Как описано здесь, здесь и здесь.


Класс является бесплатным для осуществления сравнения, она выбирает, и он может выбрать, чтобы сделать сравнение с кем-то значит (что на самом деле имеет смысл; если кто-то сказал вам реализовать ни один объект с нуля, как еще можно вам это сравнение справедливо и в отношении себя?).


Строки

Грубо говоря, в Python есть 3 метода с указанием строки.

`keys` and single characters go between single quotes.
"sentences go between double quotes"
"""docstrings and multi-line strings
go between tripled double quotes"""

Также хорошо показано здесь.

И что бы вы ни делали, будьте последовательны. Так что нет больше такого:

suit = random.choice(['D', "S", 'C', 'H'])

Что S между одинарными кавычками, как и все остальные.


Именования

Незаконные имена

Следующий довольно важный.

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

round
sum

У тебя те же функции и имена переменных. Нет.

Рассмотреть что-то, называя через встроенный незаконным.

Функции и переменные

Функция, способ и имен переменных все snake_case. Строчные символы подчеркивания в качестве разделителей. Если вы чувствуете необходимость, чтобы указать функция является частью группы функций, как вы делали с дилерскими функциями, рассмотреть вопрос о внесении их методы частью класса. Проблема решена.

Глобальные переменные, которые никогда не меняли (думаю константы, кроме питона не у них) в UPPER_CASE.

Я не знаю, что bob и joe делают в вашей программе, но имена должны быть эффективными в том, чтобы рассказать миру, что они означают. Те не режут его.

joe = [0, 1]

Понятия не имею.

QuitorNah()

В лучшем случае сомнительными. Не пытайтесь заставить ваши имена функций смешной. Мы получили замечания за это.

z = bust(x, playerMoney)
if z == 0:
return playerMoney

Почему это называется z? Только использовать z если это имеет значение, как и в 3D-графике в качестве третьей оси. Вот, это плохое имя. Возможно, даже хотят уронить з полностью и просто вернуться, когда bust(x, playerMoney) является ложным.


Разное

Там много кода там, похоже, ничего не делает.

def round(playerMoney):
PcardUpdate(0, 0, playerMoney)
playerMoney = playerMoney # <----

Когда у вас закончатся деньги, игра прекращается. Не действительно проблема, но несколько неожиданный. После всего, вы продолжаете спрашивать меня после каждого раунда, хочу ли я бросить. Почему не спрашиваешь в конце каждой игры, хочу ли я новую?

Кроме того, рекомендуется оставлять пробел или перевод строки за вопрос, поэтому ответ не напечатан непосредственно рядом с вопросом. Делает все это только немного аккуратнее.

Я знаю, что большинство людей имеют хороший сегодня большой монитор, но рекомендуется остановиться ниже шириной 80 символов при написании на языке Python. Лучше использовать несколько дополнительных строк, чем строку из 200 символов в ширину. Прокрутка вверх и вниз легко, прокрутка вбок-это более утомительно.

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

Ой, а это ваш Card.getNumber() делать то, что вы думаете?

def getNumber(self):
return self.number[1]

self.number не должно быть в списке.


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

import random
import turtle

updater = turtle.Turtle()
updater.ht()
updater.speed(0)
updater.up()
updater.goto(30, 0)
turtle.speed(0)
playerMoney = 1000
turtle.ht()

class Card:
def __init__(self, number=None, suit=None):
if suit is None:
suit = random.choice(['D', 'S', 'C', 'H'])
number = random.choice(
['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
)
if number in ['K', 'Q', 'J']:
number = [number, 10]
else:
number = [number, number]
self.suit = suit
self.number = number

def getSuit(self):
return self.suit

def getNumber(self):
return self.number[1]

def writing(self, x, y):
turtle.up()
turtle.goto(x, y)
turtle.down()
turtle.write(self.number[0])
turtle.up()
turtle.right(90)
turtle.forward(25)
turtle.left(90)
turtle.write(self.suit)
turtle.left(90)
turtle.forward(50)
turtle.right(90)

def ace(self):
if 'A' in self.number:
x = int(input("Would you like your ace to equal 11 or 1?"))
if x == 11:
self.number[1] = 11
elif x == 1:
self.number[1] = 1
else:
ace(self)

def setup(x, y):
turtle.up()
turtle.goto(x, y)
turtle.down()
for _ in range(2):
for _ in range(2):
turtle.forward(50)
turtle.right(90)
turtle.forward(100)
turtle.right(90)
turtle.forward(50)

def drawcard(x, y):
turtle.up()
turtle.goto(x-25, y+30)
turtle.down()
for _ in range(2):
turtle.forward(50)
turtle.right(90)
turtle.forward(100)
turtle.right(90)

def PcardUpdate(x, card_sum, playerMoney):
updater.clear()
updater.goto(30, 20)
updater.write("Player Card sum: " + str(x))
updater.goto(30, 0)
updater.write("Dealer Card sum: " + str(card_sum))
updater.goto(30, -20)
updater.write("Player Money: " + str(playerMoney))

def bust(x, playerMoney):
if x > 21:
print("Bust!")
return 0

def is_hit(current_player):
x = -25 + (current_player * 50)
choice = input('Hit or stand?')
while choice.lower() not in ['hit', 'stand']:
choice = input('Hit or stand')
if choice.lower() == 'Hit':
print('Hit it is')
current_player += 1
XtraCard = Card()
XtraCard.writing(x, -55)
drawcard(x, -55)
XtraCard.ace()
return [XtraCard.getNumber(), current_player]
elif choice.lower() == 'stand':
print('Ok')
return [0, 0]
else:
print("I didn't understand")
is_hit(current_player)

def DHit(current_player, playerhand, card_sum):
x = -25 + (current_player * 50)
current_player += 1
XtraCard = Card()
XtraCard.writing(x-55, 100)
drawcard(x, 120)
if XtraCard.getNumber() == 'A':
if card_sum + 11 > 21:
return [1, current_player]
elif card_sum + 11 == 21:
return [11, current_player]
else:
return [11, current_player]
return [XtraCard.getNumber(), current_player]

def Dchecker(card_sum, x):
if card_sum > 21:
return 'dealer bust'
elif card_sum > x and card_sum < 21:
return 'dealer win'
elif card_sum == x:
return 'push'
elif card_sum == 21:
return 'dealer win'

def howmuch(player1): # how much the player wants to bet
bet = int(input("How much would you like to bet? (whole number)"))
while bet > player1:
bet = int(
input("You can't bet more than you have.")
)
while bet < 0:
bet = int(
input("How much would you like to bet? (whole positive number)")
)
while bet == 0:
print("No empty bets allowed.")
bet = int(
input("How much would you like to bet? (whole positive number)")
)
return bet

def want_to_quit():
choice = input("Would you like to quit?")
while choice.lower() not in ['yes', 'no']:
print("Sorry I didn't understand.")
choice = input("Would you like to quit")
if choice.lower() == 'yes':
print("Ok, bye")
return 'bye'
elif choice.lower() == 'no':
print("Ok")
return

def play_round(playerMoney):
PcardUpdate(0, 0, playerMoney)
playerMoney = playerMoney
bet = howmuch(playerMoney)
PcardUpdate(0, 0, playerMoney)
playerMoney -= bet
counter = [0, 1]
joe = [0, 1]
setup(-100, 150)
setup(-100, -25)

# dealer cards
Dcard1 = Card()
Dcard1.writing(-75, 100)

# player cards
Pcard1 = Card()
Pcard2 = Card()

# writes the card down
Pcard1.writing(-75, -55)
Pcard2.writing(-25, -55)

# checks to see if Pcard is ace
Pcard1.ace()
Pcard2.ace()
x = Pcard1.getNumber() + Pcard2.getNumber()
if x == 21:
print("Blackjack!")
playerMoney = playerMoney + 2 * bet
return playerMoney
PcardUpdate(x, Dcard1.getNumber(), playerMoney)
while counter != [0, 0]:
counter = is_hit(counter[1])
x += counter[0]
PcardUpdate(x, Dcard1.getNumber(), playerMoney)
z = bust(x, playerMoney)
if z == 0:
return playerMoney

card_sum = Dcard1.getNumber()
if card_sum == 'A':
card_sum = 11
result = 'current_player'

while result not in ['dealer bust', 'dealer win', 'push']:
joe = DHit(joe[1], x, card_sum)
card_sum += joe[0]
PcardUpdate(x, card_sum, playerMoney)
result = Dchecker(card_sum, x)

if result == 'dealer bust':
print('Dealer bust!')
playerMoney += 2*bet
return playerMoney

elif result == 'dealer win':
print('Dealer win!')
return playerMoney

elif result == 'push':
print('Push!')
playerMoney += bet
return playerMoney

while True:
playerMoney = play_round(playerMoney)
if playerMoney == 0:
print("You ran out of money :(")
break
last_round = want_to_quit()
turtle.clear()
if last_round == 'bye':
break

2
ответ дан 13 мая 2018 в 01:05 Источник Поделиться