Класс ООП роботов в Python

Привет всем!

Вот в чем дело. Итак, я сначала хотел создать класс Робота, я хочу, чтобы он передвигался по какой-нибудь доске. Может быть, 10×10 или что-то в этом роде, тогда я хотел изобрести класс боевых роботов, я хочу добавить классных игроков (потому что я хочу играть между игроком 1 и игроком 2), но вот это то, что у меня так много.

Давайте сосредоточимся на этом коде, потому что я хочу, чтобы он улучшил его, а затем приступил к созданию боев роботов!

class Robot:

    def __init__(self, name, place, start = (0,0), power = 9):
        self.name = name
        self.start = start
        self.place = place
        self.power = power
        
    def get_name(self):
        return self.name
        
    def get_start(self):
        return self.start
        
    def get_place(self):
        return self.place
        
    def get_power(self):
        return self.power
        

    
    def set_name(self, x):
        if isinstance(x, str):
            self.name = x
        else:
            raise TypeError("must be a string")
    
    def set_start(self, x):
        if isinstance(x, tuple):
            self.start = x
        else:
            raise TypeError("must be a tuple")
    
    def set_place(self, x):
        if isinstance(x, list):
            self.place = x
        else:
            raise TypeError("must be a list")
    
    def set_power(self, x):
        if isinstance(x, int):
            self.power = x
        else:
            raise TypeError("must a int")
    
    
    
    def check_power(self):
        if self.power <= 0:
            raise ValueError("No power")
            
          
    def left(self, value):
        self.check_power()
        
        self.power -= value

        if self.place[0] - value < 0:
            self.place[0] = self.place[0] - value + 8

        else:
            self.place[0] = self.place[0] - value
            
    def up(self, value):
        self.check_power()
        
        self.power -= value

        if self.place[1] + value > 7:
            self.place[1] = self.place[1] + value - 8

        else:
            self.place[1] = self.place[1] + value

        if self.place[1] == 5:
            self.power += 2

    def __str__(self):
        return self.name, self.place, self.power

Также хочу, чтобы я стал лучше в этом. Что ж, сила будет важна в боях роботов, потому что если какой-то робот от игрока 1 будет рядом с роботом от игрока 2, я хочу, чтобы вы знали, сражайтесь, так что сила будет довольно хорошей прямо здесь, если они будут рядом с друг друга мощность будет уменьшаться, пока робот не будет уничтожен. Но давайте сосредоточимся на приведенном выше коде, чтобы сделать его лучше.

Любые советы, как сделать это короче и аккуратнее, ближе к продвинутому или просто лучшему решению, будут определенно к делу.

Хорошего дня!

1 ответ
1

Аннотации типов

Использование аннотаций типов сделает вашу программу более читаемой и простой в отладке. Например:

def __init__(self, name, place, start = (0,0), power = 9):
    # assignments

становится

def __init__(self, name: str, place : List[int], start: Tuple[int, int] = (0,0), power: int = 9):
    # assignments

Я импортировал List, Tuple от typing модуль из стандартной библиотеки:

from typing import List, Tuple

Вот дополнительная информация об использовании аннотаций типов.


Получатель и сеттер

Использование геттеров и сеттеров довольно непифонично. Вместо этого вы можете изменить поведение получения и настройки с помощью @property декоратор вроде этого:

def __init__(self, name: str, place : List[int], start: Tuple[int, int] = (0,0), power: int = 9):
    self._name = name

    # further assignments

@property
def name(self):
    return self._name

@name.setter
def name(self, value):
    if isinstance(value, str):
        self._name = value
    else:
        raise TypeError("must be a string")

Это позволит вам использовать свойства без явного вызова методов получения и установки:

my_robot.name="foo"
print(my_robot.name)

Этот вопрос о StackOverflow содержит более подробные пояснения.


Логика

  1. Вам также следует взглянуть на свои сеттеры для place а также start. Вы проверяете только тип переданного аргумента value, но не проверяйте, находятся ли элементы в list или же tuple относятся к типу int.
  2. Вы можете рассмотреть возможность использования настраиваемого класса Position или аналогичный для обработки позиционной логики робота. Таким образом, вы можете получить доступ к различным измерениям по их именам, а не по индексам
    place (self.place[0] или же self.place[1]). Вы также сможете добавить в него дополнительную логику (например, отсечение и т. Д.).
  3. power а также check_power(): В зависимости от предполагаемой функциональности вы можете ограничить количество шагов, которые может сделать робот, до power что он ушел. В настоящее время робот может делать любое количество шагов, пока он power > 0 оставил.
  4. Вы должны проверить работоспособность left(value) а также up(value) для больших значений, особенно для значений, которые > 2 * board_dimension. Я подозреваю, что результаты могут быть непреднамеренными.

  • В целом согласен. Я бы пошел дальше ваших «непифонических функций доступа» — если есть какая-то нетривиальная логика для получения или установки, @property требуется, но здесь его нет. Просто сделайте «общедоступную» переменную.

    — Райндериен


  • Подлинный вопрос: как вы затем проверяете / гарантируете, что присвоены только значения определенного типа общественный атрибуты, если вообще?

    — рискованный пингвин


  • 2

    Короткий ответ — нет. Проверка типа — как правило — не выполняется вообще, поскольку Python использует утиную типизацию. Недавняя поддержка статического анализа типов полезна, но не применяется во время выполнения. Если вы действительно хотите применить проверку к значению перед установкой, вы должны сделать это, как показано, с помощью @properties или — если вы можете сделать класс неизменяемым, что имеет много преимуществ — тогда во время __init__.

    — Райндериен

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *