news 2026/4/24 12:04:51

排位匹配算法测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
排位匹配算法测试

做赛事系统的时候,推出一个赛制叫自由排位赛制,即参赛选手随意匹配对手,然后自身的rank分、胜率等也会变化,再根据这些变化的影响因子,再去匹配对手,后端会出一个算法文档,测试需要验证一下这个算法的基本准确性。

一、系统要求

大概的要求是这些

1.对局体验:玩家参赛前几局要匹配实力相近的队友和对手,避免被虐
2.公平性:赛事最终排名应该与选手真实实力匹配
3.匹配时长:玩家参赛初期,匹配时长15s~30s
玩家场数较多且排名较高时,匹配时长<1min

二、测试方案

经过和开发讨论之后,纯手工测试执行难度比较大,才用测试脚本测试,基本思路:

1、开发测试环境模拟匹配池海量匹配,并且把每一个匹配对局的队伍信息、匹配时长、rank匹配范围等信息打出日志,然后确定格式转化成excel表格

2、测试编写脚本来验证每一行数据的准确性,取一定样本量数据来进行数据校对测试(比如1000条)

3、最后确定一个合格的通过率(比如90%、85%)作为测试通过标准

三、测试准备

测试数据表格准备示例:

测试结果由测试给出,前面的数据由开发日志提出

测试脚本:

import openpyxl import math # 前三场球员, 轮数与标准差 is_first_three_match_list = { 1: 0.10, 2: 0.20, 3: 0.25, 4: 0.30, 5: 0.35, 6: 0.40, 7: 0.45, 8: 0.50 } # 非前三场球员, 轮数与标准差 is_not_first_three_match_list = { 1: 0.10, 2: 0.20, 3: 0.30, 4: 0.40, 5: 0.50, 6: 0.60, 7: 0.60, 8: 0.70, 9: 0.70, 10: 0.80, 11: 0.80, 12: 0.80, 13: 0.90, 14: 0.90, 15: 0.90, 16: 1.00 } # 读取excel表格数据 def read_data(file_path, sheet_name): # 打开excel表格 workbook = None try: workbook = openpyxl.load_workbook(file_path) # 获取工作表对象 sheet = workbook[sheet_name] test_data = [] # 逐行读取数据,存入列表 for i in range(2, sheet.max_row + 1): test_dict = dict() test_dict['队伍A名称'] = sheet.cell(i, 1).value test_dict['队伍B名称'] = sheet.cell(i, 2).value test_dict['队伍A匹配前隐藏分'] = sheet.cell(i, 3).value test_dict['队伍B匹配前隐藏分'] = sheet.cell(i, 4).value test_dict['匹配轮数'] = sheet.cell(i, 5).value test_dict['匹配时长'] = sheet.cell(i, 6).value test_dict['匹配成功时A的隐藏分匹配范围'] = sheet.cell(i, 7).value test_dict['匹配成功时B的隐藏分匹配范围'] = sheet.cell(i, 8).value test_dict['队伍A是否含有前3场球员'] = sheet.cell(i, 9).value test_dict['队伍B是否含有前3场球员'] = sheet.cell(i, 10).value test_dict['测试结果1'] = sheet.cell(i, 11).value test_dict['测试结果2'] = sheet.cell(i, 12).value test_dict['测试结果3'] = sheet.cell(i, 13).value test_dict['整体结果'] = sheet.cell(i, 14).value test_data.append(test_dict) return test_data except Exception as e: raise e finally: if workbook: workbook.close() # 写入excel表格数据 def write_data(row, file_path, sheet_name, column, value): workbook = None try: workbook = openpyxl.load_workbook(file_path) sheet = workbook[sheet_name] sheet.cell(row=row, column=column).value = value workbook.save(file_path) except Exception as e: raise e finally: if workbook: workbook.close() # 测试轮次与时长 def test_round_time(match_round, time): return int(time / match_round) == 2 # 测试分数范围重合 def test_rank_score_intersect(match_success_a, match_success_b): return max(match_success_a[0], match_success_b[0]) <= min(match_success_a[1], match_success_b[1]) # 测试分数范围扩散 def test_increase_score(score, increase_score_list, is_contain_first_three, match_round): s = is_first_three_match_list[match_round] if is_contain_first_three else is_not_first_three_match_list[match_round] increase_score_min = score - score * s increase_score_max = score + score * s print(increase_score_min, increase_score_max) num_min = min(increase_score_list) num_max = max(increase_score_list) print(num_min, num_max) return math.fabs(int(num_max) - int(increase_score_max)) <= 1 and math.fabs(int(num_min) - int(increase_score_min)) <= 1 if __name__ == '__main__': # 测试数据路径, 可修改 path = r'C:\Users\xxx\Desktop\匹配测试数据.xlsx' sheet_name = '测试' data_list = read_data(path, sheet_name) for i in range(len(data_list)): match_round = data_list[i]['匹配轮数'] score_a = int(data_list[i]['队伍A匹配前隐藏分']) increase_score_a = eval(data_list[i]['匹配成功时A的隐藏分匹配范围']) is_contain_first_three_a = int(data_list[i]['队伍A是否含有前3场球员']) score_b = int(data_list[i]['队伍B匹配前隐藏分']) increase_score_b = eval(data_list[i]['匹配成功时B的隐藏分匹配范围']) is_contain_first_three_b = int(data_list[i]['队伍B是否含有前3场球员']) if test_round_time(data_list[i]['匹配轮数'], data_list[i]['匹配时长']): write_data(i + 2, path, sheet_name, 11, '匹配轮次与时长正确') else: write_data(i + 2, path, sheet_name, 11, '匹配轮次与时长错误') write_data(i + 2, path, sheet_name, 14, 'FAIL') if test_rank_score_intersect(increase_score_a, increase_score_b): write_data(i + 2, path, sheet_name, 12, '匹配范围重合, 正确') else: write_data(i + 2, path, sheet_name, 12, '匹配范围不重合, 错误') write_data(i + 2, path, sheet_name, 14, 'FAIL') if (test_increase_score(score_a, increase_score_a, is_contain_first_three_a, match_round) and test_increase_score(score_b, increase_score_b, is_contain_first_three_b, match_round)): write_data(i + 2, path, sheet_name, 13, '匹配范围扩散, 正确') else: write_data(i + 2, path, sheet_name, 13, '匹配范围扩散, 错误') write_data(i + 2, path, sheet_name, 14, 'FAIL') if '错误' not in data_list[i]['测试结果1'] and '错误' not in data_list[i]['测试结果2'] and '错误' not in data_list[i]['测试结果3']: write_data(i + 2, path, sheet_name, 14, 'PASS')

上面是我自己写的,看下ai优化后的:

import openpyxl import math from typing import List, Dict, Tuple, Union # 前三场球员, 轮数与标准差 IS_FIRST_THREE_MATCH_LIST = { 1: 0.10, 2: 0.20, 3: 0.25, 4: 0.30, 5: 0.35, 6: 0.40, 7: 0.45, 8: 0.50 } # 非前三场球员, 轮数与标准差 IS_NOT_FIRST_THREE_MATCH_LIST = { 1: 0.10, 2: 0.20, 3: 0.30, 4: 0.40, 5: 0.50, 6: 0.60, 7: 0.60, 8: 0.70, 9: 0.70, 10: 0.80, 11: 0.80, 12: 0.80, 13: 0.90, 14: 0.90, 15: 0.90, 16: 1.00 } def read_data(file_path: str, sheet_name: str) -> List[Dict[str, Union[str, int]]]: """读取excel表格数据 Args: file_path: Excel文件路径 sheet_name: 工作表名称 Returns: 测试数据列表,每个元素为包含测试数据的字典 """ try: workbook = openpyxl.load_workbook(file_path) sheet = workbook[sheet_name] test_data = [] for i in range(2, sheet.max_row + 1): test_dict = { '队伍A名称': sheet.cell(i, 1).value, '队伍B名称': sheet.cell(i, 2).value, '队伍A匹配前隐藏分': sheet.cell(i, 3).value, '队伍B匹配前隐藏分': sheet.cell(i, 4).value, '匹配轮数': sheet.cell(i, 5).value, '匹配时长': sheet.cell(i, 6).value, '匹配成功时A的隐藏分匹配范围': sheet.cell(i, 7).value, '匹配成功时B的隐藏分匹配范围': sheet.cell(i, 8).value, '队伍A是否含有前3场球员': sheet.cell(i, 9).value, '队伍B是否含有前3场球员': sheet.cell(i, 10).value, '测试结果1': sheet.cell(i, 11).value, '测试结果2': sheet.cell(i, 12).value, '测试结果3': sheet.cell(i, 13).value, '整体结果': sheet.cell(i, 14).value } test_data.append(test_dict) return test_data except FileNotFoundError: raise FileNotFoundError(f"文件 {file_path} 不存在") except KeyError: raise KeyError(f"工作表 {sheet_name} 不存在") except Exception as e: raise Exception(f"读取Excel文件时发生错误: {str(e)}") finally: if 'workbook' in locals(): workbook.close() def write_data(row: int, file_path: str, sheet_name: str, column: int, value: str) -> None: """写入excel表格数据 Args: row: 行号 file_path: 文件路径 sheet_name: 工作表名称 column: 列号 value: 要写入的值 """ try: workbook = openpyxl.load_workbook(file_path) sheet = workbook[sheet_name] sheet.cell(row=row, column=column).value = value workbook.save(file_path) except FileNotFoundError: raise FileNotFoundError(f"文件 {file_path} 不存在") except KeyError: raise KeyError(f"工作表 {sheet_name} 不存在") except PermissionError: raise PermissionError(f"文件 {file_path} 可能被其他程序占用") except Exception as e: raise Exception(f"写入Excel文件时发生错误: {str(e)}") finally: if 'workbook' in locals(): workbook.close() def test_round_time(match_round: int, time: int) -> bool: """测试轮次与时长 Args: match_round: 匹配轮数 time: 匹配时长 Returns: 测试结果布尔值 """ return int(time / match_round) == 2 def test_rank_score_intersect(match_success_a: Tuple[int, int], match_success_b: Tuple[int, int]) -> bool: """测试分数范围重合 Args: match_success_a: 队伍A的匹配范围元组 (min, max) match_success_b: 队伍B的匹配范围元组 (min, max) Returns: 范围是否重合的布尔值 """ return max(match_success_a[0], match_success_b[0]) <= min(match_success_a[1], match_success_b[1]) def test_increase_score(score: int, increase_score_list: List[int], is_contain_first_three: bool, match_round: int) -> bool: """测试分数范围扩散 Args: score: 原始分数 increase_score_list: 扩散后的分数范围列表 is_contain_first_three: 是否包含前三场球员 match_round: 匹配轮数 Returns: 测试结果布尔值 """ std_dev = IS_FIRST_THREE_MATCH_LIST.get(match_round) if is_contain_first_three else IS_NOT_FIRST_THREE_MATCH_LIST.get(match_round) if std_dev is None: return False increase_score_min = score - score * std_dev increase_score_max = score + score * std_dev num_min = min(increase_score_list) num_max = max(increase_score_list) return (abs(int(num_max) - int(increase_score_max)) <= 1 and abs(int(num_min) - int(increase_score_min)) <= 1) def safe_eval_range_string(range_str: str) -> List[int]: """安全地解析范围字符串,避免使用eval的安全风险 Args: range_str: 格式如 '[1000, 1200]' 的字符串 Returns: 解析后的整数列表 """ if not range_str or not isinstance(range_str, str): return [] # 移除方括号和空格 cleaned_str = range_str.strip().replace('[', '').replace(']', '').replace(' ', '') if ',' in cleaned_str: parts = cleaned_str.split(',') try: return [int(part) for part in parts if part.strip()] except ValueError: return [] return [] def run_tests(data_list: List[Dict], path: str, sheet_name: str) -> None: """执行所有测试并写入结果 Args: data_list: 测试数据列表 path: Excel文件路径 sheet_name: 工作表名称 """ for i, data in enumerate(data_list, start=2): match_round = data['匹配轮数'] score_a = int(data['队伍A匹配前隐藏分']) increase_score_a = safe_eval_range_string(data['匹配成功时A的隐藏分匹配范围']) is_contain_first_three_a = int(data['队伍A是否含有前3场球员']) score_b = int(data['队伍B匹配前隐藏分']) increase_score_b = safe_eval_range_string(data['匹配成功时B的隐藏分匹配范围']) is_contain_first_three_b = int(data['队伍B是否含有前3场球员']) # 检查数据有效性 if not increase_score_a or not increase_score_b: write_data(i, path, sheet_name, 14, 'FAIL - 数据格式错误') continue # 测试1: 匹配轮次与时长 if test_round_time(data['匹配轮数'], data['匹配时长']): write_data(i, path, sheet_name, 11, '匹配轮次与时长正确') else: write_data(i, path, sheet_name, 11, '匹配轮次与时长错误') write_data(i, path, sheet_name, 14, 'FAIL') # 测试2: 匹配范围重合 if test_rank_score_intersect((increase_score_a[0], increase_score_a[1]), (increase_score_b[0], increase_score_b[1])): write_data(i, path, sheet_name, 12, '匹配范围重合, 正确') else: write_data(i, path, sheet_name, 12, '匹配范围不重合, 错误') write_data(i, path, sheet_name, 14, 'FAIL') # 测试3: 匹配范围扩散 if (test_increase_score(score_a, increase_score_a, is_contain_first_three_a, match_round) and test_increase_score(score_b, increase_score_b, is_contain_first_three_b, match_round)): write_data(i, path, sheet_name, 13, '匹配范围扩散, 正确') else: write_data(i, path, sheet_name, 13, '匹配范围扩散, 错误') write_data(i, path, sheet_name, 14, 'FAIL') # 检查最终结果 if ('错误' not in data['测试结果1'] and '错误' not in data['测试结果2'] and '错误' not in data['测试结果3']): write_data(i, path, sheet_name, 14, 'PASS') if __name__ == '__main__': # 测试数据路径, 可修改 path = r'C:\Users\xxx\Desktop\匹配测试数据.xlsx' sheet_name = '测试' try: data_list = read_data(path, sheet_name) print(f"成功读取 {len(data_list)} 条测试数据") run_tests(data_list, path, sheet_name) print("测试完成,结果已写入Excel文件") except Exception as e: print(f"执行测试时发生错误: {e}") raise

测试脚本主要做了啥:

1、数据读取:从Excel文件中读取测试数据,包括:

  • 队伍名称和隐藏分
  • 匹配轮数和时长
  • 匹配范围数据
  • 是否包含前三场球员的标记

2、三种核心测试:

  • 匹配轮次与时长测试:验证匹配时长是否等于匹配轮数的2倍
  • 匹配范围重合测试:检查两队匹配范围是否有交集
  • 匹配范围扩散测试:根据配置的标准差验证分数扩散范围是否正确

3、结果写入:

  • 将测试结果写回Excel文件的对应列中

四、测试结果

统计准确率可以自行统计

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/24 12:04:50

从‘深蓝’到ChatGPT:一文看懂AI发展史上的10个关键‘胜负手’

从‘深蓝’到ChatGPT&#xff1a;AI进化史上的10个战略转折点 1997年5月11日&#xff0c;纽约公平大厦34层&#xff0c;加里卡斯帕罗夫面对IBM深蓝计算机推枰认负的那一刻&#xff0c;人类第一次真切感受到机器智能的压迫感。这场持续6局的世纪对弈&#xff0c;不仅是国际象棋史…

作者头像 李华
网站建设 2026/4/24 12:04:19

别再手动敲命令了!用Ansible CE模块批量管理华为交换机,保姆级避坑教程

华为交换机自动化管理实战&#xff1a;Ansible CE模块深度避坑指南 每次登录几十台交换机重复输入相同命令的日子该结束了。作为经历过无数次深夜故障处理的运维老兵&#xff0c;我深知手工操作不仅效率低下&#xff0c;更可怕的是人为失误带来的连锁反应。直到发现Ansible CE模…

作者头像 李华
网站建设 2026/4/24 12:02:18

如何一键永久保存微信聊天记录:WeChatMsg完整备份方案

如何一键永久保存微信聊天记录&#xff1a;WeChatMsg完整备份方案 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeCha…

作者头像 李华
网站建设 2026/4/24 12:00:34

HS2-HF_Patch终极指南:三步轻松完成Honey Select 2汉化与优化

HS2-HF_Patch终极指南&#xff1a;三步轻松完成Honey Select 2汉化与优化 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为《Honey Select 2》的日文界面感…

作者头像 李华