def knockoutScenario(plrs, FOLDER):
    # 屏蔽AI自带print
    class null_stream:
        def read(*args):
            pass

        def write(*args):
            pass

        def flush(*args):
            pass
    sys.stdout = null_stream
    
    # 设置比赛参数
    GAMES = 10    # 作为先后手各比赛场数,总场次 2 * GAMES
    HALFWIDTH, HEIGHT, TIMELIMIT, ROUNDSPERGAME = 51, 101, 30, 2000
    CLEAR = 'cls' if platform.system() == 'Windows' else 'clear'    # 设置清屏指令

    # 创建赛程
    name1, func1, name2, func2 = plrs[0][0], plrs[0][1], plrs[1][0], plrs[1][1]

    # 图形化计分表,比赛结果统计表
    x = PrettyTable(['  # ', ' Endgame Winner ',
                     ' Game State ', '    Rmk    '])
    pairResult = [0, 0]

    # 图形化计分表与比赛结果统计表绘图工具
    def outputer(match_result, i, GAMES, pairResult, name1, name2, x):
        # 统计胜方
        gameResult = match_result['result']
        gameWinner = gameResult[0]
        if gameWinner == None:
            winner = 'None'
        elif i <= GAMES:    # 前 GAMES 局
            if gameWinner == 0:
                pairResult[0] += 1
                winner = '(A) ' + name1
            elif gameWinner == 1:
                pairResult[1] += 1
                winner = '(B) ' + name2
        else:    # 后 GAMES 局
            if gameWinner == 1:
                pairResult[0] += 1
                winner = '(B) ' + name1
            elif gameWinner == 0:
                pairResult[1] += 1
                winner = '(A) ' + name2

        # 即时比赛结果的输出文字内容准备
        flag = gameResult[1]
        state = 'KO'
        if abs(flag) == 3:
            state = str(gameResult[2])
        flag = flag + 3
        rmklst = ['END', 'OVT', 'ERR', 'WAL', 'TAP', 'SID', 'FAC', 'CIT']
        
        gameRounds = len(match_result['log']) - 1
        x.add_row(['%2d'%i, winner, state, rmklst[flag] + ', %4d'%gameRounds])

        # 更新即时比赛结果
        os.system(CLEAR)
        print(
            name1,
            ' ' * (21 - len(name1)),
            '%2d' % pairResult[0],
            ': ',
            '%2d' % pairResult[1],
            ' ' * (23 - len(name2)),
            name2,
            file=sys.__stdout__)
        print(x, file=sys.__stdout__)
        
    # 初始化存储空间
    storageAB, storageBA = [{}, {}], [{}, {}]
    for match_core.STORAGE in storageAB, storageBA:
        for i in range(2):
            try:
                exec('func%d.init(match_core.STORAGE[%d])' % (i+1, i))
            except:
                pass
    storageBA = storageBA[::-1]

    # 根据赛程比赛
    # A vs B 顺序存储空间,先赛GAMES局
    for i in range(1, 1+GAMES):
        match_core.STORAGE = storageAB

        match_result = match((func1, func2), (name1, name2), 
                             HALFWIDTH, HEIGHT, ROUNDSPERGAME, TIMELIMIT)
        log_name = '%s/log/%s-VS-%s(%s).zlog' % (FOLDER, name1, name2, i)
        save_match_log(match_result, log_name)

        outputer(match_result, i, GAMES, pairResult, name1, name2, x)
    
    # B vs A 顺序存储空间,再赛GAMES局  
    for i in range(1+GAMES, 1+GAMES*2):  
        match_core.STORAGE = storageBA

        match_result = match((func2, func1), (name2, name1), 
                             HALFWIDTH, HEIGHT, ROUNDSPERGAME, TIMELIMIT)
        log_name = '%s/log/%s-VS-%s(%s).zlog' % (FOLDER, name2, name1, i-GAMES)
        save_match_log(match_result, log_name)

        outputer(match_result, i, GAMES, pairResult, name1, name2, x)

        if pairResult[0] > GAMES or pairResult[1] > GAMES:
            break

    # 总结函数
    storageBA = storageBA[::-1]
    for match_core.STORAGE in storageAB, storageBA:
        for i in range(2):
            try:
                exec('func%d.summaryall(match_core.STORAGE[%d])' % (i+1, i))
            except:
                pass
            
    # 单挑结束,输出结果
    if pairResult[0] > pairResult[1]:
        totalwinner = name1
        output = [(name1, func1)], [(name2, func2)]
    elif pairResult[0] < pairResult[1]:
        totalwinner = name2
        output = [(name2, func2)], [(name1, func1)]
    else:
        totalwinner = 'No one'
        output = [['No one']], None
    print('Knockout Result:', totalwinner, 'wins.',
          '\nPress enter to continue:', file=sys.__stdout__)
    input()
    return output
Esempio n. 2
0
def worker(id, net, data_queue, save=False):
    EPS_START = 0.9
    EPS_END = 0.2
    EPS_DECAY = 5000

    class player1:
        def load(self, stat, storage):
            storage['field_size'] = 0
            if 'tensor' in storage:
                del storage['tensor']

        def play(self, stat, storage):
            tensor, field_size = getFeatureMap(stat)
            reward = field_size - storage['field_size']
            if 'tensor' in storage:
                data_queue.put(
                    (storage['tensor'], storage['action'], tensor, reward))
            storage['tensor'] = tensor
            storage['field_size'] = field_size
            if 'steps_done' in storage:
                storage['steps_done'] += 1
            else:
                storage['steps_done'] = 1
            #print(tensor.shape)
            sample = random.random()
            eps_threshold = EPS_END + (EPS_START - EPS_END) * \
                math.exp(-1. * storage['steps_done'] / EPS_DECAY)
            #print('EPS: ', storage['steps_done'], eps_threshold)
            choices = ['l', 's', 'r']
            if sample > eps_threshold:
                #print('Using Net')
                with torch.no_grad():
                    res = net(tensor).max(1)[1]
                ret = choices[res]
            else:
                ret = random.choice(['l', 'r', 's'])
            storage['action'] = ret
            #print(ret)
            return ret

        def summary(self, result, stat, storage):
            tensor, field_size = getFeatureMap(stat)
            eps_threshold = EPS_END + (EPS_START - EPS_END) * \
                math.exp(-1. * storage['steps_done'] / EPS_DECAY)
            if id == 0:
                print('EPS: ', storage['steps_done'], eps_threshold, "Size: ",
                      tensor[0][0].sum())
            if result[0] is not None and result[1] >= 0:
                if result[0] == stat['log'][0]['me']['id'] - 1:
                    reward = 0
                else:
                    reward = -0
                data_queue.put(
                    (storage['tensor'], storage['action'], None, reward))

    class player2:
        def load(self, stat, storage):
            return p2.load(stat, storage)

        def play(self, stat, storage):
            return "r"
            return p2.play(stat, storage)

    gameCnt = 1
    while True:
        t1 = pf()
        res = match((player1(), player2()))
        t2 = pf()
        if id == 0:
            print("Time: ", t2 - t1)
            print(gameCnt, ' Match Done')
        if save:
            save_match_log(res, 'saves/' + str(gameCnt % 100) + '.zlog')
        gameCnt += 1
        if 'DEBUG_TRACEBACK' in dir(match):
            print(match.DEBUG_TRACEBACK)
            exit()
def process_task(data_queue, path, names, log_format, rounds, match_params):
    '''
    子进程执行两玩家多局对决

    params:
        data_queue - 数据队列
        path - 玩家模块所在路径
        names - 玩家名称
        log_format - 记录文件名格式
            比赛记录将保存为log_format % (*names, index)路径
        rounds - 单向比赛局数(双向进行)
        match_params - 比赛参数
    '''
    # 读取玩家
    sys.path.append(path)
    players = [__import__(n) for n in names]

    # 双向比赛
    win_counts = [0, 0]
    for i in 0, 1:
        # 初始化存储空间、局数统计
        match_core.STORAGE = [{}, {}]

        # 第二次交换比赛
        if i:
            players = players[::-1]
            names = names[::-1]
            win_counts = win_counts[::-1]

        # 总初始化函数
        for i in range(2):
            try:
                players[i].init(match_core.STORAGE[i])
            except:
                pass

        # 运行多局比赛
        for i in range(rounds):
            # 进行比赛,获取记录
            match_log = match_core.match(players, names, *match_params)

            # 生成比赛记录
            log_name = log_format % (*names, i)
            match_interface.save_match_log(match_log, log_name)

            # 比赛结果传递至队列
            result = match_log['result']
            data_queue.put((names, result))

            # 统计比赛结果,若胜利过半则跳出
            if result[0] is not None:
                win_counts[result[0]] += 1
                if win_counts[result[0]] > rounds:
                    break

        # 总总结函数
        for i in range(2):
            try:
                players[i].summaryall(match_core.STORAGE[i])
            except:
                pass
Esempio n. 4
0
storageAB, storageBA = [{}, {}], [{}, {}]
for match_core.STORAGE in storageAB, storageBA:
    for i in range(2):
        try:
            exec('func%d.init(match_core.STORAGE[0])' % i)
        except:
            pass

for i in range(GAMES):
    # A vs B 顺序存储空间
    match_core.STORAGE = storageAB

    match_result = match((func1, func2), (name1, name2), HALFWIDTH, HEIGHT,
                         ROUNDSPERGAME, TIMELIMIT)
    log_name = '%s/log/%s-VS-%s(%s).zlog' % (FOLDER, name1, name2, 1 + i)
    save_match_log(match_result, log_name)

    os.system('clear')

    gameWinner = match_result['result'][0]
    if gameWinner == 0:
        gameResult[0] += 1
        winner = '(A) ' + name1
    elif gameWinner == 1:
        gameResult[1] += 1
        winner = '(B) ' + name2
    else:
        winner = 'None'
    '''
    终局原因 : 
         0 - WAL 撞墙
def knockoutScenario(plrs, FOLDER):    # 单挑赛脚本:读取目录内两个文件,提取play函数并执行
    # 屏蔽AI自带print
    class null_stream:
        def read(*args):
            pass

        def write(*args):
            pass

        def flush(*args):
            pass


    sys.stdout = null_stream


    # 设置比赛参数
    GAMES = 10    # 作为先后手各比赛场数,总场次 2 * GAMES
    HALFWIDTH, HEIGHT, TIMELIMIT, ROUNDSPERGAME,  = 51, 101, 30, 20
    CLEAR = 'cls' if platform.system() == 'Windows' else 'clear'    # 设置清屏指令


    # 创建赛程
    name1, func1, name2, func2 = plrs[0][0], plrs[0][1], plrs[1][0], plrs[1][1]


    # 图形化计分表,比赛结果统计表
    x = PrettyTable([' #', 'Endgame Winner', 'Game State', '   Rmk   '])
    pairResult = [0, 0]


    # 图形化计分表与比赛结果统计表绘图工具
    def outputer(match_result, i, GAMES, pairResult, name1, name2, x):
        # 统计胜方
        gameResult = match_result['result']
        gameWinner = gameResult[0]
        if gameWinner == None:
            winner = 'None'
        elif i < GAMES:    # 前 GAMES 局
            if gameWinner == 0:
                pairResult[0] += 1
                winner = '(A) ' + name1
            elif gameWinner == 1:
                pairResult[1] += 1
                winner = '(B) ' + name2
        else:    # 后 GAMES 局
            if gameWinner == 1:
                pairResult[0] += 1
                winner = '(B) ' + name1
            elif gameWinner == 0:
                pairResult[1] += 1
                winner = '(A) ' + name2

        # 即时比赛结果的输出文字内容准备
        flag = gameResult[1]
        if flag < 0:
            flag += 8
        rmklst = ['WAL', 'TAP', 'SID', 'FAC', 'CIT', 'END', 'OVT', 'ERR']
        reason = 'KO'
        if flag == 3 or flag == 5:
            reason = str(gameResult[2])

        gameRounds = len(match_result['log']) - 1
        x.add_row(['%2d'%i, winner, reason, rmklst[flag] + ', %4d'%gameRounds])

        # 更新即时比赛结果
        os.system(CLEAR)
        print(
            name1,
            ' ' * (17 - len(name1)),
            '%2d' % pairResult[0],
            ': ',
            '%2d' % pairResult[1],
            ' ' * (19 - len(name2)),
            name2,
            file=sys.__stdout__)
        print(x, file=sys.__stdout__)
        

    # 初始化存储空间
    storageAB, storageBA = [{}, {}], [{}, {}]
    for match_core.STORAGE in storageAB, storageBA:
        for i in range(2):
            try:
                exec('func%d.init(match_core.STORAGE[%d])' % (i + 1, i))
            except:
                pass
    storageBA = storageBA[::-1]


    # 根据赛程比赛
    for i in range(GAMES):    # A vs B 顺序存储空间,先赛GAMES局
        match_core.STORAGE = storageAB

        match_result = match((func1, func2), (name1, name2), HALFWIDTH, HEIGHT,
                             ROUNDSPERGAME, TIMELIMIT)
        log_name = '%s/log/%s-VS-%s(%s).zlog' % (FOLDER, name1, name2, 1 + i)
        save_match_log(match_result, log_name)

        outputer(match_result, i, GAMES, pairResult, name1, name2, x)


    for i in range(GAMES, GAMES*2):    # B vs A 顺序存储空间,再赛GAMES局    
        match_core.STORAGE = storageBA

        match_result = match((func2, func1), (name2, name1), HALFWIDTH, HEIGHT,
                             ROUNDSPERGAME, TIMELIMIT)
        log_name = '%s/log/%s-VS-%s(%s).zlog' % (FOLDER, name2, name1, 1 + i)
        save_match_log(match_result, log_name)

        outputer(match_result, i, GAMES, pairResult, name1, name2, x)

        if pairResult[0] > GAMES or pairResult[1] > GAMES:
            break
        

    # 总结函数
    storageBA = storageBA[::-1]
    for match_core.STORAGE in storageAB, storageBA:
        for i in range(2):
            try:
                exec('func%d.summaryall(match_core.STORAGE[%d])' % (i + 1, i))
            except:
                pass


    # 单挑结束,输出结果;平手的话该对重赛一次
    if pairResult[0] > pairResult[1]:
        totalresult = name1 + ' wins.'
        output = [(name1, func1)], [(name2, func2)]
    elif pairResult[0] < pairResult[1]:
        totalresult = name2 + ' wins.'
        output = [(name2, func2)], [(name1, func1)]
    else:
        totalresult = 'Ties.'
        output = [['No one']], None
    print('Knockout Result:', totalresult, file=sys.__stdout__)
    time.sleep(5)
    if output is not None:
        return output
    else:
        return knockout20(plrs, FOLDER)