예제 #1
0
def fix():
    try:
        db = database()
        data = db.read('SELECT * FROM PrizeWinners WHERE Absent IS NOT NULL ')
        return render_template("fix.html", data=data)
    except:
        return render_template("fix.html")
예제 #2
0
def fixupdate():
    try:
        db = database()
        db.write('UPDATE PrizeWinners SET Absent = NULL WHERE ID = (?)',
                 request.args.get('id'))
        return redirect(request.referrer)
    except:
        return redirect(request.referrer)
예제 #3
0
def viewabsents():
    try:
        db = database()
        data = db.read(
            'SELECT * FROM PrizeWinners WHERE Absent IS NOT NULL ORDER BY PrizeID DESC'
        )
        return render_template("absents.html", data=data)
    except:
        return render_template("absents.html")
예제 #4
0
def toDB():
    os.remove('data/database.db')
    with open('data/PrizeWinners.csv', 'r') as f:
        data = f.readlines()[1:]
    db = database()
    db.c.execute(
        'CREATE TABLE IF NOT EXISTS "PrizeWinners" ( `ID` INTEGER PRIMARY KEY AUTOINCREMENT, `PrizeID` INTEGER, `Name` TEXT, `Absent` NUMERIC, `Prizes` TEXT, `Extra` TEXT )'
    )

    for d in data:
        d = d.split(',')
        if d[0].isnumeric():
            print(d)
            db.write(
                'INSERT INTO PrizeWinners(PrizeID, Name, Prizes, Extra) VALUES(?,?,?,?)',
                d[0], d[1], d[3], d[4][:-2])

    db.close()
예제 #5
0
def view():
    try:
        step = 1
        page = 0
        db = database()
        if request.args.get('step') == None or request.args.get(
                'page') == None:
            data = db.read('SELECT * FROM PrizeWinners')
        else:
            step = int(request.args.get('step'))
            page = int(request.args.get('page'))

            start = step * page
            end = step * (page + 1)

            data = db.read('SELECT * FROM PrizeWinners')[start:end]
        return render_template("view.html", data=data, step=step, page=page)
    except:
        return render_template("view.html")
class squad_generation():
    """Создаём отряд, распределяем должности, обучаем, снаряжаем.
    
    - Генерируется число солдат, равное численности отряда.
    - Солдаты распределяются по должностям и уровням (лучшие -- командиры)
    """
    metadict_squads = squads.metadict_squads
    # Для названий отрядов:
    dict_words = {}
    dict_words.update(lang_sindar.dict_words)
    dict_words.update(lang_human.dict_words)
    # Подключаемся к базе данных солдат:
    database = database.database()

    def create_squad(self, squad_type):
        """Создаём отряд.
        
        Описание функции.
        """
        # TODO: Добавь "воссоздание" отрядов из базы данных.
        # В том случае, если вместо squad_type указано его имя.
        self.squad_type = squad_type
        self.dict_squad = self.metadict_squads[self.squad_type].copy()
        # У отряда тоже есть имя -- название:
        self.name, self.name_translate = gen_name(self.dict_words, name_length = 3)
        reinforce_number = sum(self.dict_squad.values())
        # Изначально все бойцы отряда 1 уровня:
        self.metadict_soldiers = self.gen_soldiers(reinforce_number)
        self.squad_number = len(self.metadict_soldiers)
        self.soldiers_list = list(self.metadict_soldiers.keys())
        # Здесь бойцы отряда получают levelup и распределяются по должностям:
        self.metadict_soldiers.update(self.set_ranks())
        #self.set_initiative()
        # Отряд получает верховых животных:
        self.pet_types = self.find_pets(self.metadict_soldiers)
        for pet_type, number in self.pet_types.items():
            self.metadict_soldiers.update(self.gen_pets(number, pet_type))
        # Лошади знакомятся с хозяевами (и хозяева снаряжают их бронёй):
        self.set_mounts()
        self.set_mounts_armor()
        # Кое-какая обобщённая статистика:
        self.behavior = self.find_base_behaviour()
        self.squad_overload = self.calculate_squad_overload()
        self.armor_class = self.calculate_squad_armor_class()
        self.hitpoints_medial = self.calculate_squad_hitpoints_medial()
        self.attack_mod = self.calculate_squad_attack_mod()
        self.squad_cost = self.calculate_squad_cost()
        #self.set_hitpoints()

    def load_squad_from_DB(self, squad_name, get_injured = False, get_all = False):
        """Воссоздаём отряд из базы данных.
        
        Там только список солдат.
        """
        # TODO: пили вывод данных из БД.
        # Придумай что-нибудь с типом отряда и переводом имени
        self.squad_type = squad_name
        self.name = squad_name
        self.name_translate = squad_name
        soldiers_uuid_list = self.database.print_squad_soldiers(squad_name)
        self.metadict_soldiers = self.load_soldiers_from_DB(soldiers_uuid_list, get_injured, get_all)
        self.squad_number = len(self.metadict_soldiers)
        self.soldiers_list = list(self.metadict_soldiers.keys())
        # Кое-какая обобщённая статистика:
        self.behavior = self.find_base_behaviour()
        self.squad_overload = self.calculate_squad_overload()
        self.armor_class = self.calculate_squad_armor_class()
        self.attack_mod = self.calculate_squad_attack_mod()
        self.squad_cost = self.calculate_squad_cost()

    def load_soldiers_from_DB(self, soldiers_uuid_list, get_injured = False, get_all = False):
        """Создаём солдат, загружая характеристики из базы данных."""
        metadict_soldiers = {}
        for uuid_string in soldiers_uuid_list:
            soldier_dict = self.database.soldier_from_database(uuid_string)
            if not soldier_dict.get('death')\
                    and not soldier_dict.get('disabled')\
                    and not soldier_dict.get('captured')\
                    or get_all:
                if not soldier_dict.get('fall') and soldier_dict.get('hitpoints') > 0\
                        or get_all or get_injured:
                    recruit = soldier_in_battle()
                    recruit.__dict__ = soldier_dict
                    # Восстанавливаем рекурсивную ссылку:
                    recruit.spells_generator.mage = recruit
                    metadict_soldiers[recruit.uuid] = recruit
        # Сортируем бойцов по уровню, чтобы на вершине были командиры.
        metadict_soldiers = OrderedDict(reversed(sorted(metadict_soldiers.items(),key=lambda x: x[1].level)))
        return metadict_soldiers

    def set_hitpoints(self):
        """Хитпоинты в начале боя."""
        for uuid,soldier in self.metadict_soldiers.items():
            soldier.set_hitpoints()

    def set_initiative(self):
        """Броски инициативы бойцам стороны."""
        for uuid,soldier in self.metadict_soldiers.items():
            soldier.set_initiative()

    def set_ally_side(self, ally_side):
        """Указываем своих."""
        self.ally_side = ally_side
        for uuid,soldier in self.metadict_soldiers.items():
            soldier.set_ally_side(ally_side)

    def set_enemy_side(self, enemy_side):
        """Указываем врага."""
        self.enemy_side = enemy_side
        for uuid,soldier in self.metadict_soldiers.items():
            soldier.set_enemy_side(enemy_side)

    def reinforce(self, reinforce_number, rank = None):
        """Пополняем отряд. Просто создаём новых солдат и пополняем словарь."""
        self.metadict_soldiers.update(self.gen_soldiers(reinforce_number))
        self.squad_number = len(self.metadict_soldiers)

    def reinforce_pets(self, reinforce_number, animal_type = None):
        """Пополняем отряд лошадками."""
        # TODO: так потерявшие коней всадники должны получить новых.
        self.metadict_soldiers.update(self.gen_pets(reinforce_number, animal_type))

    def find_pets(self, metadict_soldiers):
        """Возвращает словарь ездовых/боевых животных отряда.
        
        Питомцы должны быть указаны в шаблонах metadict_chars.
        """
        # Находим нуждающихся в лошадках бойцов:
        animals_list = []
        for soldier in metadict_soldiers.values():
            if hasattr(soldier, 'mount_type'):
                animals_list.append(soldier.mount_type)
        # Группируем одинаковых питомцев в словарь:
        animals_dict = {}
        for key in animals_list:
            if not key in animals_dict:
                animals_dict[key] = 1
            elif key in animals_dict:
                animals_dict[key] += 1
        return animals_dict

    def set_mounts(self):
        """Верховые животные получают хозяев, а хозяева верховых животных.
        
        Отныне они узнают друг друга по uuid.
        """
        for soldier in self.metadict_soldiers.values():
            if hasattr(soldier, 'mount_type') and not hasattr(soldier, 'mount_uuid'):
                for mount in self.metadict_soldiers.values():
                    if mount.rank == soldier.mount_type and not hasattr(mount, 'master_uuid'):
                        soldier.mount_uuid = mount.uuid
                        mount.master_uuid = soldier.uuid
                        break

    def set_mounts_armor(self):
        """Верховые животные получают броню от своих хозяев."""
        for soldier in self.metadict_soldiers.values():
            if hasattr(soldier, 'mount_uuid'):
                mount = self.metadict_soldiers[soldier.mount_uuid]
                mount.equipment_weapon = soldier.equipment_mount
                mount.armor = mount.takeoff_armor()
                mount.armor.update(mount.get_armor())

    def find_medial_abilities(self):
        """Средняя сумма характеристик по роте.
        
        Используется для вывода статистики, другого применения нет.
        """
        ability_sum_list = [ ]
        for soldier in self.metadict_soldiers.values():
            ability_sum = sum(soldier.abilityes.values())
            ability_sum_list.append(ability_sum)
        medial_ability_sum = sum(ability_sum_list) / len(ability_sum_list)
        return medial_ability_sum

    def find_best(self):
        """Находим лучшего в роте по сумме параметров.
        
        Используется для выбора офицеров. Крепкие получаются бычары:
        - В геройской роте средние параметры командира -- 95
        - В роте из простолюдинов среднее для командира -- 82
        """
        ability_sum_min = 0
        for soldier in self.metadict_soldiers.values():
            ability_sum = sum(soldier.abilityes.values())
            if ability_sum >= ability_sum_min:
                ability_sum_min = ability_sum
                best_soldier = soldier
        return best_soldier.uuid

    def find_base_behaviour(self):
        """Определяем тактику отряда по основному юниту (лучники, бойцы).
        
        Это использует squad_AI для выбора задачи боя.
        """
        types_list = [soldier.behavior for soldier in self.metadict_soldiers.values()\
                if soldier.behavior != 'mount']
        types_dict = collections.Counter(types_list)
        max_type = max(types_dict.items(), key=operator.itemgetter(1))
        return max_type[0]

    def calculate_squad_overload(self):
        """Суммарный вес снаряжения отряда и число перегруженных бойцов."""
        overload_soldiers = 0
        lightload_soldiers = 0
        squad_overload = {}
        for soldier in self.metadict_soldiers.values():
            for key, value in soldier.overload.items():
                if key == 'base_speed':
                    pass
                elif not key in squad_overload and not type(value) == bool:
                    squad_overload[key] = value
                elif key in squad_overload and type(value) != bool:
                    squad_overload[key] += value
                elif key == 'battle_overload' and value == True:
                    overload_soldiers += 1
                elif key == 'battle_lightload' and value == True:
                    lightload_soldiers += 1
        #squad_overload.pop('base_speed'),
        #squad_overload.pop('battle_lightload'),
        #squad_overload.pop('battle_overload'),
        #squad_overload.pop('travel_overload')
        squad_overload['overload_soldiers'] = overload_soldiers
        squad_overload['lightload_soldiers'] = lightload_soldiers
        return squad_overload

    def calculate_squad_armor_class(self):
        """Усреднённая защита отряда."""
        sum_armor_class = sum([soldier.armor['armor_class'] for soldier in self.metadict_soldiers.values()])
        squad_number = len(self.metadict_soldiers)
        return round(sum_armor_class / squad_number, 1)

    def calculate_squad_hitpoints_medial(self):
        """Усреднённые хиты по отряду."""
        sum_hitpoints = sum([soldier.hitpoints_max for soldier in self.metadict_soldiers.values()])
        squad_number = len(self.metadict_soldiers)
        return round(sum_hitpoints / squad_number, 1)

    def calculate_squad_attack_mod(self):
        """Средний по отряду (и по типам бойцов) модификатор атаки.
        
        В выводе кортеж:
        1) атака лучшего бойца.
        2) лучшая атака бойцов усреднённо.
        3) средняя атака бойцов по всем видам оружия.
        """
        attack_mod_best = 0
        attack_mods_dict_sum = {}
        attack_mods_dict_max = {}
        for soldier in self.metadict_soldiers.values():
            attacks_mods_list = [attack['attack_mod'] for key, attack in soldier.attacks.items()
                    if not 'volley' in key]
            if attacks_mods_list:
                attack_mod_max = max(attacks_mods_list)
                attack_mod_medial = sum(attacks_mods_list) / len(attacks_mods_list)
                if not soldier.rank in attack_mods_dict_sum:
                    attack_mods_dict_max[soldier.rank] = attack_mod_max
                    attack_mods_dict_sum[soldier.rank] = attack_mod_medial
                else:
                    attack_mods_dict_max[soldier.rank] += attack_mod_max
                    attack_mods_dict_sum[soldier.rank] += attack_mod_medial
                #if attack_mod_max > attack_mod_best:
                #    attack_mod_best = attack_mod_max
                # Дуэлятся с героями у нас только командиры 4+ lvl:
                if attack_mod_max > attack_mod_best\
                        and soldier.behavior == 'commander' and soldier.level >= 4:
                    attack_mod_best = attack_mod_max
        attack_mod_medial = round(sum(attack_mods_dict_sum.values()) / len(self.metadict_soldiers), 1)
        attack_mod_max = round(sum(attack_mods_dict_max.values()) / len(self.metadict_soldiers), 1)
        #attack_mods_dict = {}
        #for key, attack_mod_sum in attack_mods_dict_sum.items():
        #    rank_list = [soldier for soldier in self.metadict_soldiers.values()\
        #            if soldier.rank == key]
        #    rank_number = len(rank_list)
        #    attack_mods_dict[key] = round(attack_mod_sum / rank_number, 1)
        #return attack_mods_dict
        return attack_mod_best, attack_mod_max, attack_mod_medial
    
    def calculate_squad_cost(self):
        """Суммарная стоимость отряда."""
        squad_cost_dict = {}
        for soldier in self.metadict_soldiers.values():
            for key, value in soldier.unit_cost.items():
                if not key in squad_cost_dict:
                    squad_cost_dict[key] = value
                elif key in squad_cost_dict and type(value) != bool:
                    squad_cost_dict[key] += value
        for key, value in squad_cost_dict.items():
            squad_cost_dict[key] = round(value)
        return squad_cost_dict

    def gen_pets(self, number, animal_type):
        """Даём отряду верховых животных, питомцев."""
        metadict_pets = {}
        for n in range(number):
            pet = soldier_in_battle()
            pet.create_pet(animal_type)
            pet.squad_name = self.name
            pet.squad_name_translate = self.name_translate
            metadict_pets[pet.uuid] = pet
        return metadict_pets

    def select_soldiers(func):
        """Выкидываем слабейших из состава отряда.

        Для этого есть метка recruit_selection (которая должна быть у всех).
        """
        def wrapper(self, squad_number, rank = None):
            metadict_soldiers = func(self, squad_number, rank = None)
            if not rank and [soldier for soldier in metadict_soldiers.values()
                    if soldier.__dict__.get('recruit_selection')]:
                # Убираем рекрутов из шаблона отряда:
                dict_squad = self.dict_squad.copy()
                common_soldier = max(dict_squad, key=lambda k: dict_squad[k])
                dict_squad.pop(common_soldier)
                # Отбираем лучших по оставшемуся числу:
                number = (sum(dict_squad.values()))
                metadict_soldiers = self.select_best_soldiers(number, metadict_soldiers)
            return metadict_soldiers
        return wrapper

    def select_best_soldiers(self, number, metadict_soldiers):
        """Выбирает определённое число лучших солдат в отряде.
        
        Лучшими считаются бойцы с наибольшей суммой параметров.
        """
        # ЗАМЕТКА: Стоило бы учесть хитпоинты, но все бойцы пока что 1 lvl.
        # ------------------------------------------------------------
        # Если понадобится, прибавь к сумме ниже число хитов, делённое на уровень.
        # Тогда нам нужна независимая от constitution сумма хитов. Да просто вычти!
        # ------------------------------------------------------------
        abilityes_dict = {uuid:sum(soldier.abilityes.values())
                for uuid, soldier in metadict_soldiers.items()}
        abilityes_dict = OrderedDict(reversed(sorted(abilityes_dict.items(),key=lambda x: x[1])))
        best_soldiers_list = list(abilityes_dict.keys())[0:number]
        best_soldiers_dict = {uuid:soldier for uuid, soldier in metadict_soldiers.items()
                if uuid in best_soldiers_list}
        #print([sum(soldier.abilityes.values()) for soldier in best_soldiers_dict.values()])
        return best_soldiers_dict

    @select_soldiers
    def gen_soldiers(self, squad_number, rank = None):
        """Даём отряду столько-то бойцов определённого ранга.

        По умолчанию берётся самый многочисленный ранг (рядовые бойцы).
        """
        dict_squad = self.dict_squad.copy()
        if not rank:
            common_soldier = max(dict_squad, key=lambda k: dict_squad[k])
            rank = common_soldier
        # Создаём солдат:
        metadict_soldiers = {}
        for n in range(squad_number):
            recruit = soldier_in_battle()
            recruit.create_soldier(common_soldier)
            # TODO: допилить
            # ------------------------------------------------------------
            # Здесь даём рекруту название его отряда.
            # Лучше бы сделать для этого сеттер (метод soldier)
            # ------------------------------------------------------------
            recruit.squad_name = self.name
            recruit.squad_name_translate = self.name_translate
            metadict_soldiers[recruit.uuid] = recruit
        return metadict_soldiers

    def set_ranks(self):
        """Раздаём должности солдатам, даём levelup лучшим.
        
        Как это работает:
        - В шаблоне отряда ищется самый малочисленный класс солдат (командиры)
        - Последовательно выбираются лучшие из списка рекрутов и их звание повышается.
        - Так командиром роты становится лучший по сумме параметров, а худшие остаются рядовыми.
        - Все командиры/сержанты/капралы получают levelup, чтобы соответствовать своим должностям.
        - Если их класс изменился, характеристики перетасовываются под новый класс (в методе levelup).
        """
        dict_squad = self.dict_squad.copy()
        metadict_reqruits = self.metadict_soldiers
        metadict_soldiers = {}
        for n in range(self.squad_number):
            # TODO: исправить баг
            # ------------------------------------------------------------
            # Тут костыль. Цикл прерывается, если должности закончились, а рекруты остались.
            # Это случается, если вызвать set_ranks заново, после срабатываения create_squad.
            # Один худший рекрут всегда теряется. Да и хрен с ним.
            # ------------------------------------------------------------
            #print(n, self.squad_number, dict_squad)
            if not dict_squad:
                break
            # Находим самое малочисленное звание и лучшего бойца:
            rank = min(dict_squad, key=lambda k: dict_squad[k])
            uuid = self.find_best()
            # Даём лучшему бойцу levelup до нового звания:
            recruit = metadict_reqruits[uuid]
            recruit.levelup(rank)
            metadict_soldiers[uuid] = recruit
            #print(recruit.level, recruit.abilityes, sum(recruit.abilityes.values()))
            # Убираем обработанные параметры рекрута:
            metadict_reqruits.pop(uuid)
            # Убираем занятую должность:
            dict_squad[rank] -=1
            if dict_squad[rank] <= 0:
                dict_squad.pop(rank)
        metadict_soldiers = OrderedDict(reversed(sorted(metadict_soldiers.items(),key=lambda x: x[1].level)))
        return metadict_soldiers

    def throw_squad_initiative(self):
        """Инициатива отряда = инициативы командира.
        
        Ранее была сумма инициативы командиров, но так честнее.
        """
        squad_initiative = 0
        for uuid,soldier in self.metadict_soldiers.items():
            if soldier.behavior == 'commander':
                squad_initiative += soldier.initiative
                break
        return squad_initiative

    def throw_squad_moral(self, enemy_recon, commanders_list, advantage = False, disadvantage = False):
        """Каждый командир даёт от -1 до +2 к морали отряда, как повезёт.
        
        Бросок морали = 1d20 + мод_харизмы + бонус_мастерства
        Сложность проверки = число_врагов/число_союзников * 10
        Если врагов и союзников поровну, сложность проверки = 10
        Если врагов вдвое больше, сложность проверки = 20
        - крит_успех 20 -- +2 мораль.
        - результат >10 -- +1 мораль.
        - результат <10 -- +0 мораль.
        #- крит_провал 0 -- -1 мораль.

        Офицеры дают больший бонус, чем сержанты:
        - сержант 3 lvl -- мораль x1
        - лейтенант 4 lvl -- мораль x2
        - капитан 5 lvl -- мораль x3

        Единицы морали и единицы опасности в danger_sense, это одно и то же.
        """
        if enemy_recon:
            # Число врагов относительно числа наших:
            # Например: 200/100 * 10 = 20 (это сложность броска морали)
            if enemy_recon['ally_strenght'] <= 0:
                enemy_recon['ally_strenght'] = 1
            morale_throw_DC = round(enemy_recon['enemy_strenght'] / enemy_recon['ally_strenght'] * 10)
        else:
            morale_throw_DC = 0
        commanders_list_uuids = [commander.uuid for commander in commanders_list]
        squad_moral = 0
        for uuid in commanders_list_uuids:
            commander_moral = 0
            commander = self.metadict_soldiers[uuid]
            morale_throw = dices.dice_throw_advantage('1d20', advantage, disadvantage)
            # TODO: здесь должне быть навык дипломатии/запугивания/обмана:
            result = morale_throw + commander.mods['charisma'] + commander.proficiency_bonus
            if morale_throw == 20:
                commander_moral += 2
            #elif morale_throw == 1:
            #    commander_moral -= 1
            elif result >= morale_throw_DC:
                commander_moral += 1
            elif result < morale_throw_DC:
                commander_moral += 0
            if commander.level <= 3:
                squad_moral += commander_moral
            elif commander.level == 4:
                squad_moral += commander_moral * 2
            elif commander.level > 4:
                squad_moral += commander_moral * 3
        #print(self.ally_side, enemy_recon, morale_throw_DC, squad_moral)
        return squad_moral

    def gen_ability_stat(self, metadict_soldiers):
        """Показывает распределение параметров по отряду.
        
        Сколько бойцов с силой 10, сколько с силой 11 и т.д.
        """
        dict_ability_stat = {}
        for soldier in metadict_soldiers.values():
            if soldier.behavior != 'mount':
                for ability, value in soldier.abilityes.items():
                    key = (ability, value)
                    if not key in dict_ability_stat:
                        dict_ability_stat[key] = 1
                    elif key in dict_ability_stat:
                        dict_ability_stat[key] += 1
        dict_ability_stat = OrderedDict(reversed(sorted(dict_ability_stat.items(),key=lambda x: x)))
        metadict_ability_stat = {}
        for key, number in dict_ability_stat.items():
            ability, value = key
            if not ability in metadict_ability_stat:
                metadict_ability_stat[ability] = {value:number}
            elif ability in metadict_ability_stat:
                metadict_ability_stat[ability][value] = number
        return metadict_ability_stat

    def print_ability_stat(self, metadict_ability_stat):
        """Вывод статистики параметров в виде графика."""
        import matplotlib.pyplot as plt
        abilities = tuple(metadict_ability_stat.keys())
        for ability, value_dict  in metadict_ability_stat.items():
            x_list = []
            y_list = []
            for value, number in value_dict.items():
                x_list.append(value)
                y_list.append(number)
            plt.scatter(x_list,y_list)
            plt.plot(x_list,y_list)
        plt.legend(abilities, loc='upper left')
        plt.show()
class database_stat():
    """Описание класса.
    
    """
    database = database.database()
    # Опыт от показателя опасности:
    challenge_rating_experience_dict = {
        '-': 10,
        '0': 10,
        '1/8': 25,
        '1/4': 50,
        '1/2': 100,
        '1': 200,
        '2': 450,
        '3': 700,
        '4': 1100,
        '5': 1800,
        '6': 2300,
        '7': 2900,
        '8': 3900,
        '9': 5000,
        '10': 5900,
        '11': 7200,
        '12': 8400,
        '13': 10000,
        '14': 11500,
        '15': 13000,
        '16': 15000,
        '17': 18000,
        '18': 20000,
        '19': 22000,
        '20': 25000,
        '21': 33000,
        '22': 41000,
        '23': 50000,
        '24': 62000,
        '25': 75000,
        '26': 90000,
        '27': 105000,
        '28': 120000,
        '29': 135000,
        '30': 155000,
    }

    def print_squads_names(self):
        """Имена отрядов из базы данных."""
        print('Database [{n}]: {squads}'.format(
            n=len(self.database.print_squads()),
            squads=self.database.print_squads(),
        ))

    def test_squads(self):
        """Данные по отрядам из БД.
        
        """
        metadict_squads_stat = {}
        #trophy_dict = {}
        # TODO: Сохраняй это в словаре (что уже сделано). А вывод потом.
        # Ключи словаря -- кортежи (bluefor, squad_name)
        print(
            '[1/1 -- командиры] [100/100 -- боеспособные] [c:0 -- пленные] [i:0 -- калеки] [d:0 -- погибшие]'
        )
        print(
            '--------------------------------------------------------------------------------'
        )
        for squad_name in self.database.print_squads():
            squad = squad_generation()
            squad.load_squad_from_DB(squad_name, get_all=True)
            for soldier in squad.metadict_soldiers.values():
                soldier.set_actions_base(squad)
            squad.victories = sum([soldier.__dict__.get('victories',0) for soldier\
                in squad.metadict_soldiers.values()])
            squad.experience = sum([soldier.__dict__.get('experience',0) for soldier\
                in squad.metadict_soldiers.values()])
            squad.hitpoints_max = sum([soldier.hitpoints_max for soldier\
                in squad.metadict_soldiers.values()])
            squad.hitpoints_new = sum([soldier.hitpoints for soldier\
                in squad.metadict_soldiers.values()\
                if not soldier.hitpoints <= 0])
            squad.soldiers_number = len([soldier for soldier\
                in squad.metadict_soldiers.values()\
                if not soldier.behavior == 'mount'
                and not soldier.__dict__.get('mechanism')])
            squad.soldiers_number_ready = len([soldier for soldier\
                in squad.metadict_soldiers.values()\
                if soldier.hitpoints >= soldier.hitpoints_max / 2\
                and not soldier.__dict__.get('mechanism')\
                and not soldier.behavior == 'mount'])
            squad.commanders_number = len([soldier for soldier\
                in squad.metadict_soldiers.values()\
                if soldier.behavior == 'commander'
                and not soldier.__dict__.get('mechanism')])
            squad.commanders_number_ready = len([soldier for soldier\
                in squad.metadict_soldiers.values()\
                if soldier.behavior == 'commander'
                and soldier.hitpoints >= soldier.hitpoints_max / 3
                and not soldier.__dict__.get('mechanism')])
            dict_dead = {}
            dict_disabled = {}
            dict_capture = {}
            dict_fall = {}
            # Стоимость пополнения, по стоимости снаряжения:
            squad.reinforce_cost = 0
            # Стоимость трофеев и потерянного снаряжения:
            squad.trophy_cost = 0
            squad.drop_items_cost = 0
            squad.drop_ammo_cost = 0
            # Словари трофеев и потерянного снаряжения:
            squad.trophy_dict = {}
            squad.drop_items_dict = {}
            for soldier in squad.metadict_soldiers.values():
                squad.trophy_dict = dict(Counter(squad.trophy_dict)\
                        + Counter(soldier.trophy_items_dict))
                squad.drop_items_dict = dict(Counter(squad.drop_items_dict)\
                        + Counter(soldier.drop_items_dict))
                if hasattr(soldier, 'death') and soldier.death == True\
                        and not soldier.behavior == 'mount':
                    if not soldier.rank in dict_dead:
                        dict_dead[soldier.rank] = 1
                    elif soldier.rank in dict_dead:
                        dict_dead[soldier.rank] += 1
                    squad.reinforce_cost += soldier.unit_cost['equipment_cost']
                    #trophy_cost += soldier.unit_cost['equipment_cost']
                    #trophy_dict = dict(Counter(trophy_dict) + Counter(soldier.equipment_weapon))
                elif hasattr(soldier, 'disabled') and soldier.disabled == True\
                        and not soldier.behavior == 'mount':
                    if not soldier.rank in dict_disabled:
                        dict_disabled[soldier.rank] = 1
                    elif soldier.rank in dict_disabled:
                        dict_disabled[soldier.rank] += 1
                    # Стоимость лечения у жрецов -- 10 эфесов/100 солдат
                    squad.reinforce_cost += 0.1
                elif hasattr(soldier, 'captured') and soldier.captured == True\
                        and not soldier.behavior == 'mount':
                    if not soldier.rank in dict_capture:
                        dict_capture[soldier.rank] = 1
                    elif soldier.rank in dict_capture:
                        dict_capture[soldier.rank] += 1
                    #trophy_cost += soldier.unit_cost['equipment_cost']
                    #trophy_dict = dict(Counter(trophy_dict) + Counter(soldier.equipment_weapon))
                elif soldier.hitpoints <= 0:
                    if not soldier.rank in dict_fall:
                        dict_fall[soldier.rank] = 1
                    elif soldier.rank in dict_fall:
                        dict_fall[soldier.rank] += 1
            dict_dead = OrderedDict(
                reversed(sorted(dict_dead.items(), key=lambda x: x)))
            dict_disabled = OrderedDict(
                reversed(sorted(dict_disabled.items(), key=lambda x: x)))
            dict_capture = OrderedDict(
                reversed(sorted(dict_capture.items(), key=lambda x: x)))
            dict_fall = OrderedDict(
                reversed(sorted(dict_fall.items(), key=lambda x: x)))
            # Словарь израсходованной аммуниции (кроме рун):
            squad.drop_ammo_dict = {}
            for item, number in squad.drop_items_dict.items():
                if item in soldier.metadict_items:
                    if soldier.metadict_items[item].get('ammo') == True\
                            or soldier.metadict_items[item].get('weapon') == True\
                            or soldier.metadict_items[item].get('shield') == True\
                            or soldier.metadict_items[item].get('armor') == True:
                        squad.drop_ammo_dict[item] = number
            # Стоимость трофеев и потерянного снаряжения:
            squad.trophy_cost = round(
                calculate_equipment_cost(squad.trophy_dict,
                                         soldier.metadict_items))
            squad.drop_items_cost = round(
                calculate_equipment_cost(squad.drop_items_dict,
                                         soldier.metadict_items))
            squad.drop_ammo_cost = round(
                calculate_equipment_cost(squad.drop_ammo_dict,
                                         soldier.metadict_items))
            squad.reinforce_cost = round(squad.reinforce_cost)
            # Боеспособность отряда:
            if squad.soldiers_number_ready >= squad.soldiers_number / 2\
                    and squad.commanders_number_ready >= 1:
                squad_combativity = '●'
            else:
                squad_combativity = '○'
            #print('{s} [{c}/{c_max}] [{n:>3}/{n_max:<3}] [capt:{cap:<2}] [dead:{dead:<2}] [dis:{dis:<2}] {name}'.format(
            print(
                '{s} [{c}/{c_max}] [{n:>3}/{n_max:<3}] [c:{cap:<2}] [i:{dis:<2}] [d:{dead:<2}] {name} (exp {exp})'
                .format(
                    #print('{s} [{c}/{c_max}] [{n:>3}/{n_max:<3}] [v:{vic:<2}] [c:{cap:<2}] [i:{dis:<2}] [d:{dead:<2}] {name}'.format(
                    #print('{s} [{c}/{c_max}] [{n:>3}/{n_max:<3}] [c:{cap:<2}] [d:{dead:<2}] [r:{re:<2}] {name}'.format(
                    s=squad_combativity,
                    n=squad.soldiers_number_ready,
                    n_max=squad.soldiers_number,
                    c=squad.commanders_number_ready,
                    c_max=squad.commanders_number,
                    name=squad.name,
                    hp=squad.hitpoints_new,
                    hp_max=squad.hitpoints_max,
                    vic=squad.victories,
                    re=round(squad.reinforce_cost),
                    exp=round(squad.experience),
                    #trophy = round(trophy_cost),
                    dead=sum(dict_dead.values()),
                    dis=sum(dict_disabled.values()),
                    cap=sum(dict_capture.values()),
                    fall=sum(dict_fall.values()),
                ))
            print(
                '--------------------------------------------------------------------------------'
            )
            print('* Восполнение потерь (солдат): {re} эфес'.format(
                re=squad.reinforce_cost))
            print('* Восполнение потерь (снаряжения): {ammo} эфес'.format(
                ammo=squad.drop_ammo_cost))
            print('* Трофеи солдат: {trophy} эфес'.format(
                trophy=squad.trophy_cost))
            for key, el in dict_dead.items():
                print('dead', el, key)
            for key, el in dict_disabled.items():
                print('disabled', el, key)
            for key, el in dict_capture.items():
                print('captured', el, key)
            #for key, el in dict_fall.items():
            #    print('fall', el, key)
            metadict_squads_stat[squad_name] = squad
            print('Потери:', squad.drop_ammo_dict)
            print('Трофеи:', squad.trophy_dict)
            print(
                '--------------------------------------------------------------------------------'
            )
        # Список трофеев:
        #for key, value in trophy_dict.items():
        #    print(key, value)
        return metadict_squads_stat