Дизайн шаблона для реализации игры - PullRequest
1 голос
/ 20 сентября 2019

Извините за общее название, если у кого-то после прочтения ниже есть лучший, пожалуйста, измените его.

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

class Game:
    def __init__(self):
        ...        
        self.tokens = num_tokens

class Player:
    def take_token(self, game):
        game.tokens[token] -= 1
        self.tokens[token] += 1
        return game  # the updated game instance

Мне это явно кажется ужасной идеей, потому что я передаю игровое состояние в Player только для того, чтобы манипулировать ими затем отослать это назад ... должен быть намного более чистый способ представить это.Проблема в том, что мне нравится хранить данные под self для каждого объекта, так как это кажется хорошим способом привязать данные к объекту.Может ли кто-нибудь помочь мне определить правильный шаблон дизайна здесь?

Ответы [ 3 ]

1 голос
/ 20 сентября 2019

Поскольку это вопрос, основанный на дизайне, я бы сказал, что вы отдаете больше ответственности одному классу (игроку в вашем случае), чем требуется.Чтобы написать более независимый код, вы должны следовать «Принципу единой ответственности». Вы должны написать слабосвязанный код, как предложено в предыдущих ответах.

В этой ссылке есть приятное чтение: https://medium.com/@severinperez/writing-flexible-code-with-the-single-responsibility-principle-b71c4f3f883f

1 голос
/ 20 сентября 2019

После некоторого обсуждения мы решили, что лучший способ сохранить инкапсуляцию, сохраняя владение объектом соответствующими свойствами, - это использовать геттеры и сеттеры с распространением ошибок:

class Game:
    def __init__(self):
        ...        
        self.tokens = num_tokens

    def take_token(self):
        if self.tokens ≤ 0:
            raise RuntimeError("Trying to take from empty pile")
        self.tokens -= 1
        return True

class Player:
    def take_token(self, game):
        if game.take_token():
            self.tokens[token] += 1

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

1 голос
/ 20 сентября 2019

Как насчет

class Game:
    def __init__(self):
        ...        
        self.tokens = num_tokens

    def give_token(self, token):
        if game.tokens[token] > 0:
           game.tokens[token] -= 1
           return 1
        else:
            return 0

class Player:
    def take_token(self, game):
        self.tokens[token] += game.give_token(token)

...