15. Морской бой (в коде есть строки из следующих тем: "рекурсия").

(открыть в новой вкладке)

Условие:

Написать игру морской бой, используя ООП.
⇒ Звуки для игры "Морской бой".

Код:

"""ИГРА МОРСКОЙ БОЙ"""


import random, bext, playsound


class Sea_battle:
    """БУКВЕННЫЕ И ЦИФРОВЫЕ КООРДИНАТЫ"""
    letters = "АБВГДЕЖЗИК"                                                                                          
    letters_go = "  АБВГДЕЖЗИК"
    numbers = ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
    """КОРТЕЖ С КОРАБЛЯМИ"""
    ships = (4, 3, 3, 2, 2, 2, 1, 1, 1, 1)
    """ЗНАЧКИ ДЛЯ МОРЯ"""
    sea_icon = "🟦"
    sea_icon_block = "🟪"
    ship_icon = "⚓"    
    hit_icon = "❌"
    miss_icon = "⚪"    
    
    """В КОНСТРУКТОРЕ СОЗДАДИМ АТРИБУТ ОБЪЕКТА - ЭТО ИГРОВОЕ ПОЛЕ, ОДНО ДЛЯ РАССТАНОВКИ КОРАБЛЕЙ, ДРУГОЕ ДЛЯ ХОДОВ"""
    def __init__(self) -> None:                                                                                     
        self._field = self.__initialize()       
        self._field_go = self.__initialize()
        
    """МЕТОД ДЛЯ ОПРЕДЕЛЕНИЯ ПЕРЕМЕННЫХ ДЛЯ КОНСТРУКТОРА __init__ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __initialize(self):                                                                                         
        self.__field = {}
        n = 1
        for a in self.__class__.numbers:
            for b in self.__class__.letters:
                self.__field[str(a) + b] = [n, self.__class__.sea_icon]
                n += 1
        return self.__field

    """МЕТОД, КОТОРЫЙ ВОЗВРАЩАЕТ ИГРОВОЕ ПОЛЕ В ТЕКУЩЕМ СОСТОЯНИИ + ПОЛЕ С ХОДАМИ (ВИЗУАЛИЗАЦИЯ ИГРОВОЙ ОБЛАСТИ)"""
    def show_field(self):                                                                                           
        for i in (self.__class__.letters + self.__class__.letters_go):
            print((i + " "), end="")
        print()            
        for a in self._field.values():           
            if a[0] % 10 != 0 and a[0] < 10:
                print(a[1], end="")
            elif a[0] == 10:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and a[0] < 10:
                print(a[1], end="")
            elif a[0] == 10:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 10 < a[0] < 20:
                print(a[1], end="")
            elif a[0] == 20:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 10 < a[0] < 20:
                print(a[1], end="")
            elif a[0] == 20:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 20 < a[0] < 30:
                print(a[1], end="")
            elif a[0] == 30:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 20 < a[0] < 30:
                print(a[1], end="")
            elif a[0] == 30:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 30 < a[0] < 40:
                print(a[1], end="")
            elif a[0] == 40:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 30 < a[0] < 40:
                print(a[1], end="")
            elif a[0] == 40:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 40 < a[0] < 50:
                print(a[1], end="")
            elif a[0] == 50:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 40 < a[0] < 50:
                print(a[1], end="")
            elif a[0] == 50:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 50 < a[0] < 60:
                print(a[1], end="")
            elif a[0] == 60:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 50 < a[0] < 60:
                print(a[1], end="")
            elif a[0] == 60:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 60 < a[0] < 70:
                print(a[1], end="")
            elif a[0] == 70:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 60 < a[0] < 70:
                print(a[1], end="")
            elif a[0] == 70:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 70 < a[0] < 80:
                print(a[1], end="")
            elif a[0] == 80:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 70 < a[0] < 80:
                print(a[1], end="")
            elif a[0] == 80:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 80 < a[0] < 90:
                print(a[1], end="")
            elif a[0] == 90:
                print(a[1], int(a[0] / 10), end="")
        print("  ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 80 < a[0] < 90:
                print(a[1], end="")
            elif a[0] == 90:
                print(a[1], int(a[0] / 10))
        for a in self._field.values():           
            if a[0] % 10 != 0 and 90 < a[0] < 100:
                print(a[1], end="")
            elif a[0] == 100:
                print(a[1], int(a[0] / 10), end="")
        print(" ", end="")
        for a in self._field_go.values():           
            if a[0] % 10 != 0 and 90 < a[0] < 100:
                print(a[1], end="")
            elif a[0] == 100:
                print(a[1], int(a[0] / 10))
            
    """МЕТОД, КОТОРЫЙ ПРОВОДИТ ДОПОЛНИТЕЛЬНУЮ ПРОВЕРКУ ПРИ УСТАНОВКЕ ТРЁХ-ПАЛУБНЫХ КОРАБЛЕЙ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __arrange_ships_three(self, x, move):
        if move == "right":                                                                                                      # проверяет, есть ли три подходящих клетки для коробля по-горизонтали            
            return True if [(x), self.__class__.sea_icon] in self._field.values() and \
                [(x + 1), self.__class__.sea_icon] in self._field.values() and \
                [(x + 2), self.__class__.sea_icon] in self._field.values() else False                                                                   
        elif move == "down":                                                                                                     # проверяет, есть ли три подходящих клетки для коробля по-вертикали
            return True if [(x), self.__class__.sea_icon] in self._field.values() and \
                [(x + 10), self.__class__.sea_icon] in self._field.values() and \
                [(x + 20), self.__class__.sea_icon] in self._field.values() else False                                                       
                    
    """МЕТОД, КОТОРЫЙ ПРОВОДИТ ДОПОЛНИТЕЛЬНУЮ ПРОВЕРКУ ПРИ УСТАНОВКЕ ДВУХ-ПАЛУБНЫХ КОРАБЛЕЙ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __arrange_ships_two(self, x, move):
        if move == "right":                                                                                                      # проверяет, есть ли две подходящие клетки для коробля по-горизонтали
            return True if [(x), self.__class__.sea_icon] in self._field.values() and \
                [(x + 1), self.__class__.sea_icon] in self._field.values() else False                                                                        
        elif move == "down":                                                                                                     # проверяет, есть ли две подходящие клетки для коробля по-вертикали
            return True if [(x), self.__class__.sea_icon] in self._field.values() and \
                [(x + 10), self.__class__.sea_icon] in self._field.values() else False                                                       
        
    """МЕТОД, КОТОРЫЙ ПРОВОДИТ ДОПОЛНИТЕЛЬНУЮ ПРОВЕРКУ ПРИ УСТАНОВКЕ ОДНО-ПАЛУБНЫХ КОРАБЛЕЙ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __arrange_ships_one(self, x):                                                                                                              
            return True if [(x), self.__class__.sea_icon] in self._field.values() else False                                     # проверяет, есть ли две подходящие клетки для коробля по-горизонтали                                                                                                         
            
    """МЕТОД, КОТОРЫЙ РАССТАВЛЯЕТ КОРАБЛИ НА ИГРОВОМ ПОЛЕ"""
    def arrange_ships(self):
        for i in self.__class__.ships:                                                                                           # обходим в цикле кортеж с кораблями
            if i == 4:                                                                                                           # условие для четырех-палубного
                while True:                                                                                                      # цикл повторяется пока не будут найдены подходящие координаты для установки корабля                
                    x = random.randint(1, 100)                                                                                   # рандомные координаты, которые генерируются в цикле пока не будет найдена подходящая точка
                    move = random.choice(["right", "down"])                                                                      # направление расстановки корабля из точка (направо или вниз)
                    if move == "right" and 0 < int(str(x)[-1]) <= 7:                                                             # первое условие, при котором корабль может быть установлен горизонтально
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                       
                            if b[0] == x + 1:   
                                self._field[a] = [x + 1, self.__class__.ship_icon]                                
                            if b[0] == x + 2:   
                                self._field[a] = [x + 2, self.__class__.ship_icon]                                
                            if b[0] == x + 3:   
                                self._field[a] = [x + 3, self.__class__.ship_icon]                                       
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x - 9) or b[0] == (x - 8) or b[0] == (x - 7) or \
                                b[0] == (x + 13) or b[0] == (x + 12) or \
                                b[0] == (x + 11) or b[0] == (x + 10) else self._field[a]                                         # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 6) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 4) and str(b[0])[-1] != "1" \
                                or b[0] == (x + 14) and str(b[0])[-1] != "1" else self._field[a]                                 # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 9) \
                                and str(b[0])[-1] != "0" or b[0] == (x - 1) and str(b[0])[-1] != "0" \
                                or b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                 # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break
                    elif move == "down" and x <= 70:                                                                             # второе условие, при котором корабль может быть установлен вертикально
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                 
                            if b[0] == x + 10:   
                                self._field[a] = [x + 10, self.__class__.ship_icon]                                
                            if b[0] == x + 20:   
                                self._field[a] = [x + 20, self.__class__.ship_icon]                                
                            if b[0] == x + 30:   
                                self._field[a] = [x + 30, self.__class__.ship_icon]                                                            
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x + 40) else self._field[a]                                                             # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 9) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 1) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 11) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 21) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 31) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 41) and str(b[0])[-1] != "1" else self._field[a]                                    # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 39) \
                                and str(b[0])[-1] != "0" or b[0] == (x + 29) and str(b[0])[-1] != "0" or \
                                b[0] == (x + 19) and str(b[0])[-1] != "0" or \
                                b[0] == (x + 9) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 1) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                    # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break
            if i == 3:                                                                                                           # условие для трёх-палубного
                while True:                                                                                                      # цикл повторяется пока не будут найдены подходящие координаты для установки корабля                
                    x = random.randint(1, 100)                                                                                   # рандомные координаты, которые генерируются в цикле пока не будет найдена подходящая точка                    
                    move = random.choice(["right", "down"])                                                                      # направление расстановки корабля из точка (направо или вниз)                    
                    if move == "right" and 0 < int(str(x)[-1]) <= 8 and self.__arrange_ships_three(x, move):                     # первое условие, при котором корабль может быть установлен (горизонтально)
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                 
                            if b[0] == x + 1:   
                                self._field[a] = [x + 1, self.__class__.ship_icon]                                
                            if b[0] == x + 2:   
                                self._field[a] = [x + 2, self.__class__.ship_icon]  
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x - 9) or b[0] == (x - 8) or \
                                b[0] == (x + 12) or \
                                b[0] == (x + 11) or b[0] == (x + 10) else self._field[a]                                         # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)       
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 7) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 3) and str(b[0])[-1] != "1" \
                                or b[0] == (x + 13) and str(b[0])[-1] != "1" else self._field[a]                                 # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)         
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 9) \
                                and str(b[0])[-1] != "0" or b[0] == (x - 1) and str(b[0])[-1] != "0" \
                                or b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                 # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break
                    elif move == "down" and x <= 80 and self.__arrange_ships_three(x, move):                                     # второе условие, при котором корабль может быть установлен (вертикально)
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                 
                            if b[0] == x + 10:                       
                                self._field[a] = [x + 10, self.__class__.ship_icon]
                            if b[0] == x + 20:                       
                                self._field[a] = [x + 20, self.__class__.ship_icon]
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x + 30) else self._field[a]                                                             # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 9) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 1) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 11) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 21) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 31) and str(b[0])[-1] != "1" else self._field[a]                                    # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 29) \
                                and str(b[0])[-1] != "0" or b[0] == (x + 19) and str(b[0])[-1] != "0" or \
                                b[0] == (x + 9) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 1) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                    # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break                            
            if i == 2:                                                                                                           # условие для двух-палубного
                while True:                                                                                                      # цикл повторяется пока не будут найдены подходящие координаты для установки корабля                
                    x = random.randint(1, 100)                                                                                   # рандомные координаты, которые генерируются в цикле пока не будет найдена подходящая точка
                    move = random.choice(["right", "down"])                                                                      # направление расстановки корабля из точка (направо или вниз)                    
                    if move == "right" and 0 < int(str(x)[-1]) <= 9 and self.__arrange_ships_two(x, move):                       # первое условие, при котором корабль может быть установлен (горизонтально)
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                 
                            if b[0] == x + 1:   
                                self._field[a] = [x + 1, self.__class__.ship_icon]                                                              
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x - 9) or \
                                b[0] == (x + 11) or \
                                b[0] == (x + 10) else self._field[a]                                                             # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)       
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 8) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 2) and str(b[0])[-1] != "1" \
                                or b[0] == (x + 12) and str(b[0])[-1] != "1" else self._field[a]                                 # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)         
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 9) \
                                and str(b[0])[-1] != "0" or b[0] == (x - 1) and str(b[0])[-1] != "0" \
                                or b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                 # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break
                    elif move == "down" and x <= 90 and self.__arrange_ships_two(x, move):                                       # второе условие, при котором корабль может быть установлен (вертикально)
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                 
                            if b[0] == x + 10:                       
                                self._field[a] = [x + 10, self.__class__.ship_icon]                    
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x + 20) else self._field[a]                                                             # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 9) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 1) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 11) and str(b[0])[-1] != "1" or \
                                b[0] == (x + 21) and str(b[0])[-1] != "1" else self._field[a]                                    # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 19) \
                                and str(b[0])[-1] != "0" or b[0] == (x + 9) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 1) and str(b[0])[-1] != "0" or \
                                b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                    # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break
            if i == 1:                                                                                                           # условие для одно-палубного
                while True:                                                                                                      # цикл повторяется пока не будут найдены подходящие координаты для установки корабля                
                    x = random.randint(1, 100)                                                                                   # рандомные координаты, которые генерируются в цикле пока не будет найдена подходящая точка
                    if self.__arrange_ships_one(x):                                                                              # условие, при котором корабль может быть установлен
                        for a, b in self._field.items():                                                                         # в цикле модернизируем игровое поле, клетки с кораблями и морем вокруг кораблей меняют свои значения
                            if b[0] == x:                                                        
                                self._field[a] = [x, self.__class__.ship_icon]                                                              
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 10) or \
                                b[0] == (x + 10) else self._field[a]                                                             # условие для верха и низа от корабля (помечаем морские клетки, рядом с кораблём)       
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x - 9) \
                                and str(b[0])[-1] != "1" or b[0] == (x + 1) and str(b[0])[-1] != "1" \
                                or b[0] == (x + 11) and str(b[0])[-1] != "1" else self._field[a]                                 # условие для правой стороны от корабля (помечаем морские клетки, рядом с кораблём)         
                            self._field[a] = [b[0], self.__class__.sea_icon_block] if b[0] == (x + 9) \
                                and str(b[0])[-1] != "0" or b[0] == (x - 1) and str(b[0])[-1] != "0" \
                                or b[0] == (x - 11) and str(b[0])[-1] != "0" else self._field[a]                                 # условие для левой стороны от корабля (помечаем морские клетки, рядом с кораблём)
                        break    

    """МЕТОД-addon, КОТОРЫЙ РЕАЛИЗУЕТ SETTER ДЛЯ ИГРОВОГО ПОЛЯ КОТОРОЕ ПРЕДНАЗНАЧЕНО ДЛЯ ХОДОВ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __set_field_go_addon(self, value):                                                                                       # возвращает уже готовый правильный вид игрового поля в основной setter в виде словаря, в котором ключи - это координаты, а значения - это списки с номерами клетки и иконкой для неё
        coordinates = value[0]    
        icon = value[1]
        for a, b in self._field_go.items():
            if coordinates == a:
                self._field_go[a] = [b[0], icon]
        return self._field_go

    """МЕТОД, КОТОРЫЙ РЕАЛИЗУЕТ GETTER И SETTER ДЛЯ ЧАСТИ ИГРОВОГО ПОЛЯ КОТОРОЕ ПРЕДНАЗНАЧЕНО ДЛЯ ХОДОВ"""
    def get_field_go(self):                                                                                                      # getter, который возвращает сразу часть поля для ходов - это словарь, где ключи - это значения координат, а значения ключей - это список с номером клетки и её иконкой
        return self._field_go        
    def set_field_go(self, value):                                                                                               # setter меняет часть поля, предназначенную для ходов. Переменная value должна быть кортежом или словарём.
        self._field_go = self.__set_field_go_addon(value)                                                                        # требуется дополнительная обработка инкапсулированным методом "__set_field_go_addon"
    field_go = property(get_field_go, set_field_go) 

    """МЕТОД-addon, КОТОРЫЙ РЕАЛИЗУЕТ SETTER ДЛЯ ИГРОВОГО ПОЛЯ КОТОРОЕ С КОРАБЛЯМИ (ИНКАПСУЛИРОВАННЫЙ)"""
    def __set_field_addon(self, value):                                                                                          # возвращает уже готовый правильный вид игрового поля в основной setter в виде словаря, в котором ключи - это координаты, а значения - это списки с номерами клетки и иконкой для неё
        coordinates = value[0]    
        icon = value[1]
        for a, b in self._field.items():
            if coordinates == a:
                self._field[a] = [b[0], icon]
        return self._field

    """МЕТОД, КОТОРЫЙ РЕАЛИЗУЕТ GETTER И SETTER ДЛЯ ЧАСТИ ИГРОВОГО ПОЛЯ КОТОРОЕ СОДЕРЖИТ КОРАБЛИ"""
    def get_field(self):                                                                                                         # getter, который возвращает сразу часть поля для кораблей - это словарь, где ключи - это значения координат, а значения ключей - это список с номером клетки и её иконкой
        return self._field        
    def set_field(self, value):                                                                                                  # setter меняет часть поля, предназначенную для кораблей. Переменная value должна быть кортежом или списком.
        self._field = self.__set_field_addon(value)                                                                              # требуется дополнительная обработка инкапсулированным методом "__set_field_addon"
    field_ship = property(get_field, set_field) 

"""ФУНКЦИЯ, КОТОРАЯ ОПРЕДЕЛЯЕТ СЛЕДУЮЩИЙ ВЫСТРЕЛ ДЛЯ КОМПЬЮТЕРА, ЕСЛИ КОРАБЛЬ РАНЕН И ИМЕЕТ ВЕРТИКАЛЬНУЮ ОРИЕНТАЦИЮ."""
def vertical_shot(temp_dict, shot_cpu):
    ### -1
    if (str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:                                                                                          
        return (str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1])                                                                                                                                                    # 1 строка наверх
    ### +1
    elif (str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:                                                                                          
        return (str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1])                                                                                                                                                    # 1 строка вниз
    ### -2
    elif (str(int(shot_cpu[0:-1]) - 2) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 2) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 2) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:
        return (str(int(shot_cpu[0:-1]) - 2) + shot_cpu[-1])                                                                                                                                                    # 2 строки наверх
    ### +2
    elif (str(int(shot_cpu[0:-1]) + 2) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 2) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 2) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:                                                                                          
        return (str(int(shot_cpu[0:-1]) + 2) + shot_cpu[-1])                                                                                                                                                    # 2 строки вниз
    ### -3
    elif (str(int(shot_cpu[0:-1]) - 3) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 3) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 3) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 2) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) - 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:
        return (str(int(shot_cpu[0:-1]) - 3) + shot_cpu[-1])                                                                                                                                                    # 3 строки наверх
    ### +3
    elif (str(int(shot_cpu[0:-1]) + 3) + shot_cpu[-1]) in temp_dict \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 3) + shot_cpu[-1])][-1] != Sea_battle.hit_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 3) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 2) + shot_cpu[-1])][-1] != Sea_battle.miss_icon \
        and temp_dict[(str(int(shot_cpu[0:-1]) + 1) + shot_cpu[-1])][-1] != Sea_battle.miss_icon:
        return (str(int(shot_cpu[0:-1]) + 3) + shot_cpu[-1])                                                                                                                                                    # 3 строки вниз
    else:
        return "ошибка"

"""ФУНКЦИЯ, КОТОРАЯ ОПРЕДЕЛЯЕТ СЛЕДУЮЩИЙ ВЫСТРЕЛ ДЛЯ КОМПЬЮТЕРА, ЕСЛИ КОРАБЛЬ РАНЕН И ИМЕЕТ ГОРИЗОНТАЛЬНУ ОРИЕНТАЦИЮ."""
def horizontal_shot(temp_dict, shot_cpu):
#    ### -1"К" 
    if shot_cpu[-1] == "К" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.miss_icon:        
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))                                                                     # -1 символ, если буква в координате первого выстрела "К"
#    ### -1 не "К"  
    elif shot_cpu[-1] != "К" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1))                                                                     # -1 символ, если буква в координате первого выстрела не "К"        
#    ### +1"И"
    elif shot_cpu[-1] == "И" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))                                                                     # +1 символ, если буква в координате первого выстрела "И"    
    ### +1 не "И"
    elif shot_cpu[-1] != "И" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))                                                                     # +1 символ, если буква в координате первого выстрела не "И"
#    ### -2 "К"
    elif shot_cpu[-1] == "К" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.miss_icon:        
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))                                                                     # -2 символа, если буква в координате первого выстрела "К"
#    ### -2 не "К"
    elif shot_cpu[-1] != "К" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))                                                                     # -2 символа, если буква в координате первого выстрела не "К"
#    ### +2 "З"
    elif shot_cpu[-1] == "З" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))                                                                     # +2 символа, если буква в координате первого выстрела "З"
#    ### +2 не "З"
    elif shot_cpu[-1] != "З" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))                                                                     # +2 символа, если буква в координате первого выстрела не "З"
#    ### -3 "К"
    elif shot_cpu[-1] == "К" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 4))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 4))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.miss_icon:        
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 4))                                                                     # -3 символа, если буква в координате первого выстрела "К"
#    ### -3 не "К"
    elif shot_cpu[-1] != "К" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 2))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) - 3))                                                                     # -3 символа, если буква в координате первого выстрела не "К"
#    ### +3 "Ж"
    elif shot_cpu[-1] == "Ж" and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 4))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 4))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 4))                                                                     # +3 символа, если буква в координате первого выстрела "Ж"
#    ### +3 не "Ж"
    elif shot_cpu[-1] != "Ж" and (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3)) in temp_dict \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))][-1] != Sea_battle.hit_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 2))][-1] != Sea_battle.miss_icon \
        and temp_dict[(shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 1))][-1] != Sea_battle.miss_icon:                                                                                          
        return (shot_cpu[0:-1] + chr(ord(shot_cpu[-1]) + 3))                                                                     # +3 символа, если буква в координате первого выстрела не "Ж"    
    else:
        return "ошибка"

"""ФУНКЦИЯ, КОТОРАЯ ПРОСТО ОПРЕДЕЛЯЕТ ВСЕХ СОСЕДЕЙ ТОЧКИ ПО ВЕРТИКАЛИ И ГОРИЗОНТАЛИ.
ВОЗВРАЩАЕТ СПИСОК КООРДИНАТ."""
def vertical_and_horizontal_neighborhood_check_3(point):                                                                                               
    if point == "1А":
        temp = ["1Б", "2А"]                             
    elif len(point) == 2 and point[0] == "1" and point != "1И" and point != "1К":
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
    elif point == "1И":
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
    elif point == "1К":
        temp = ["1И", "2К"]
    elif point[-1] == "К" and point != "10К":
        up = str(int(point[0]) - 1) + point[1]
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 2)
        temp = [up, down, left]
    elif point == "10К":
        temp = ["10И", "9К"]
    elif point == "10И":
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 2)
        left = point[0:-1] + chr(ord(point[-1]) - 1)                
        temp = [up, right, left]
    elif len(point) == 3 and point != "10А":
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 1)
        left = point[0:-1] + chr(ord(point[-1]) - 1)  
        temp = [up, right, left]
    elif point == "10А":
        temp = ["9А", "10Б"]
    elif point[-1] == "А":
        up = str(int(point[0]) - 1) + point[1]
        left = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [up, left, down]
    elif point[-1] == "И":
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
    else:
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
    return temp

"""ФУНКЦИЯ, КОТОРАЯ ПРОВЕРЯЕТ ЕСТЬ ЛИ СОСЕДСТВО ПО ВЕРТИКАЛИ И ГОРИЗОНТАЛИ '⚓' с '❌', ТОЛЬКО ДЛЯ ТЕХ КЛЕТОК, КОТОРЫЕ САМИ с '❌'."""
def vertical_and_horizontal_neighborhood_check_2(point, field):                                                                 
    if point == "1А" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["1Б", "2А"]                      
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif len(point) == 2 and point[0] == "1" and point != "1И" and point != "1К" and field[point][-1] == Sea_battle.hit_icon:
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point == "1И" and field[point][-1] == Sea_battle.hit_icon:
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point == "1К" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["1И", "2К"]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point[-1] == "К" and point != "10К" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 2)
        temp = [up, down, left]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point == "10К" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["10И", "9К"]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point == "10И" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 2)
        left = point[0:-1] + chr(ord(point[-1]) - 1)                
        temp = [up, right, left]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif len(point) == 3 and point != "10А" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 1)
        left = point[0:-1] + chr(ord(point[-1]) - 1)  
        temp = [up, right, left]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point == "10А" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["9А", "10Б"]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point[-1] == "А" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        left = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [up, left, down]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif point[-1] == "И" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    elif field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
        result = set()
        for a in temp:
            if field[a][1] == Sea_battle.ship_icon:
                result.add("ранен")
            else:
                result.add("не ранен")
    else:
        result = set()
    return result

"""ФУНКЦИЯ, КОТОРАЯ ГЕНЕРИРУЕТ ВЫСТРЕЛ ДЛЯ CPU."""
def function_input_coordinates_for_cpu(temp_dict):
    go = []
    for a, b in temp_dict.items():
        if b[1] != Sea_battle.hit_icon and b[1] != Sea_battle.miss_icon:
            go.append(a)
    return random.choice(go)

"""ФУНКЦИЯ, КОТОРАЯ ИЗМЕНЯЕТ СОСЕДЕЙ ВОКРУГ С КЛЕТКОЙ "🟪"."""
def changing_neighbors_around(point, field):                                                                                                         
        if point == "1А":
            temp = ["1Б", "2Б", "2А"]                
        elif len(point) == 2 and point[0] == "1" and point != "1И" and point != "1К" and field[point][-1] == Sea_battle.hit_icon:
            left = point[0] + chr(ord(point[1]) - 1)
            right = point[0] + chr(ord(point[1]) + 1)
            down = str(int(point[0]) + 1) + point[1]
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) - 1)
            down_right = str(int(point[0]) + 1) + chr(ord(point[1]) + 1)
            temp = [left, right, down, down_left, down_right]
        elif point == "1И" and field[point][-1] == Sea_battle.hit_icon:
            left = point[0] + chr(ord(point[1]) - 1)
            right = point[0] + chr(ord(point[1]) + 2)
            down = str(int(point[0]) + 1) + point[1]
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) - 1)
            down_right = str(int(point[0]) + 1) + chr(ord(point[1]) + 2)
            temp = [left, right, down, down_left, down_right]             
        elif point == "1К" and field[point][-1] == Sea_battle.hit_icon:
            temp = ["1И", "2И", "2К"]
        elif point[-1] == "К" and point != "10К" and field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0]) - 1) + point[1]
            down = str(int(point[0]) + 1) + point[1]
            left = point[0] + chr(ord(point[1]) - 2)
            up_left = str(int(point[0]) - 1) + chr(ord(point[1]) - 2)
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) - 2) 
            temp = [up, down, left, up_left, down_left]
        elif point == "10К" and field[point][-1] == Sea_battle.hit_icon:
            temp = ["9И", "10И", "9К"]            
        elif point == "10И" and field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0:-1]) - 1) + point[-1]
            right = point[0:-1] + chr(ord(point[-1]) + 2)
            left = point[0:-1] + chr(ord(point[-1]) - 1)                
            up_left = str(int(point[0:-1]) - 1) + chr(ord(point[-1]) - 1)
            up_right = str(int(point[0:-1]) - 1) + chr(ord(point[-1]) + 2)
            temp = [up, right, left, up_left, up_right]
        elif len(point) == 3 and point != "10А" and field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0:-1]) - 1) + point[-1]
            right = point[0:-1] + chr(ord(point[-1]) + 1)
            left = point[0:-1] + chr(ord(point[-1]) - 1)  
            up_left = str(int(point[0:-1]) - 1) + chr(ord(point[-1]) - 1)
            up_right = str(int(point[0:-1]) - 1) + chr(ord(point[-1]) + 1)
            temp = [up, right, left, up_left, up_right]
        elif point == "10А" and field[point][-1] == Sea_battle.hit_icon:
            temp = ["9А", "9Б", "10Б"]            
        elif point[-1] == "А" and field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0]) - 1) + point[1]
            left = point[0] + chr(ord(point[1]) + 1)
            down = str(int(point[0]) + 1) + point[1]
            up_left = str(int(point[0]) - 1) + chr(ord(point[1]) + 1)
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) + 1)
            temp = [up, left, down, up_left, down_left]            
        elif point[-1] == "И" and field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0]) - 1) + point[1]
            right = point[0] + chr(ord(point[1]) + 2)
            down = str(int(point[0]) + 1) + point[1]
            left = point[0] + chr(ord(point[1]) - 1)
            up_left = str(int(point[0]) - 1) + chr(ord(point[1]) - 1)
            up_right = str(int(point[0]) - 1) + chr(ord(point[1]) + 2)
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) - 1)
            down_right = str(int(point[0]) + 1) + chr(ord(point[1]) + 2)
            temp = [up, right, down, left, up_left, up_right, down_left, down_right]
        elif field[point][-1] == Sea_battle.hit_icon:
            up = str(int(point[0]) - 1) + point[1]
            right = point[0] + chr(ord(point[1]) + 1)
            down = str(int(point[0]) + 1) + point[1]
            left = point[0] + chr(ord(point[1]) - 1)
            up_left = str(int(point[0]) - 1) + chr(ord(point[1]) - 1)
            up_right = str(int(point[0]) - 1) + chr(ord(point[1]) + 1)
            down_left = str(int(point[0]) + 1) + chr(ord(point[1]) - 1)
            down_right = str(int(point[0]) + 1) + chr(ord(point[1]) + 1)
            temp = [up, right, down, left, up_left, up_right, down_left, down_right]
        for i in temp:
            if field[i][1] == Sea_battle.sea_icon_block:
                field[i][1] = Sea_battle.miss_icon
        return field

"""addon №1 ПРОИЗВОДИТ ОТБОР СОСЕДЕЙ ТОЛЬКО С '❌' И ОПРЕДЕЛЯЕТ ПОТОПЛЕН КОРАБЛЬ ИЛИ НЕТ (НАЛИЧИЕ '⚓')."""
def determining_vertical_and_horizontal_neighbors_addon(temp, field):
    result = [[]]
    for a in temp:
        if field[a][1] == Sea_battle.hit_icon:
            result[0].append(a)
        if field[a][1] == Sea_battle.ship_icon:
            result.append("alive")                                                                                               # в списке "result" появляется метка "alive" (корабль жив)
    return result

"""ФУНКЦИЯ, КОТОРАЯ ВОЗВРАЩАЕТ СОСЕДЕЙ ПО ВЕРТИКАЛИ И ГОРИЗОНТАЛИ с '❌', ТОЛЬКО ДЛЯ ТЕХ КЛЕТОК, КОТОРЫЕ САМИ с '❌'.
ДОПОЛНИТЕЛЬНАЯ ПРОВЕРКА КЛЕТОК НАПИСАНА В <addon №1>. МОДИФИКАЦИЯ КЛЕТОК НАПИСАНА В <addon №2>."""
def determining_vertical_and_horizontal_neighbors(point, field, for_basic_case):                                                 # ФУНКЦИЯ БУДЕТ ВЫЗЫВАТЬСЯ РЕКУРСИВНО, А В РЕКУРСИИ БУДУТ ВЫЗЫВАТЬСЯ НЕ РЕКУРСИНО ДРУГИЕ ДВЕ ФУНКЦИИ
        if point in for_basic_case:                                                                                              # базовый случай                     
            pass
        else:
            for_basic_case.append(point)                                                                                         # модернизация переменной для базового случая, данная точка больше не будет учитываться (условие в базовом случае)                                                                                                                    
            if point == "1А" and field[point][-1] == Sea_battle.hit_icon:
                temp = ["1Б", "2А"]                
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field) 
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)                    
            elif len(point) == 2 and point[0] == "1" and point != "1И" and point != "1К" and field[point][-1] == Sea_battle.hit_icon:
                left = point[0] + chr(ord(point[1]) - 1)
                right = point[0] + chr(ord(point[1]) + 1)
                down = str(int(point[0]) + 1) + point[1]
                temp = [left, right, down]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)        
            elif point == "1И" and field[point][-1] == Sea_battle.hit_icon:
                left = point[0] + chr(ord(point[1]) - 1)
                right = point[0] + chr(ord(point[1]) + 2)
                down = str(int(point[0]) + 1) + point[1]
                temp = [left, right, down]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)                
            elif point == "1К" and field[point][-1] == Sea_battle.hit_icon:
                temp = ["1И", "2К"]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field) 
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)              
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)                    
            elif point[-1] == "К" and point != "10К" and field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0]) - 1) + point[1]
                down = str(int(point[0]) + 1) + point[1]
                left = point[0] + chr(ord(point[1]) - 2)
                temp = [up, down, left]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)
            elif point == "10К" and field[point][-1] == Sea_battle.hit_icon:
                temp = ["10И", "9К"]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field) 
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)        
            elif point == "10И" and field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0:-1]) - 1) + point[-1]
                right = point[0:-1] + chr(ord(point[-1]) + 2)
                left = point[0:-1] + chr(ord(point[-1]) - 1)                
                temp = [up, right, left]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)        
            elif len(point) == 3 and point != "10А" and field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0:-1]) - 1) + point[-1]
                right = point[0:-1] + chr(ord(point[-1]) + 1)
                left = point[0:-1] + chr(ord(point[-1]) - 1)  
                temp = [up, right, left]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)        
            elif point == "10А" and field[point][-1] == Sea_battle.hit_icon:
                temp = ["9А", "10Б"]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field) 
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)                
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)
            elif point[-1] == "А" and field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0]) - 1) + point[1]
                left = point[0] + chr(ord(point[1]) + 1)
                down = str(int(point[0]) + 1) + point[1]
                temp = [up, left, down]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)
            elif point[-1] == "И" and field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0]) - 1) + point[1]
                right = point[0] + chr(ord(point[1]) + 2)
                down = str(int(point[0]) + 1) + point[1]
                left = point[0] + chr(ord(point[1]) - 1)
                temp = [up, right, down, left]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)
            elif field[point][-1] == Sea_battle.hit_icon:
                up = str(int(point[0]) - 1) + point[1]
                right = point[0] + chr(ord(point[1]) + 1)
                down = str(int(point[0]) + 1) + point[1]
                left = point[0] + chr(ord(point[1]) - 1)
                temp = [up, right, down, left]
                result = determining_vertical_and_horizontal_neighbors_addon(temp, field)             
                for i in result[0]:
                    determining_vertical_and_horizontal_neighbors(i, field, for_basic_case)
                if len(result) == 1:
                    field = changing_neighbors_around(point, field)
            return field
        
"""addon ОПРЕДЕЛЯЕТ СОСЕДСТВО КЛЕТКИ С '❌' И КЛЕТОК С '⚓'."""
def vertical_and_horizontal_neighborhood_check_addon(temp, field):    
    result = []
    for a in temp:
        if field[a][1] == Sea_battle.ship_icon:
            result.append(True)
    return True if True in result else False

"""ФУНКЦИЯ, КОТОРАЯ ПРОВЕРЯЕТ ЕСТЬ ЛИ СОСЕДСТВО ПО ВЕРТИКАЛИ И ГОРИЗОНТАЛИ '⚓' с '❌', ТОЛЬКО ДЛЯ ТЕХ КЛЕТОК, КОТОРЫЕ САМИ с '❌'.
ФУНКЦИЯ ВОЗВРАЩАЕТ СПИСОК, КОТОРЫЙ МОЖЕТ СОДЕРЖАТЬ TRUE, А МОЖЕТ НЕ СОДЕРЖАТЬ."""
def vertical_and_horizontal_neighborhood_check(point, field, temp_list):                                                         # Определяет соседние клетки и передаёт в функцию-addon их список. Addon возвращает True или False (проверяет окончательно на соседство с '⚓').
    if point == "1А" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["1Б", "2А"]                             
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif len(point) == 2 and point[0] == "1" and point != "1И" and point != "1К" and field[point][-1] == Sea_battle.hit_icon:
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point == "1И" and field[point][-1] == Sea_battle.hit_icon:
        left = point[0] + chr(ord(point[1]) - 1)
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        temp = [left, right, down]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point == "1К" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["1И", "2К"]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point[-1] == "К" and point != "10К" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 2)
        temp = [up, down, left]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point == "10К" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["10И", "9К"]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point == "10И" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 2)
        left = point[0:-1] + chr(ord(point[-1]) - 1)                
        temp = [up, right, left]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif len(point) == 3 and point != "10А" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0:-1]) - 1) + point[-1]
        right = point[0:-1] + chr(ord(point[-1]) + 1)
        left = point[0:-1] + chr(ord(point[-1]) - 1)  
        temp = [up, right, left]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point == "10А" and field[point][-1] == Sea_battle.hit_icon:
        temp = ["9А", "10Б"]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point[-1] == "А" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        left = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        temp = [up, left, down]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif point[-1] == "И" and field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 2)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    elif field[point][-1] == Sea_battle.hit_icon:
        up = str(int(point[0]) - 1) + point[1]
        right = point[0] + chr(ord(point[1]) + 1)
        down = str(int(point[0]) + 1) + point[1]
        left = point[0] + chr(ord(point[1]) - 1)
        temp = [up, right, down, left]
        result = vertical_and_horizontal_neighborhood_check_addon(temp, field)
        if result == True:
            temp_list.append(result)
    return temp_list

"""ФУНКЦИЯ, КОТОРАЯ ВОЗВРАЩАЕТ ОБНОВЛЁННЫЙ ОБЪЕКТ ВРАГА С ПОЛЕМ ДЛЯ КОРАБЛЕЙ ПОСЛЕ ХОДА ТЕКУЩЕГО ИГРОКА"""
def fuction_mod_object_of_enemy_ship_field_for_go_current_user(object, shot_player, package):
    object.field_ship = (shot_player, package)
    return object

"""ФУНКЦИЯ, КОТОРАЯ ВОЗВРАЩАЕТ ОБНОВЛЁННЫЙ ОБЪЕКТ С ПОЛЕМ ДЛЯ ТЕКУЩЕГО ИГРОКА (части для ходов) И ЗАМЕНЯЕТ ОБЪЕКТ НОВЫМ ЗНАЧЕНИЕМ"""
def fuction_mod_object_for_current_user_go(object, shot_player, package):
    object.field_go = (shot_player, package)
    return object

"""ФУНКЦИЯ, КОТОРАЯ ПРОВЕРЯЕТ СТАТУС КЛЕТКИ ИГРОВОГО ПОЛЯ С КОРАБЛЯМИ ПРОТИВНИКА"""
def function_check_cell(obj, shot):                                                                                              # в качестве параметров функция получает атрибут объект (словарь с расстановкой кораблей) и координаты выстрела игрока
    for a, b in obj.items():
        if a == shot:
            return b[1]

"""ФУНКЦИЯ, КОТОРАЯ РЕАЛИЗУЕТ ПРОЦЕСС ВВОДА КООРДИНАТ ВЫСТРЕЛА ОТ ИГРОКА"""
def function_input_coordinates():
    temp = []                                                                                                                    # в этот список будем класть все возможные варианты координат
    for a in Sea_battle.numbers:
        for b in  Sea_battle.letters:
            temp.append(a + b)                                                                                                   # кладём варианты координат в список
    while True:                                                                                                                  # повторяющийся цикл, пока не получим от пользователя существующие координаты
        result = input("Введите координаты выстрела (пример: 1А, 2А ... 10К): ").upper()
        if result in temp:
            break
        else:            
            print("Повторите ввод.")
            print()
    return result

"""ФУНКЦИЯ ДЛЯ ОКОНЧАТЕЛЬНОЙ ВИЗУАЛИЗАЦИИ ИГРОВОГО ПРОЦЕССА ПОЛЯ ИГРОКА (первая визуализация была описана в классе).
ФУНКЦИЯ В КАЧЕСТЕ ПАРАМЕТРА ПРИНИМАЕТ ОБЪЕКТ КЛАССА "Sea_battle"."""
def function_visualization(player):
    WIDTH, HEIGHT = bext.size()                                                                                                  # определить ширину и высоту экрана в em-(ах) (это размер символа) с помощью модуля bext
    bext.clear()                                                                                                                 # очистить экран с помощью модуля bext
    bext.goto(int(WIDTH / 75), int(HEIGHT / 4))                                                                                  # выберем расположение вывода поля игрока на экране с помощью модуля bext
    bext.fg("red")                                                                                                               # выберем цвет вывода шрифта на экране с помощью модуля bext
    print("ПОЛЕ ИГРОКА.\n")        
    player.show_field()                                                                                                          # используем методы класса, чтобы вывести игровое поле для игрока и поле для его выстрелов на экран
    print()

"""ОСНОВНАЯ ФУНКЦИЯ"""
def function_main():
    """В ЭТОМ БЛОКЕ СОЗДАДИМ ИГРОВЫЕ ПОЛЯ"""    
    player = Sea_battle()                                                                                                        # создадим объекты класса "игровое поле" для игрока 
    cpu = Sea_battle()                                                                                                           # создадим объекты класса "игровое поле" для компьютера 
    player.arrange_ships()                                                                                                       # используем метод класса, чтобы заполнить игровое поля для игрока кораблями
    cpu.arrange_ships()                                                                                                          # используем метод класса, чтобы заполнить игровое поля для компьютера кораблями   
    
    """ЗАПУСК ОСНОВНОГО ЦИКЛА ИГРЫ""" 
    response  = "Начинаем заново"                                                                                                # переменная понадобится для первого запуска условия в подцикле "для компьютера"
    init_vert_horizontal = set()                                                                                                 # переменная-множество понадобится для определения ориентации корабля (вертикаль или горизонталь)
    while True:                                                                                                                  # основной цикл прервётся только в случае окончания игры
        win = False                                                                                                              # переменная, по-умолчанию содержащая значение, что игра пока ещё не закончена

        """подцикл для игрока, следующий подцикл будет для компьютера"""
        while True:                                                                                                              
            function_visualization(player)                                                                                       # функция визуализации для поля игрока, поле компьютера выводить не надо                           
            shot_player = function_input_coordinates()                                                                           # функция, которая вызывает ввод координат выстрела от игрока и возвращает реальную, проверенную координату
            cell_status = function_check_cell(cpu.field_ship, shot_player)                                                       # функция проверки статуса клетки для компьютеного поля с расстановкой кораблей           
            if cell_status == Sea_battle.hit_icon or cell_status == Sea_battle.miss_icon:                                        # случай, если в эту клетку ранее уже производили выстрел, нужно отправить в начало цикла
                playsound.playsound("2.1.15.task_error.mp3")
                print()
                input("Такой выстрел ранее был произведён или это клетка рядом с потопленным кораблём. Нажмите <Enter> для повторения ввода. ")
                continue
            elif cell_status == Sea_battle.sea_icon or cell_status == Sea_battle.sea_icon_block:                                 # случай, при котором возможна модернизация основного поля компьютера и поля ходов у игрока
                package = Sea_battle.miss_icon                                                                                   # вводится переменная, которая содержит значение для иконки выстрела
                playsound.playsound("2.1.15.task_выстрел.mp3")
                playsound.playsound("2.1.15.task_вода.mp3")
            elif cell_status == Sea_battle.ship_icon:                                                                            # случай, при котором возможна модернизация основного поля компьютера и поля ходов у игрока
                package = Sea_battle.hit_icon                                                                                    # вводится переменная, которая содержит значение для иконки выстрела           
                playsound.playsound("2.1.15.task_выстрел.mp3")
                playsound.playsound("2.1.15.task_попадание.mp3")
            player = fuction_mod_object_for_current_user_go(player, shot_player, package)                                        # возвращает обновлённый объект с полем для текущего игрока (части для ходов) и заменяет объект новым значением            
            cpu = fuction_mod_object_of_enemy_ship_field_for_go_current_user(cpu, shot_player, package)                          # возвращает обновлённый объект с полем для cpu (части для кораблей) и заменяет объект новым значением
            """необходимо начать проверку убит/не убит"""
            temp_list = []
            for i in cpu.field_ship:
                temp_list = vertical_and_horizontal_neighborhood_check(i, cpu.field_ship, temp_list)    
            test = True if True not in temp_list else False                                                                      # проверка поля, если есть рядом '⚓' и '❌', то условие не выполняется и переменная будет False и следующую операцию выполнять нельзя          
            """обновим объект cpu (часть поля с кораблями), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
            появятся "⚪"."""
            if test:                                                                                                             # если рядом '⚓' и '❌', то условие не запустится
                for i in cpu.field_ship:
                    for_basic_case = []                                                                                          # эта переменная нужна для сбора информации, о том какие клетки уже посетили рекурсивно, и она должна быть именно здесь, а не в самой функции
                    cpu._field = determining_vertical_and_horizontal_neighbors(i, cpu.field_ship, for_basic_case)                # обновление словаря с полем для кораблей с обработкой каждой точки, проверяет убит ли корабль и ставаит "⚪" вокруг убитого корабля
            """обновим объект player (часть поля для ходов), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
            появятся "⚪". Перенесём "⚪" из cpu._field_ship в player._field_ship_go."""
            temp_dict = dict()
            for a, b in cpu.field_ship.items():
                if b[1] == Sea_battle.miss_icon:
                    temp_dict[a] = b
            for a, b in temp_dict.items():
                player._field_go[a] = b            
            """проверка победы игрока, конец игры"""
            check = set()
            for i in cpu.field_ship.values():
                if Sea_battle.ship_icon in i:
                    check.add(i[1])
            if Sea_battle.ship_icon not in check:
                win = True
                break
            """проверка повторного хода игрока, отправляем в начало цикла"""
            if cpu.field_ship[shot_player][1] == Sea_battle.hit_icon:
                continue
            break

        """Конец игры. Победа игрока!!!"""
        if win:
            function_visualization(player)
            print("Победа!!!")
            playsound.playsound("2.1.15.task_победа.mp3")
            break                                                                                                                # прерываем основной цикл
        
        """подцикл для компьютера"""
        while True:
            function_visualization(player)                                                                                       # функция визуализации для поля игрока, поле компьютера выводить не надо ----------> (НА ПОЛЕ ИГРОКА БУДУТ ВИДНЫ ХОДЫ КОМПТЮТЕРА!!!)                          
            if response == "Начинаем заново":                                                                                    # условие, если предыдущий корабль убит или это первый ход
                shot_cpu = function_input_coordinates_for_cpu(cpu.field_go)                                                      # функция, которая рандомно определяет выстрел cpu и возвращает реальную, проверенную координату, в которую раньше не стреляли
                cell_status = function_check_cell(player.field_ship, shot_cpu)                                                   # функция проверки статуса клетки для поля игрока, которое с кораблями
                if cell_status == Sea_battle.sea_icon or cell_status == Sea_battle.sea_icon_block:                               # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                    package = Sea_battle.miss_icon                                                                               # вводится переменная, которая содержит значение для иконки выстрела
                elif cell_status == Sea_battle.ship_icon:                                                                        # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                    package = Sea_battle.hit_icon                                                                                # вводится переменная, которая содержит значение для иконки выстрела          
                cpu = fuction_mod_object_for_current_user_go(cpu, shot_cpu, package)                                             # возвращает обновлённый объект с полем для компьютера (части для ходов) и заменяет объект новым значением
                player = fuction_mod_object_of_enemy_ship_field_for_go_current_user(player, shot_cpu, package)                   # возвращает обновлённый объект с полем для игрока (части для кораблей) и заменяет объект новым значением
                """необходимо начать проверку убит/не убит"""
                temp_list = []
                for i in player.field_ship:
                    temp_list = vertical_and_horizontal_neighborhood_check(i, player.field_ship, temp_list)    
                test = True if True not in temp_list else False                                                                  # проверка поля, если есть рядом '⚓' и '❌', то условие не выполняется и переменная будет False и следующую операцию выполнять нельзя         
                """обновим объект player (часть поля с кораблями), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                появятся "⚪"."""
                if test:                                                                                                         # если рядом '⚓' и '❌', то условие не запустится                                                                                                         
                    for i in player.field_ship:
                        for_basic_case = []                                                                                      # эта переменная нужна для сбора информации, о том какие клетки уже посетили рекурсивно, и она должна быть именно здесь, а не в самой функции
                        player._field = determining_vertical_and_horizontal_neighbors(i, player.field_ship, for_basic_case)      # обновление словаря с полем для кораблей с обработкой каждой точки, проверяет убит ли корабль и ставаит "⚪" вокруг убитого корабля
                """обновим объект cpu (часть поля для ходов), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                появятся "⚪". Перенесём "⚪" из player._field_ship в cpu._field_ship_go."""
                temp_dict = dict()
                for a, b in player.field_ship.items():
                    if b[1] == Sea_battle.miss_icon:
                        temp_dict[a] = b
                for a, b in temp_dict.items():
                    cpu._field_go[a] = b            
                """проверка победы игрока, конец игры"""
                check = set()
                for i in player.field_ship.values():
                    if Sea_battle.ship_icon in i:
                        check.add(i[1])
                if Sea_battle.ship_icon not in check:
                    win = True
                    break
                """необходимо начать проверку убит/не убит №2. для переменной response"""
                wounded_set = set()                                                                                              # множество, которое содержит "ранен" и "не ранен" или только "ранен". 
                for point in player.field_ship:
                    result = vertical_and_horizontal_neighborhood_check_2(point, player.field_ship)                              # переменная множество содержит "ранен" и "не ранен"
                    wounded_set = wounded_set | result                              
                if "ранен" in wounded_set:
                    response = "Ранен. Продолжаем стрелять."
                else:
                    response = "Начинаем заново"
                """проверка повторного хода игрока, отправляем в начало цикла"""
                if player.field_ship[shot_cpu][1] == Sea_battle.hit_icon:
                    continue
            
            elif response == "Ранен. Продолжаем стрелять.":                                                                      # условие, если предыдущий корабль ранен
                shot_cpu_neighborhood_list = vertical_and_horizontal_neighborhood_check_3(shot_cpu)                              # переменная содержит список соседей клетки, в которую произведено последнее попадание
                for a, b in cpu.field_go.items():                                                                                # в цикле выкинем из списка shot_cpu_neighborhood_list все не подходящие промахи
                    if b[1] == Sea_battle.miss_icon and a in shot_cpu_neighborhood_list:
                        shot_cpu_neighborhood_list.remove(a)
                """нужно определить ориентацию раненного корабля (вертикаль или горизонталь)"""
                init_vert_horizontal.add(shot_cpu)                                                                               # добавим первый выстрел в множество
                for a, b in cpu.field_go.items():                                                                                # в цикле добавим в множество вторую клетку с попаданием (если оно есть), которая поможет определить ориентацию корабля
                    if b[1] == Sea_battle.hit_icon and a in shot_cpu_neighborhood_list:
                        init_vert_horizontal.add(a)
                
                # если множество всё еще короткое и состоит из одного элемента, значит ориентация корабля еще не определена (он может оказаться 2-х палубным и определение ориентации в дальнейшем не понадобится)
                if len(init_vert_horizontal) == 1:
                    shot_cpu_second = random.choice(shot_cpu_neighborhood_list)                                
                    cell_status = function_check_cell(player.field_ship, shot_cpu_second)                                        # функция проверки статуса клетки для поля игрока, которое с кораблями
                    if cell_status == Sea_battle.sea_icon or cell_status == Sea_battle.sea_icon_block:                           # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                        package = Sea_battle.miss_icon                                                                           # вводится переменная, которая содержит значение для иконки выстрела
                    elif cell_status == Sea_battle.ship_icon:                                                                    # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                        package = Sea_battle.hit_icon                                                                            # вводится переменная, которая содержит значение для иконки выстрела          
                    cpu = fuction_mod_object_for_current_user_go(cpu, shot_cpu_second, package)                                  # возвращает обновлённый объект с полем для компьютера (части для ходов) и заменяет объект новым значением
                    player = fuction_mod_object_of_enemy_ship_field_for_go_current_user(player, shot_cpu_second, package)        # возвращает обновлённый объект с полем для игрока (части для кораблей) и заменяет объект новым значением
                    """необходимо начать проверку убит/не убит"""
                    temp_list = []
                    for i in player.field_ship:
                        temp_list = vertical_and_horizontal_neighborhood_check(i, player.field_ship, temp_list)    
                    test = True if True not in temp_list else False                                                              # проверка поля, если есть рядом '⚓' и '❌', то условие не выполняется и переменная будет False и следующую операцию выполнять нельзя         
                    """обновим объект player (часть поля с кораблями), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                    появятся "⚪"."""
                    if test:                                                                                                     # если рядом '⚓' и '❌', то условие не запустится                                                                                                         
                        for i in player.field_ship:
                            for_basic_case = []                                                                                  # эта переменная нужна для сбора информации, о том какие клетки уже посетили рекурсивно, и она должна быть именно здесь, а не в самой функции
                            player._field = determining_vertical_and_horizontal_neighbors(i, player.field_ship, for_basic_case)  # обновление словаря с полем для кораблей с обработкой каждой точки, проверяет убит ли корабль и ставаит "⚪" вокруг убитого корабля
                    """обновим объект cpu (часть поля для ходов), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                    появятся "⚪". Перенесём "⚪" из player._field_ship в cpu._field_ship_go."""
                    temp_dict = dict()
                    for a, b in player.field_ship.items():
                        if b[1] == Sea_battle.miss_icon:
                            temp_dict[a] = b
                    for a, b in temp_dict.items():
                        cpu._field_go[a] = b            
                    """проверка победы игрока, конец игры"""
                    check = set()
                    for i in player.field_ship.values():
                        if Sea_battle.ship_icon in i:
                            check.add(i[1])
                    if Sea_battle.ship_icon not in check:
                        win = True
                        break
                    """необходимо начать проверку убит/не убит №2. для переменной response"""
                    wounded_set = set()                                                                                              # множество, которое содержит "ранен" и "не ранен" или только "ранен". 
                    for point in player.field_ship:
                        result = vertical_and_horizontal_neighborhood_check_2(point, player.field_ship)                              # переменная множество содержит "ранен" и "не ранен"
                        wounded_set = wounded_set | result                              
                    if "ранен" in wounded_set:
                        response = "Ранен. Продолжаем стрелять."
                    else:
                        response = "Начинаем заново"
                    init_vert_horizontal = set()                                                                                     # переменная-множество понадобится для определения ориентации корабля (нужно её обнулять в конце каждого цикла, она заполнится заново)               
                    """проверка повторного хода игрока, отправляем в начало цикла"""
                    if player.field_ship[shot_cpu_second][1] == Sea_battle.hit_icon:
                        continue    
                     
                # если множество длинное и состоит из двух элементов, значит ориентацию корабля уже можно определить"""
                elif len(init_vert_horizontal) > 1:     
                    """определение ориентации корабля"""
                    if list(init_vert_horizontal)[0][0] == list(init_vert_horizontal)[1][0]:
                        orientation = "horizontal"
                    elif list(init_vert_horizontal)[0][1] == list(init_vert_horizontal)[1][1]:
                        orientation = "vertical"
                    """две ориентации и для каждой своя переменная shot_cpu_second, которая будет определяться соответствующей функцией"""
                    if orientation == "horizontal":
                        shot_cpu_second = horizontal_shot(cpu.field_go, shot_cpu)
                    else:
                        shot_cpu_second = vertical_shot(cpu.field_go, shot_cpu)
                    cell_status = function_check_cell(player.field_ship, shot_cpu_second)                                        # функция проверки статуса клетки для поля игрока, которое с кораблями
                    if cell_status == Sea_battle.sea_icon or cell_status == Sea_battle.sea_icon_block:                           # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                        package = Sea_battle.miss_icon                                                                           # вводится переменная, которая содержит значение для иконки выстрела
                    elif cell_status == Sea_battle.ship_icon:                                                                    # случай, при котором возможна модернизация основного поля игрока и поля ходов у компьютера
                        package = Sea_battle.hit_icon                                                                            # вводится переменная, которая содержит значение для иконки выстрела          
                    cpu = fuction_mod_object_for_current_user_go(cpu, shot_cpu_second, package)                                  # возвращает обновлённый объект с полем для компьютера (части для ходов) и заменяет объект новым значением
                    player = fuction_mod_object_of_enemy_ship_field_for_go_current_user(player, shot_cpu_second, package)        # возвращает обновлённый объект с полем для игрока (части для кораблей) и заменяет объект новым значением
                    """необходимо начать проверку убит/не убит"""
                    temp_list = []
                    for i in player.field_ship:
                        temp_list = vertical_and_horizontal_neighborhood_check(i, player.field_ship, temp_list)    
                    test = True if True not in temp_list else False                                                              # проверка поля, если есть рядом '⚓' и '❌', то условие не выполняется и переменная будет False и следующую операцию выполнять нельзя         
                    """обновим объект player (часть поля с кораблями), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                    появятся "⚪"."""
                    if test:                                                                                                     # если рядом '⚓' и '❌', то условие не запустится                                                                                                         
                        for i in player.field_ship:
                            for_basic_case = []                                                                                  # эта переменная нужна для сбора информации, о том какие клетки уже посетили рекурсивно, и она должна быть именно здесь, а не в самой функции
                            player._field = determining_vertical_and_horizontal_neighbors(i, player.field_ship, for_basic_case)  # обновление словаря с полем для кораблей с обработкой каждой точки, проверяет убит ли корабль и ставаит "⚪" вокруг убитого корабля
                    """обновим объект cpu (часть поля для ходов), в случае уничтожения одного из кораблей вокруг этих клеток с кораблём
                    появятся "⚪". Перенесём "⚪" из player._field_ship в cpu._field_ship_go."""
                    temp_dict = dict()
                    for a, b in player.field_ship.items():
                        if b[1] == Sea_battle.miss_icon:
                            temp_dict[a] = b
                    for a, b in temp_dict.items():
                        cpu._field_go[a] = b            
                    """проверка победы игрока, конец игры"""
                    check = set()
                    for i in player.field_ship.values():
                        if Sea_battle.ship_icon in i:
                            check.add(i[1])
                    if Sea_battle.ship_icon not in check:
                        win = True
                        break
                    """необходимо начать проверку убит/не убит №2. для переменной response"""
                    wounded_set = set()                                                                                              # множество, которое содержит "ранен" и "не ранен" или только "ранен". 
                    for point in player.field_ship:
                        result = vertical_and_horizontal_neighborhood_check_2(point, player.field_ship)                              # переменная множество содержит "ранен" и "не ранен"
                        wounded_set = wounded_set | result                              
                    if "ранен" in wounded_set:
                        response = "Ранен. Продолжаем стрелять."
                    else:
                        response = "Начинаем заново"
                    init_vert_horizontal = set()                                                                                     # переменная-множество понадобится для определения ориентации корабля (нужно её обнулять в конце каждого цикла, она заполнится заново)               
                    """проверка повторного хода игрока, отправляем в начало цикла"""
                    if player.field_ship[shot_cpu_second][1] == Sea_battle.hit_icon:
                        continue                    
            break
            
        """Конец игры. Победа компьютера!!!"""
        if win:
            function_visualization(player)
            print("Вы проиграли!!!")
            playsound.playsound("2.1.15.task_game_over.mp3")
            break                                                                                                                # прерываем основной цикл 
        

if __name__ == "__main__":    
    print()
    print("Скрипт запущен напрямую.")                                                                                            # сообщение не будет видно на экране, т.к. экран далее будет очищен с помощью модуля bext
    print()
    function_main()
else:    
    print()
    print("Скрипт импортирован.")
    print()