Example #1
0
    def __init__(self, setting):
        self.setting = setting
        self.__logger = LoggerPrint(self.setting)
        self.log = self.__logger.printLogToSystem()

        self.times = 0
        self.color1, self.color2 = 'red', 'black'
Example #2
0
    def __init__(self, setting):
        self.setting = setting
        self.logger = LoggerPrint(self.setting)
        self.log = self.logger.printLogToSystem()
        # 初始化混音器
        pygame.mixer.init()

        self.log.info("初始化混音器成功!")
Example #3
0
 def __init__(self, all_pieces, player1Color):
     self.all_pieces = all_pieces
     self.player1_color = player1Color
     #
     self.settings = Settings()
     self.game_func = GameFunction(self.settings)
     self.log = LoggerPrint(self.settings).printLogToSystem(False)
 def __init__(self, setting):
     self.setting = setting
     self.logger = LoggerPrint(self.setting).printLogToSystem()
class GameFunction():
    """
    游戏逻辑的所有方法,不涉及到界面显示内容
    """
    def __init__(self, setting):
        self.setting = setting
        self.logger = LoggerPrint(self.setting).printLogToSystem()

    # 将红黑棋子对应的图片,关联起来,存放在字典中
    def _get_all_pieces(self, piece_flag):
        pieces = []
        for piece in self.setting.pieces_list:
            # value = f"{self.setting.pieces_front}{piece_flag}_{piece}{self.setting.pieces_noun}"
            if piece in ['shi', 'xiang', 'ma', 'ju', 'pao']:
                for i in range(1, 3):
                    pieces.append(f"{piece_flag}_{piece}{str(i)}")
            elif piece == 'zu':
                for i in range(1, 6):
                    pieces.append(f"{piece_flag}_{piece}{str(i)}")
            else:
                pieces.append(f"{piece_flag}_{piece}1")
        return pieces

    # 初始化棋子配置
    def box_pieces(self):
        # 获得所有的红黑棋子的dict
        pieces = self._get_all_pieces('red')
        pieces_black = self._get_all_pieces('black')
        pieces += pieces_black
        all_pieces = {}
        for i in range(8):
            for j in range(4):
                # 随机抽取key放入boxid中,并初始化box的状态为False
                random_key = random.choice(pieces)
                all_pieces[f"box_{i}_{j}"] = {'box_key': random_key, 'state': False}
                pieces.remove(random_key)
        return all_pieces

    # 获取鼠标位置所对应的方格id
    def get_box_xy(self, event_x, event_y):
        # 确定鼠标的有效矩形位置
        min_area_x = self.setting.piece_first_x
        min_area_y = self.setting.piece_first_y
        max_area_x = min_area_x + 8 * self.setting.piece_size
        max_area_y = min_area_y + 4 * self.setting.piece_size
        # 确认鼠标是在棋盘上有效的矩形范围之内
        if (min_area_x < event_x < max_area_x) and (min_area_y < event_y < max_area_y):
            mouse_x_not = (i * 100 + min_area_x for i in range(1, 9))
            mouse_y_not = (i * 100 + min_area_y for i in range(1, 5))
            # 鼠标不能在棋盘线上
            if (event_x not in mouse_x_not) and (event_y not in mouse_y_not):
                # 计算当前鼠标坐标所在的方格坐标
                box_x = int((event_x - min_area_x) / 100)
                box_y = int((event_y - min_area_y) / 100)
                return (box_x, box_y)

    # 获取棋子所在方格左上角的坐标
    # def get_box_local_xy(self, box_x, box_y):
    #     box_local_x = box_x * self.setting.piece_size + self.setting.piece_first_x
    #     box_local_y = box_y * self.setting.piece_size + self.setting.piece_first_y

    # 加载棋子对应的图片
    def get_piece_image(self):
        pieces_dict = {}
        for piece_name in self.setting.pieces_list:
            pieces_dict[f"red_{piece_name}"] = f"{self.setting.pieces_front}red_{piece_name}{self.setting.pieces_noun}"
            pieces_dict[f"black_{piece_name}"] = f"{self.setting.pieces_front}black_{piece_name}{self.setting.pieces_noun}"
        return pieces_dict

    # 两个棋子之间的比较
    def piece_VS_piece(self, box1_xy, box2_xy, all_pieces):
        '''
        :param box1_xy:
        :param box2_xy:
        :param all_pieces:
        :return: [True|False|None, '原因', True|False]
                True|False|None:表示box1和box2的比较结果
                '原因':表示原因,便于提示失败的原因,也可指示成功的提示
                True|False:表示对于该原因,对后续AI走棋获取该走棋步骤时,是否为需要添加的走棋步骤
        '''
        value_list = self.setting.pieces_list
        box1_x = int(box1_xy.split('_')[1])
        box1_y = int(box1_xy.split('_')[2])
        box2_x = int(box2_xy.split('_')[1])
        box2_y = int(box2_xy.split('_')[2])
        box1_name = all_pieces[box1_xy]['box_key']
        box2_name = all_pieces[box2_xy]['box_key']
        box1_color = box1_name.split('_')[0]
        box1_value = box1_name.split('_')[1]
        box1_value = box1_value[:-1]
        box1_value_index = value_list.index(box1_value)
        # 如果box1的位置比box2的位置大,则交换他们的值
        if box1_y > box2_y:
            box1_y, box2_y = box2_y, box1_y
        if box1_x > box2_x:
            box1_x, box2_x = box2_x, box1_x
        # box2如果为空,则认为第二次选择了棋盘空格,不为空则需要取box2的值与box1比较
        if box2_name is not None:
            box2_color = box2_name.split('_')[0]
            if box2_color == box1_color:
                # self.logger.info("false原因:两个棋子在同一个方阵")
                return [False, 'color', False]
            box2_value = box2_name.split('_')[1]
            box2_value = box2_value[:-1]
            box2_value_index = value_list.index(box2_value)
        else:
            return self._other_vs_piece(box1_x, box1_y, box2_x, box2_y, piece_equal=False)
        # 如果两个棋子相同
        if box1_value_index == box2_value_index:
            if box1_value == 'pao':
                # '炮'相同时的吃法:
                # 中间有且只有一个棋子,中间棋子不论打没打开都可以,没有距离限制
                return self._pao_vs_piece(box1_x, box1_y, box2_x, box2_y, all_pieces, piece_equal=False)
            else:
                # 其他相同棋子的吃法:
                # 只能相邻位置两个棋子,最后也是两个棋子同时失去
                return self._other_vs_piece(box1_x, box1_y, box2_x, box2_y, piece_equal=True)
        # 如果两个棋子不相同
        else:
            if box1_value == 'pao':
                # '炮'的吃法:
                # 1、中间必须有且只有一个棋子,才能吃到对方棋子,没有距离限制;
                # 2、炮没有大小吃法限制,上到将,下到卒都可以吃;
                # 3、炮移动只能相邻的格子移动,不能跳着移动;
                return self._pao_vs_piece(box1_x, box1_y, box2_x, box2_y, all_pieces, piece_equal=False)
            else:
                # 其他的棋子的吃法:
                # 1、大吃小(将(帅)>士>(象)相>马>车>炮和卒(兵)),两两相同则一起吃掉;
                # 2、炮和卒(兵)、炮和将(帅)相互不能吃,任何棋子都可以吃炮,除了卒(兵)、将(帅)外;
                # 3、任何棋子都可以吃卒(兵),而卒(兵)只吃对方的帅(将);
                # 4、棋子只能相邻的吃,而且一次只能走一步,吃一个棋子,炮除外
                if box1_value_index < box2_value_index:
                    # 大吃小,除非jiang和zu或pao同时出现
                    if box1_value == 'jiang' and box2_value == 'zu':
                        # self.logger.info("false原因:jiang在和zu比较")
                        return [False, 'jiang_zu', True]
                    elif box1_value == 'jiang' and box2_value == 'pao':
                        # self.logger.info("false原因:jiang在和pao比较")
                        return [False, 'jiang_pao', False]
                    else:
                        return self._other_vs_piece(box1_x, box1_y, box2_x, box2_y, piece_equal=False)
                elif box1_value_index > box2_value_index:
                    # 最后一种情况:zu只能吃jiang
                    if box1_value == 'zu' and box2_value == 'jiang':
                        return self._other_vs_piece(box1_x, box1_y, box2_x, box2_y, piece_equal=False)
                    elif box1_value == 'zu' and box2_value == 'pao':
                        # self.logger.info("false原因:zu在和pao比较")
                        return [False, 'zu_pao', False]
                    else:
                        # self.logger.info("false原因:box1比box2还小")
                        return [False, 'box1<box2', True]

    # pao的比较
    def _pao_vs_piece(self, box1_x, box1_y, box2_x, box2_y, all_pieces, piece_equal=True):
        if box1_x == box2_x and box2_y - box1_y > 1:
            between_state_have = 0
            for i in range(box1_y + 1, box2_y):
                if all_pieces[f"box_{box1_x}_{i}"]['state'] is not None:
                    between_state_have += 1
                if between_state_have > 1:
                    break
            if between_state_have == 1:
                if piece_equal is True:
                    # self.logger.info("None:box1和box2相同,都是pao")
                    return [None, 'box1=box2', True]
                else:
                    return [True, 'success', True]
            else:
                # self.logger.info("false原因:box1和box2之间,在y轴上没有棋子,或者有大于2个的棋子")
                return [False, 'pao_between', False]
        elif box1_y == box2_y and box2_x - box1_x > 1:
            between_state_have = 0
            for i in range(box1_x + 1, box2_x):
                if all_pieces[f"box_{i}_{box1_y}"]['state'] is not None:
                    between_state_have += 1
                if between_state_have > 1:
                    break
            if between_state_have == 1:
                if piece_equal is True:
                    # self.logger.info("None:box1和box2相同,都是pao")
                    return [None, 'box1=box2', True]
                else:
                    return [True, 'success', True]
            else:
                # self.logger.info("false原因:box1和box2之间,在x轴上没有棋子,或者有大于2个的棋子")
                return [False, 'pao_between', False]
        else:
            # self.logger.info("false原因:box1和box2不在同一条x轴或y轴上")
            return [False, 'box1_noline_box2', False]

    # 其他棋子的比较
    def _other_vs_piece(self, box1_x, box1_y, box2_x, box2_y, piece_equal=True):
        if (box1_x == box2_x and box2_y - box1_y == 1) or (box1_y == box2_y and box2_x - box1_x == 1):
            if piece_equal is True:
                # self.logger.info("None:box1和box2相同")
                return [None, 'box1=box2', True]
            else:
                return [True, 'success', True]
        else:
            # self.logger.info("false原因:box1和box2不在同一条x轴或y轴上")
            return [False, 'box1_noline_box2', False]

    # 游戏结束判断
    def is_game_over(self, all_pieces, nowPlayer, player1Color):
        # 循环all_pieces中的state得到棋子状态
        true_count = 0
        none_count = 0
        new_pieces = {}
        for key, value in all_pieces.items():
            for key1, value1 in value.items():
                if key1 == 'state':
                    if value1 is True:
                        true_count += 1
                        new_pieces[all_pieces[key]['box_key']] = key
                    elif value1 is False:
                        # 如果查到state的状态为false,立即return
                        return 'none'
                    elif value1 is None:
                        none_count += 1
        self.logger.info(f"true_count: {true_count}")
        self.logger.info(f"none_count: {none_count}")
        self.logger.info(f"new_pieces: {new_pieces}")
        # 如果allpieces全部为none,则为平局
        if none_count == 32:
            return 'tie'
        else:
            # 只有一个棋子,则取棋子的颜色return
            if true_count == 1:
                key_list = list(new_pieces.keys())
                box_color = key_list[0].split('_')[0]
                return box_color
            # 有多个棋子,则要分开判断
            else:
                # 取红黑棋子分别占有多少
                value_list = self.setting.pieces_list
                red_count, black_count = 0, 0
                box_count = len(new_pieces)
                for key, value in new_pieces.items():
                    box_color = key.split('_')[0]
                    if box_color == 'red':
                        red_count += 1
                    else:
                        black_count += 1
                self.logger.info(f"red_count: {red_count}")
                self.logger.info(f"black_count: {black_count}")
                self.logger.info(f"box_count: {box_count}")
                # 如果全部为红色或者黑色,则return
                if red_count == box_count:
                    return 'red'
                elif black_count == box_count:
                    return 'black'
                # 总数为2,红黑棋子各占1个
                elif box_count == 2 and red_count == 1:
                    red_x = 0
                    red_y = 0
                    red_value = ''
                    black_x = 0
                    black_y = 0
                    black_value = ''
                    for key, value in new_pieces.items():
                        box_color = key.split('_')[0]
                        box_value = key.split('_')[1]
                        if box_color == 'red':
                            red_x = int(value.split('_')[1])
                            red_y = int(value.split('_')[2])
                            red_value = box_value[:-1]
                        else:
                            black_x = int(value.split('_')[1])
                            black_y = int(value.split('_')[2])
                            black_value = box_value[:-1]
                    red_value_index = value_list.index(red_value)
                    black_value_index = value_list.index(black_value)
                    # 如果红黑双方棋子相同或者是不能相互吃掉的棋子,则为平局
                    if red_value == black_value or \
                            (red_value in ['jiang', 'pao'] and black_value in ['jiang', 'pao']) or \
                            (red_value in ['pao', 'zu'] and black_value in ['pao', 'zu']):
                        return 'tie'
                    # 当前玩家和玩家方阵为红方,且红方的棋子比黑方的棋子大,则他们相邻比较的时候就会是平局,红方无法吃掉黑方
                    if (nowPlayer == self.setting.player1_name and player1Color == 'red') or \
                            (nowPlayer == self.setting.player2_name and player1Color == 'black'):
                        if red_value_index > black_value_index:
                            if (red_x == black_x and fabs(red_y - black_y) == 1) or (
                                    red_y == black_y and fabs(red_x - black_x) == 1):
                                return 'tie'
                    # 黑方也是一样
                    elif (nowPlayer == self.setting.player1_name and player1Color == 'black') or \
                            (nowPlayer == self.setting.player2_name and player1Color == 'red'):
                        if red_value_index < black_value_index:
                            if (red_x == black_x and fabs(red_y - black_y) == 1) or (
                                    red_y == black_y and fabs(red_x - black_x) == 1):
                                return 'tie'
                # 总数>2,只判断一方只为1个的情况
                elif box_count > 2:
                    # 红方只有一个棋子,如果这个棋子在棋盘上黑方有其他棋子能吃掉它,则红方就一定会输
                    # 相反如果红方的这个棋子在棋盘上黑方没有棋子能吃掉它,那么就只能是平局了
                    if red_count == 1:
                        return self._one_vs_more(new_pieces, 'red', value_list)
                    elif black_count == 1:
                        return self._one_vs_more(new_pieces, 'black', value_list)
                    else:
                        return 'none'
        # return 'none'

    # 判断某一方只有一个棋子时
    def _one_vs_more(self, new_pieces, one_color, value_list):
        index_list = []
        for key, value in new_pieces.items():
            box_color = key.split('_')[0]
            box_value = key.split('_')[1]
            if box_color == one_color:
                one_value = box_value[:-1]
                one_index = value_list.index(one_value)
            else:
                more_value = box_value[:-1]
                index_list.append(value_list.index(more_value))
        # 红方只有一个pao,黑方也只有pao和zu,则为平局
        if one_index == 5 and [0, 1, 2, 3, 4] not in index_list and len(index_list) < 4:
            return 'tie'
        count = 0
        for index in index_list:
            if one_index < index:
                # 要排除jiang和zu同时存在的情况
                if one_index == 0 and index == 6:
                    return 'none'
                count += 1
            else:
                return 'none'
        # 如果对方所有的棋子都比这一个棋子小,则为平局
        if count == len(index_list):
            return 'tie'
Example #6
0
#!/usr/bin/python3
# encoding: utf-8

import timeit
from time import sleep
from loggerPrint import LoggerPrint
from settings import Settings

logg = LoggerPrint(Settings()).printLogToSystem(False)


def clock(func):
    def clocked(*args, **kwargs):
        t0 = timeit.default_timer()
        result = func(*args, **kwargs)
        elapsed = timeit.default_timer() - t0
        name = func.__name__
        logg.info('%s 耗时 [%0.8fs]' % (name, elapsed))
        return result

    return clocked
Example #7
0
class SeachMove():
    def __init__(self, setting):
        self.setting = setting
        self.logg = LoggerPrint(self.setting).printLogToSystem(False)

    # 寻找AI的下一步走棋
    @clock
    def search_next_move(self, all_pieces, player1Color, depth=1):
        # 取得当前player2的所有走棋步骤内容
        all_moves = Moves(all_pieces, player1Color).generate_all_moves()
        #
        best_move = None
        # allmoves为空,表明要么无棋子可走(输了),要么打开的棋子上没有合适的棋子可走
        if len(all_moves) == 0:
            self.logg.info('当前的allmoves为None!!')
            # 获得双方剩余棋子的数量
            dp = DataPercent(all_pieces)
            red_count, black_count = dp.pieces_perc()
            # 根据剩余棋子数量判断是否为0
            if red_count == 0 or black_count == 0:
                self.logg.info(f"一方棋子数量为0,best_move为None!!")
            else:
                # 不为0还需判断是否有未打开棋子,如果当前还有棋子未打开,则打开循环到的第一个未打开的棋子
                box_to = None
                for key, value in all_pieces.items():
                    if value['state'] is False:
                        box_to = key
                        break
                # box_to不为空,将box_to传递给best_move
                if box_to is not None:
                    best_move = MoveNodes(None, box_to, '打开', None, box_to, None)
                    self.logg.info(f"打开循环到的第一个未打开的棋子best_move: {box_to}")
                # box_to为空,表示所有棋子都已打开而且没有合适棋子可走,玩家2自动认输
                else:
                    pass
        # allmoves不为空
        else:
            self.logg.info(f"当player1color为 [{player1Color}] 时, allmove的值:")
            for move in all_moves:
                # 基于当前的move计算下一步的走棋,并返回最高得分
                self.logg.info(
                    f"{move.box_name_from}===>>>{move.box_from}===>>>{move.box_action}===>>>{move.box_name_to}===>>>{move.box_to}===>>>{move.box_res}===>>>{move.score}")
                move.score = self._seach_other_moves(all_pieces, player1Color, depth, move)
                self.logg.info(f"最终的score:{move.score}")
                # 把得分最高的走棋给best_move
                if best_move is None or move.score >= best_move.score:
                    best_move = move
        return best_move

    # 为下一个玩家寻找行棋内容
    def _seach_other_moves(self, all_pieces, player1Color, depth, move):
        # 设置一个all_pieces的替身,好还原all_pieces的值
        all_pieces_1 = deepcopy(all_pieces)
        # 根据行棋状态修改all_pieces_1的值
        if move.box_action == '吃棋':
            if move.box_res == 'box1=box2':
                all_pieces_1[move.box_from]['box_key'] = None
                all_pieces_1[move.box_from]['state'] = None
                all_pieces_1[move.box_to]['box_key'] = None
                all_pieces_1[move.box_to]['state'] = None
            elif move.box_res == 'success':
                all_pieces_1[move.box_to]['box_key'] = all_pieces_1[move.box_from]['box_key']
                all_pieces_1[move.box_to]['state'] = True
                all_pieces_1[move.box_from]['box_key'] = None
                all_pieces_1[move.box_from]['state'] = None
        elif move.box_action == '移动':
            all_pieces_1[move.box_to]['box_key'] = all_pieces_1[move.box_from]['box_key']
            all_pieces_1[move.box_to]['state'] = True
            all_pieces_1[move.box_from]['box_key'] = None
            all_pieces_1[move.box_from]['state'] = None
        elif move.box_action == '打开':
            # box_action == '打开' 时,不能给出打开这个棋子的信息,只能给出打开当前棋子的价值,同时将depth=0,给出得分
            depth = 0
        #
        if depth == 0:
            return move.score
        # depth不为0,更换player1Color的颜色方阵,反过来计算如果player1是player2的话,走棋都有哪些内容
        player1Color = 'black' if player1Color == 'red' else 'red'
        #
        score = 10
        moves = Moves(all_pieces_1, player1Color)
        all_moves = moves.generate_all_moves()
        self.logg.info(f"player2反置:当player1color为 [{player1Color}] 时, allmove的值:")
        for move_1 in all_moves:
            # 回调该函数自己,同时depth-1
            self.logg.info(
                f"player2反置:{move_1.box_name_from}===>>>{move_1.box_from}===>>>{move_1.box_action}===>>>"
                f"{move_1.box_name_to}===>>>{move_1.box_to}===>>>{move_1.box_res}===>>>{move_1.score}")
            score = max(score, self._seach_other_moves(all_pieces_1, player1Color, depth-1, move_1))
        if score >= 1000:
            score = 0
        move.score += score
        # 还原all_pieces的值,保证下一个循环用到的值还是原来的all_pieces
        all_pieces_1 = deepcopy(all_pieces)
        #
        return move.score
Example #8
0
class PlayMusic():
    # 设置音乐播放标志:0表示自动播放,1表示手动介入
    _MUSIC_PLAY_FLAG = 0

    def __init__(self, setting):
        self.setting = setting
        self.logger = LoggerPrint(self.setting)
        self.log = self.logger.printLogToSystem()
        # 初始化混音器
        pygame.mixer.init()

        self.log.info("初始化混音器成功!")

    # 播放背景音乐
    def play_bg_music(self, music_file=None):
        # 如果music_file有值,则播放选中的音乐
        if music_file:
            pygame.mixer.music.stop()
            self.log.info(f"切换的背景音乐为: {music_file}")
        # 没有值则随机播放
        else:
            music_list = self.setting.music_list
            music_file = random.sample(music_list, 1)
            music_file = music_file[0]
            self.log.info(f"随机播放的音乐为: {music_file}")
        pygame.mixer.music.load(f'mids/{music_file}')
        pygame.mixer.music.play()
        PlayMusic._MUSIC_PLAY_FLAG = 0
        self.is_not_busy()

    # 播放一首音乐完成之后,自动随机播放下一首
    def is_not_busy(self):
        mixer_state = pygame.mixer.get_init()
        if mixer_state:
            # 如果播放器没有工作,则调用播放背景音乐功能方法
            if pygame.mixer.music.get_busy(
            ) == False and PlayMusic._MUSIC_PLAY_FLAG == 0:
                self.play_bg_music()
            else:
                if PlayMusic._MUSIC_PLAY_FLAG == 0:
                    # 定时器,没隔1s检查一次播放器是否有在播放
                    t = threading.Timer(1, self.is_not_busy)
                    t.start()
        else:
            pass

    # 手动停止背景音乐播放
    def stop_bg_music(self):
        mixer_state = pygame.mixer.get_init()
        if mixer_state:
            pygame.mixer.music.stop()
            self.log.info('背景音乐播放停止!')
            PlayMusic._MUSIC_PLAY_FLAG = 1

    # 加载操作棋子时的音效
    def load_play_sound(self, sound):
        soundobj = pygame.mixer.Sound(sound)
        soundobj.play()

    # 退出游戏的时候,需要先退出pygame和mixer播放器
    def quit_music(self):
        pygame.mixer.music.fadeout(1000)
        pygame.mixer.quit()
        pygame.quit()
        self.log.info("混音器销毁成功!pygame退出!")
Example #9
0
class Commmon():
    def __init__(self, setting):
        self.setting = setting
        self.__logger = LoggerPrint(self.setting)
        self.log = self.__logger.printLogToSystem()

        self.times = 0
        self.color1, self.color2 = 'red', 'black'

    # 获取当前系统的名称
    def get_system_name(self):
        system_flag = 0
        uname = platform.uname().system
        system_name = platform.platform().split('-')[0]
        if uname == 'Darwin' or system_name == 'Darwin':
            # mac系统加载mac配置,设置flag为1
            system_flag = 1
        elif uname == 'Windows' or system_name == 'Windows':
            # windows系统加载默认setting设置,设置flag为2
            system_flag = 2
        else:
            system_flag = 3
        self.log.info(f"当前系统为:{uname}")
        return system_flag

    # 压缩图片,改变图片的大小
    def change_img(self, img, width=100, height=100):
        if isinstance(img, str):
            piece1 = Image.open(img)
            piece2 = piece1.resize((width, height))
            changed_img = ImageTk.PhotoImage(piece2)
            return changed_img
        elif isinstance(img, dict):
            img_dict = {}
            for key, value in img.items():
                piece1 = Image.open(value)
                piece2 = piece1.resize((width, height))
                changed_img = ImageTk.PhotoImage(piece2)
                img_dict[key] = changed_img
            return img_dict
        else:
            raise ImgNotFound('传入图片格式不正确或者图片不存在!')

    # 读取文件
    def read_file(self, filename, flag=None):
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                if flag is None:
                    return f.read()
                elif flag == 'info':
                    return f.readlines()
        except Exception:
            self.log.exception(f'读取{filename}文件异常!')

    # 写入info文件
    def write_file(self, filename, write_value):
        try:
            if isinstance(write_value, str):
                with open(filename, 'ab+') as f:
                    writestr = (write_value + os.linesep).encode('utf-8')
                    f.write(writestr)
            elif isinstance(write_value, list):
                with open(filename, 'w+', encoding='utf-8') as f:
                    f.writelines(write_value)
        except Exception:
            self.log.exception(f'写入{filename}文件异常!')

    # 获取当前系统时间,格式化后添加到文件名称中
    def format_now_time(self):
        ntime = time.strftime('_%Y_%m_%d_%H_%M_%S')
        return ntime

    # 获取当前系统时间
    def get_now_time(self):
        ntime = time.strftime('%Y-%m-%d %H:%M:%S')
        return ntime

    # 计算两个时间之间的时间差,返回str
    def how_long_time(self, begintime, endtime):
        howlongdays = (endtime - begintime).days
        howlongsecs = (endtime - begintime).seconds
        hours = int(howlongsecs / 3600)
        mins = int((howlongsecs % 3600) / 60)
        secs = (howlongsecs % 3600) % 60
        how_long = ''
        if howlongdays != 0:
            howlongdays = '%s天' % (str(howlongdays))
            how_long += howlongdays
        if hours != 0:
            hours = '%s小时' % (str(hours))
            how_long += hours
        if mins != 0:
            mins = '%s分' % (str(mins))
            how_long += mins
        if secs != 0:
            secs = '%s秒' % (str(secs))
            how_long += secs
        return how_long

    # 改变字体颜色
    def change_font_color(self):
        if self.times <= 5:
            self.color1, self.color2 = self.color2, self.color1
            self.times += 1
            t = threading.Timer(1, self.change_font_color)
            t.start()
        print(
            f"第 {self.times} 次:color1, color2 = {self.color1}, {self.color2}")