Страницы

Поиск по вопросам

среда, 19 июня 2019 г.

Покритикуйте код игры Камень-Ножницы-Бумага

Помогите начинающему в Python - пример кода игры Камень-ножницы-Бумага. Хотел бы избавиться от global аргументов и вообще какие могут быть советы по оптимизации. С ООП еще толком не знаком. Еще не нравится присваивание начальных значений.
Вот пример:
import random CountD = 0 # Счетчики - Ничья, Победа, Проигрыш (Draw, Loose, Win) CountL = 0 CountW = 0 l = ['k','n','b'] # Значения для рандомной выборки - Камень, Ножницы, Бумага
def inp(): # ввод числа раундов global n while True: try: n = int(input('Введите количество игр n ')) return n except ValueError: print('Это не число!')
def logic(x, y): # логика игры global CountD, CountW, CountL if x == y: print('Ничья') CountD += 1 elif (x == 'k' and y == 'n') or (x == 'n' and y == 'b') or (x == 'b' and y == 'k'): print('Выигрыш') CountW += 1 else: print('Проигрыш') CountL += 1 return CountD, CountL, CountW
# Поехали! inp() while n != 0: while True: x = input('Камень (k), Ножницы (n), Бумага (b)') if x not in l: print('Введите k, n, b') else: break
y = random.choice(l) logic(x, y) n -= 1 else: print('Победы - {0}
Проигрыши - {1}
Ничьи- {2}'.format(CountW, CountL, CountD))
В дальнейшем думаю припилить простенький AI, чтобы "ловить" повторения хода игрока.


Ответ

CountD = 0 # Счетчики - Ничья, Победа, Проигрыш (Draw, Loose, Win) CountL = 0 CountW = 0
Ну первое что скажу в питоне принято именовать переменные с маленькой буквы разделяя их нижним подчеркиванием (win_count, lose_count).
l = ['k','n','b'] # Значения для рандомной выборки - Камень, Ножницы, Бумага
Константы так же но в верхнем регистре (TYPE_LIST). И какой смысл так сокращать имена? Тут никакой гонки нет по символам. Должно быть понятно самому программисту что там за объект. Иначе тебе придется комментировать весь свой код.
Для констант списка имеется специальный объект turple, который работает как же как list за исключением того, что его нельзя изменять и тем самым весит он на много меньше.
TYPE_LIST = ('stone', 'scissors', 'paper')
Так же можно заменить на Enum
class GameType(enum.Enum): STONE = 0 SCISSORS = 1 PAPER = 2
Далее не понятно зачем у Вас возвращаются глобальные переменные. Эту строчку можно просто удалить.
return CountD, CountL, CountW
и эту
return n
всю логику запуска скрипта желательно вынести в условие __name__ == '__main__'
if __name__ == '__main__': # Поехали! inp() while n != 0: # ------ # Остальной код
Это означает, что этот блок выполнится только в том случае, если этот скрипт был основным при запуске. Это нужно, чтобы если вдруг Вам понадобилась переменная или функция из этого скрипта, то когда Вы импортируете этот файл и повторно эти функции не выполнятся.
Так же я бы предложил создать отдельный класс для игры
class Game: TYPES = ('stone', 'scissors', 'paper')
def __init__(self): #: WIN, LOSE, DRAW counts = 0, 0, 0 num = 0
def increase_count(self, n): counts[n] += 1
def round_logic(): if self.user_choice == self.ii_choice: print('Ничья') self.increase_count(2) elif (self.user_choice == 'k' and self.ii_choice == 'n') or (self.user_choice == 'n' and self.ii_choice == 'b') or (self.user_choice == 'b' and self.ii_choice == 'k'): print('Выигрыш') self.increase_count(0) else: print('Проигрыш') self.increase_count(1)
def round(self): while True: self.user_choice = input('Камень (k), Ножницы (n), Бумага (b)') if self.user_choice not in Game.TYPES: print('Введите k, n, b') else: break
self.ii_choice = random.choice(Game.TYPES) self.round_logic()
self.num -= 1 if self.num is 0: self.end()
def end(): print('Победы - {0}
Проигрыши - {1}
Ничьи- {2}'.format(*self.counts)
@staticmethod def start(): while True: try: n = int(input('Введите количество игр n ')) return Game(n) except ValueError: print('Это не число!')
if __name__ == '__main__': Game.start()

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

Отправить комментарий