示例#1
0
class Snake:
    def __init__(self, x, y):
        self.head = Cell(int(x), int(y))

        self.vel = Point(1, 0)

        self.last_tail = self.head.with_offset(-2, 0).get_key()
        self.body = {self.head.with_offset(-1, 0).get_key(): {"x": 1, "y": 0},
                     self.last_tail: {"x": 1, "y": 0}}

    def move(self):
        self.move_head()
        if not Map.food_eaten():
            self.move_tail()

    def move_head(self):
        self.add_body_piece()
        self.move_head_along_axis()
        self.head = self.check_borders(self.head)

    def move_tail(self):
        new_tail = self.get_new_tail()
        new_tail = self.check_borders(new_tail)
        self.set_tail(new_tail)

    def change_dir(self, direction) -> bool:
        valid_change = self.dir_change_is_valid(direction)
        if valid_change:
            self.set_dir(direction)
        return valid_change

    def dir_change_is_valid(self, direction: int) -> bool:
        current_dir = self.current_dir()
        return is_vertical(current_dir) == is_horizontal(direction)

    def add_body_piece(self):
        key = self.head.get_key()
        self.body[key] = {"x": self.vel.x, "y": self.vel.y}

    def move_head_along_axis(self):
        self.head.add_point(self.vel)

    def is_head(self, coord: Cell) -> bool:
        return coord == self.head

    def is_body(self, coord: Cell) -> bool:
        return coord.get_key() in self.body.keys()

    def bite_itself(self) -> bool:
        return self.is_body(self.head)

    def set_tail(self, new_tail: Cell):
        del self.body[self.last_tail]
        self.last_tail = new_tail.get_key()

    def set_dir(self, direction):
        if direction == RIGHT:
            self.set_dir_to_right()
        elif direction == LEFT:
            self.set_dir_to_left()
        elif direction == DOWN:
            self.set_dir_to_down()
        elif direction == UP:
            self.set_dir_to_up()

    def get_new_tail(self) -> Cell:
        new_tail = Cell.str2point(self.last_tail)

        new_tail.add(self.body[self.last_tail]['x'], self.body[self.last_tail]['y'])

        return new_tail

    def set_dir_to_down(self):
        self.vel.x = 0
        self.vel.y = 1

    def set_dir_to_up(self):
        self.vel.x = 0
        self.vel.y = -1

    def set_dir_to_right(self):
        self.vel.x = 1
        self.vel.y = 0

    def set_dir_to_left(self):
        self.vel.x = -1
        self.vel.y = 0

    def current_dir(self) -> int:
        return self.get_dir(self.vel)

    @classmethod
    def get_dir(cls, vel: Point) -> int:
        ans = 0
        if vel.x > 0:
            ans = RIGHT
        elif vel.x < 0:
            ans = LEFT
        elif vel.y > 0:
            ans = DOWN
        elif vel.y < 0:
            ans = UP
        return ans

    @classmethod
    def key2dir(cls, key: Key) -> int:
        ans = 0

        if key == D or key == RIGHT_ARROW:
            ans = RIGHT
        elif key == A or key == LEFT_ARROW:
            ans = LEFT
        elif key == W or key == UP_ARROW:
            ans = UP
        elif key == S or key == DOWN_ARROW:
            ans = DOWN

        return ans

    @classmethod
    def get_key(cls, coord: Cell) -> str:
        return str(coord.x) + "X" + str(coord.y)

    @classmethod
    def get_coord(cls, key) -> tuple:
        _key = key.split("X")
        x = int(_key[0])
        y = int(_key[1])
        return x, y

    @classmethod
    def check_borders(cls, point: Cell) -> Cell:
        new_point = point.copy()
        if point.x > Map.get_width() - 1:
            new_point.x = 0
        elif point.x < 0:
            new_point.x = Map.get_width() - 1

        if point.y > Map.get_height() - 1:
            new_point.y = 0
        elif point.y < 0:
            new_point.y = Map.get_height() - 1

        return new_point