Scorpion_MB
@Scorpion_MB
Изучаю Питон

Почему не работает цикл игры?

Запускаю окошко с помощью tkinter и пытаюсь из цикла запустить код из другого класса, но цикл прерывается. Что я делаю не так? Приведу часть кода.
Код игры

class Visual:
    """
    Класс визуализации
    """
    def __init__(self):
        self.tk = Tk()
        self.app_running = True
        self.size_canvas_x = 250
        self.size_canvas_y = 250
        self.s_x = self.s_y = 10  # размер игрового поля
        self.step_x = self.size_canvas_x // self.s_x  # шаг по горизонтали
        self.step_y = self.size_canvas_y // self.s_y  # шаг по горизонтали
        self.size_canvas_x = self.s_x * self.step_x
        self.size_canvas_y = self.s_y * self.step_y
        self.canvas = Canvas(self.tk, width=self.size_canvas_x, height=self.size_canvas_y, bd=-2, bg='white')

    def on_closing(self):
        if messagebox.askokcancel('Выход из игры', 'Хотите выйти из игры?'):
            self.app_running = False
            self.tk.destroy()

    def create_field(self):
        self.tk.protocol('WM_DELETE_WINDOW', self.on_closing)
        self.tk.title('Игра Морской бой')
        self.tk.resizable(0, 0)
        self.tk.wm_attributes('-topmost', 1)
        self.canvas.create_rectangle(0, 0, self.size_canvas_x, self.size_canvas_y, fill='lightgray')
        self.canvas.pack()
        self.draw_table()
        self.tk.update()
        # game.game_shot()

        while self.app_running:
            self.tk.update_idletasks()
            self.tk.update()
            time.sleep(0.005)

    def draw_table(self):
        for i in range(self.s_y + 1):
            self.canvas.create_line(0, i * self.step_y, self.size_canvas_x, i * self.step_y)
        for i in range(self.s_x + 1):
            self.canvas.create_line(i * self.step_x, 0, i * self.step_x, self.size_canvas_y)

class Game:
    """
    Класс игры
    """
    def __init__(self, player1, player2):
        self.current_player = player1
        self.next_player = player2
        self.field_radar = Board()
        # self.radar = Visual()
        self.user_field = Visual()
        self.field_user = Board()
        self.field_comp = Board()
        self.field_weight = Board()
        self.message = 'test'

    def start_game(self):
        self.clear_screen()
        print('\n\n\n\t\033[1;033m"Морской бой"'.expandtabs(tabsize=30))
        print('\tРасстановка кораблей игроков автоматическая.\n\n\n'.expandtabs(tabsize=15))
        start = input('Начать игру (y), выйти (n): \033[0m')
        if start == 'y':
            self.clear_screen()
            self.install_ship_by_player()
            self.user_field.create_field()

            self.clear_screen()
            print('\n\nВы вышли из игры.\033[0m')
        else:
            print('\033[1;033m\n\nПовторите выбор режима.\033[0m')
            time.sleep(2)
            self.start_game()

    @staticmethod
    def clear_screen():
        os.system('cls' if os.name == 'nt' else 'clear')

    def install_ship_by_player(self):

        # установка кораблей первого игрока
        for len_ship in Ship.ships_rules:
            while True:
                ship = Ship(len_ship)
                ship.install_ship(self.field_user, self.current_player.occupied, ship, self.current_player)
                if ship.setup:
                    ship.occupied_board(self.field_user, self.current_player.occupied)
                    break

        # установка кораблей второго игрока
        for len_ship in Ship.ships_rules:
            while True:
                ship = Ship(len_ship)
                ship.install_ship(self.field_comp, self.next_player.occupied, ship, self.next_player)
                if ship.setup:
                    ship.occupied_board(self.field_comp, self.next_player.occupied)
                    break

        # печать игровых полей
        self.field_radar.print_board()

    # метод для производства выстрела и обработки результатов
    def game_shot(self):

        shot = Shot()

        if not self.current_player.auto:
            if len(self.next_player.list_ships) > 0:
                print('\033[1;36mХод:', self.current_player)
                shot.shot_by_ships(self.next_player, self.field_comp)
                if game.message == 'miss':
                    print('\033[1;33mПромах!', 'Переход хода...')
                    game.field_radar.print_board()
                    self.switch_players()
                    return self.game_shot()
                if game.message == 'get':
                    print('\033[1;33mПопадание!', 'Еще выстрел...')
                if game.message == 'kill':
                    print('\033[1;33mКорабль уничтожен!', 'Ура!')
                game.field_radar.print_board()
            print('\033[1;31mВсе корабли потоплены. Вы выиграли!\033[0m')

        elif self.current_player.auto:
            if len(self.next_player.list_ships) > 0:
                print('\033[1;36mХод:', str(self.current_player) + ': ', end='')
                shot.shot_by_ships_auto(self.next_player, self.field_user)
                if game.message == 'miss':
                    print('\033[1;33mПромах!', 'Переход хода...')
                    game.field_radar.print_board()
                    self.switch_players()
                    return self.game_shot()
                if game.message == 'get':
                    print('\033[1;33mПопадание!', 'Еще выстрел...')
                if game.message == 'kill':
                    print('\033[1;33mВаш корабль уничтожен!', 'Соболезную...')
                game.field_radar.print_board()
            print('\033[1;31mВсе корабли потоплены. Выиграл компьютер!\033[0m')

    # метод для смены хода игроков
    def switch_players(self):
        self.current_player, self.next_player = self.next_player, self.current_player


if __name__ == "__main__":
    players = [Player(name='User', auto=False), Player(name='Computer', auto=True)]
    # print(players[0], players[1])

    game = Game(players[0], players[1])
    game.start_game()



Если убираю из цикла game.game_shot(), то выход из окна программы работает. Иначе нет.
  • Вопрос задан
  • 73 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы