Я новичок в программировании и решил начать свое путешествие с Python. Это мой пятый день обучения, и я решил попробовать себя и сделать очень простой игровой автомат. Я застревал на несколько часов, потому что у меня были проблемы со счетчиком баланса, но, наконец, мне удалось заставить его работать.
Не могли бы вы оценить его или высказать свое мнение о том, где код мог быть проще? Большое спасибо!
import random
global a
a = [1000]
global bet
bet = 20
# This is the user's wallet, the list "a" contains the balance
def win1():
# I did different wins, the win1,2,3 function contains them
print("WIN!WIN!WIN! n You won " , bet * 2 , "credits! ")
a.append(a[-1] + (bet * 2))
print("Actual balance : ", a[-1])
def win2():
print("WIN!WIN!WIN! n You won " , bet * 4 , "credits! ")
a.append(a[-1] + (bet * 4))
print("Actual balance : ", a[-1])
def win3():
print("WIN!WIN!WIN! n You won " , bet * 6 , "credits! ")
a.append(a[-1] + (bet * 6))
print("Actual balance : ", a[-1])
def reels():
# Here is the random number calculation.As you can see, theres a pretty good chance to win so it
# would not be a good casino game for the house :)
reel_1 = random.randint(1,3)
reel_2 = random.randint(1,3)
reel_3 = random.randint(1,3)
if reel_1 + reel_2 + reel_3 == 9 :
print("Jackpot!!!!!!!!!!")
a.append(a[-1] + bet * 100)
print ("Actual balance : " , a[-1])
elif reel_1 + reel_2 + reel_3 == 8:
win3()
elif reel_1 + reel_2 + reel_3 == 7:
win2()
elif reel_1 + reel_2 + reel_3 == 6:
win1()
else :
print("No win this time")
def spin() :
# And this is the main function, the spin
spin1 = input("Balance : "+ str(a[-1])+ " Press enter to spin the wheel ")
if spin1 == (""):
print("****************************THE WHEEL IS SPINNING**************************** n "
"")
else :
print("You can only spin the wheel with enter")
spin()
a.append(a[-1] - bet)
print("Balance : " , (a[-1]))
reels() , spin()
spin()
1 ответ
Все твои win1
, win2
а также win3
функции по сути те же. Когда у вас есть несколько функций / частей кода, которые почти идентичны, посмотрите, какие части из них одинаковы, а какие отличаются. Сделайте идентичные части телом функции, а различные части — параметрами функции.
В случае этих трех функций все они одинаковы; кроме бонусного фактора. Просто сделайте это параметром:
def win(bonus_factor):
amount_won = bet * bonus_factor
# I did different wins, the win1,2,3 function contains them
print("WIN!WIN!WIN! n You won " , amount_won, "credits! ")
a.append(a[-1] + amount_won)
print("Actual balance : ", a[-1])
Затем измените callite, чтобы использовать ту же функцию:
elif reel_1 + reel_2 + reel_3 == 8:
win(6)
elif reel_1 + reel_2 + reel_3 == 7:
win(4)
elif reel_1 + reel_2 + reel_3 == 6:
win(2)
А еще лучше 6
, 4
а также 2
должны быть извлечены в константы в верхней части файла, чтобы их можно было легко изменить.
Это уменьшило дублирование этих трех функций, но нужно сказать о нескольких вещах. a
:
Ужасное имя. Имя, которое вы связываете с объектом, должно быть описательным и позволять читателям узнать его назначение. Что для вас больше смысла ?:
a.append(a[-1] + (bet * 4)) balance_history.append(balance_history[-1] + (bet * 4))
Вы обнаружите, что в подавляющем большинстве случаев последнее будет легче понять. Не только
a
полностью не описательный, но он также настолько прост, что вы не можете найти его использование с помощью простых инструментов «поиска», посколькуa
такое обычное письмо.Это необязательно. Если вы выполните поиск использования
a
, вы увидите, что он используется только для двух целей:a[-1]
, а такжеa.append
. Хотя есть что сказать о прогнозировании будущих потребностей, в настоящее время вы накапливаете историю балансов, которые никогда не используете. Это не только использует больше памяти, чем необходимо, но и свертывает логику. Если вы ведете историю, это предполагает, что история где-то используется. Но этого никогда не бывает. Вы можете смело менятьa
кbalance = 1000
, а затем просто вычислите его напрямую. Это сделало бы код более чистым и осмысленным.
Говоря об использовании памяти, вы используете рекурсию для базового цикла, что не очень хорошо. Ваш spin
функция по существу:
def spin():
# Logic
reels(), spin()
Каждый раз, когда ваш игрок делает очередной ход, spin
выделяет другой кадр стека и занимает больше памяти. Если бы ваш игрок сделал ~ 1000 ходов, ваша программа вылетела бы из-за исчерпания стека. Измените эту функцию на базовую while
петля:
def spin():
global balance
while True:
# And this is the main function, the spin
spin1 = input("Balance : " + str(balance) + " Press enter to spin the wheel ")
if spin1 == "":
print("****************************THE WHEEL IS SPINNING**************************** n")
balance -= bet
print("Balance : ", balance)
reels()
else:
print("You can only spin the wheel with enter")
Я сделал несколько изменений:
- Я меняю
balance
быть простым целым числом и обсуждалось выше (обратите внимание, насколько больше смыслаbalance -= bet
делает). - Он использует
while
петля. Это не съедает память при использовании программы. Рекурсию следует зарезервировать для очень конкретных случаев, когда это правильный выбор, например, при итерации рекурсивной структуры. Особенно в таком языке, как Python, следует избегать рекурсии, если вы не очень хорошо с ней знакомы и не знаете о ее сильных и слабых сторонах. - Я переставил
if
ветви. У вас изначально было так, еслиif spin1 == "":
было правдой, все, что это было бы сделать, этоprint
; затем фактическая функциональность произошла в нижней части функции. Я думаю, что в этом есть больше смысла, чем здесь; где все сгруппировано. - Я сделал много мелких доработок (подробнее об этом ниже).
Вы интенсивно используете глобальные переменные. Это довольно распространенное явление, когда вы только начинаете, но это привычка, над которой нужно работать, чтобы исправить ее быстро. Общие практические правила, которым следует следовать, если у вас нет веских причин поступить иначе:
- Все изменяющиеся данные, которые требуются функции для работы (
balance
, например) следует явно передать функции в качестве аргументов. Это означает, что вы можете протестировать функцию, просто передав ей данные, и вам не нужно изменять глобальное состояние. Сейчас это не имеет большого значения, но необходимость изменения изменяемых глобальных переменных для тестирования функции станет катастрофой, когда ваша функция станет больше. - Все данные, которые производит функция, должны быть возвращены из функции. Опять же, это означает, что вы можете тестировать функцию сколько угодно, не затрагивая другой код.
В качестве альтернативы вы также можете обнаружить, что создание класса для поддержания состояния также является более чистым выбором. Однако это становится немного более продвинутым.
Я собираюсь показать полный окончательный код ниже, но мне нужно было внести много мелких исправлений, чтобы сделать его чистым. Обратите внимание на форматирование. Да, это очень важно. В вашем коде есть много мест, где не позаботились о том, чтобы сделать его последовательным и читаемым:
elif reel_1 + reel_2 + reel_3 == 8:
win3()
elif reel_1 + reel_2 + reel_3 == 7: # Too many spaces after the elif
win2()
"Balance : "+ str(a[-1])+ " Press enter to spin the wheel " # Inconsistent spacing around +
def spin() : # There shouldn't be a space before the colon
Если вы собираетесь писать на Python, вам следует потратить день, чтобы прочитать PEP8 по меньшей мере однажды. Внешний вид вашего кода во многом отражает ту осторожность, с которой он был написан. Вы хотите, чтобы ваш код выглядел четким и чистым. У вас могут быть собственные стилистические предпочтения, но будьте последовательны при их применении, а в случае сомнений придерживайтесь PEP8.
Окончательный код:
import random
balance = 1000
bet = 20
def win(bonus_factor):
global balance
amount_won = bet * bonus_factor
# I did different wins, the win1,2,3 function contains them
print("WIN!WIN!WIN! n You won ", amount_won, "credits! ")
balance += amount_won
print("Actual balance : ", balance)
def reels():
global balance
# Here is the random number calculation.As you can see, theres a pretty good chance to win so it
# would not be a good casino game for the house :)
reel_1 = random.randint(1, 3)
reel_2 = random.randint(1, 3)
reel_3 = random.randint(1, 3)
if reel_1 + reel_2 + reel_3 == 9:
print("Jackpot!!!!!!!!!!")
balance += bet * 100
print("Actual balance : ", balance)
elif reel_1 + reel_2 + reel_3 == 8:
win(6)
elif reel_1 + reel_2 + reel_3 == 7:
win(4)
elif reel_1 + reel_2 + reel_3 == 6:
win(2)
else:
print("No win this time")
def spin():
global balance
while True:
# And this is the main function, the spin
spin1 = input("Balance : " + str(balance) + " Press enter to spin the wheel ")
if spin1 == "":
print("****************************THE WHEEL IS SPINNING**************************** n")
balance -= bet
print("Balance : ", balance)
reels()
else:
print("You can only spin the wheel with enter")
spin()
Я очень ценю ваш комментарий, и я почти уверен, что на моем пути ваши советы мне очень помогут. Это уже было полезно и помогло мне думать по-другому, что будет более эффективным и сэкономит время в будущем. Как я уже упоминал, я новичок в этом мире, мне нужно много работать, многому нужно научиться. Спасибо за ваше время, которое вы добавили в этот комментарий! Бог благословил
— Linncsifincsi