问题优化

This commit is contained in:
hxuanyu 2025-04-02 14:44:42 +08:00
parent 5d4c52fba4
commit 265dd6bfa3
5 changed files with 231 additions and 12 deletions

View File

@ -27,6 +27,11 @@
- 交互式命令行界面,便于直接使用
- 支持自定义评分参数
5. **Web界面模块**
- 基于Flask的Web界面提供图形化操作体验
- 可视化显示阵容推荐结果
- 支持在线调整权重参数与配置
## 环境与依赖
- **Python版本:** Python 3.8+
@ -34,7 +39,12 @@
- requests: 用于获取在线数据
- pandas: 用于数据处理
- pyyaml: 用于配置文件解析
- numpy: 用于数值计算
- flask: 用于Web界面
- flask-cors: 处理跨域请求
- waitress: 生产环境Web服务器
- pytest: 用于单元测试
- tqdm: 用于进度显示
## 项目安装
@ -61,7 +71,7 @@ python main.py --help
输出结果会显示所有可用的子命令和选项。
### Web界面(新增)
### Web界面
运行以下命令启动Web界面
@ -74,6 +84,7 @@ python main.py web
- `--host`: 指定服务器主机地址,默认为"0.0.0.0"(允许所有网络接口访问)
- `--port`: 指定服务器端口默认为5000
- `--dev`: 启用开发模式(开启调试功能,自动重载代码)
- `--config`: 指定自定义配置文件路径
例如:
```bash
@ -135,6 +146,32 @@ python main.py scoring
python main.py scoring --config path/to/custom_config.yaml
```
### 配置管理
运行以下命令管理权重配置:
```bash
python main.py config --show
```
配置管理提供以下功能:
- 显示当前所有权重配置
- 设置特定羁绊的权重
- 设置特定棋子的权重
- 设置基础权重参数
例如:
```bash
# 设置羁绊权重
python main.py config --set-synergy "超频战士" 1.5
# 设置棋子权重
python main.py config --set-chess "厄加特" 1.8
# 设置基础权重参数
python main.py config --set-base "synergy_level_weight" 1.2
```
### 命令行界面
运行以下命令启动交互式命令行界面:
@ -160,6 +197,7 @@ python main.py cli --population 8 --results 5 --level-weight 1.2 --count-weight
- `--level-weight`羁绊等级权重默认为1.0
- `--count-weight`羁绊数量权重默认为0.5
- `--cost-weight`棋子费用权重默认为0.1
- `--config`:指定自定义配置文件路径
## 项目结构
@ -186,7 +224,10 @@ TFT-Strategist/
│ │ ├── __init__.py
│ │ ├── api.py # 编程接口
│ │ └── cli.py # 命令行界面
│ ├── web/ # Web界面模块 (新增)
│ ├── config/ # 配置管理模块
│ │ ├── __init__.py
│ │ └── weights_config.py # 权重配置管理
│ ├── web/ # Web界面模块
│ │ ├── __init__.py
│ │ ├── app.py # Flask应用
│ │ ├── static/ # 静态资源
@ -207,6 +248,10 @@ TFT-Strategist/
│ └── test_interface.py # 接口模块测试
├── main.py # 主程序入口
├── requirements.txt # 项目依赖
├── test_direct.py # 直接测试脚本
├── test_recommendation.py # 阵容推荐测试脚本
├── generate_weights_config.py # 权重配置生成工具
├── get_data.py # 数据获取工具
└── README.md # 项目文档
```
@ -478,20 +523,68 @@ python main.py cli [参数]
2. 添加必选棋子
3. 获取详细的阵容推荐结果
## Web界面模块详解
Web界面模块提供了图形化的用户交互方式基于Flask框架实现。
### 主要功能
1. **阵容推荐设置**
- 可视化选择阵容人口
- 添加/删除必选羁绊和棋子
- 自定义权重调整
2. **阵容展示**
- 直观显示推荐阵容棋子和羁绊
- 支持多种排序和筛选方式
- 详细的阵容分析数据
3. **配置管理**
- 在线编辑权重配置
- 保存和加载配置文件
- 配置模板管理
### 启动方式
```bash
python main.py web [--host HOST] [--port PORT] [--dev] [--config CONFIG_PATH]
```
## 工具脚本
### generate_weights_config.py
用于生成初始权重配置文件,可根据游戏最新数据自动更新配置。
```bash
python generate_weights_config.py [--output OUTPUT_PATH]
```
### get_data.py
用于从官方接口获取最新游戏数据,支持手动更新。
```bash
python get_data.py [--force]
```
## 开发计划
- [x] 数据提供模块
- [x] 阵容推荐模块
- [x] 阵容评分模块
- [x] 接口模块
- [x] Web界面模块
- [x] 配置管理功能
## 未来展望
- [ ] 图形用户界面(GUI)开发
- [ ] 优化算法效率,支持更复杂的推荐策略
- [ ] 基于历史数据的胜率分析
- [ ] 支持装备推荐
- [ ] 多语言支持
- [ ] 基于机器学习的个性化推荐
- [ ] 移动端应用开发
## 贡献指南

BIN
analysis_summary.txt Normal file

Binary file not shown.

View File

@ -56,11 +56,26 @@ def create_app(config_path: Optional[str] = None):
all_synergies = all_jobs + all_races
all_chess = data_api.get_all_chess()
# 打印羁绊和棋子数据结构,用于调试
logger.info(f"羁绊数量: {len(all_synergies)}")
if all_synergies:
sample_synergy = all_synergies[0]
logger.info(f"羁绊示例: {sample_synergy}")
logger.info(f"棋子数量: {len(all_chess)}")
if all_chess:
sample_chess = all_chess[0]
logger.info(f"棋子示例: {sample_chess}")
# 获取全局配置中的权重信息
base_weights = weights_config.get_base_weights()
synergy_weights = weights_config.get_synergy_weights()
chess_weights = weights_config.get_chess_weights()
# 打印权重配置,用于调试
logger.info(f"羁绊权重示例: {list(synergy_weights.items())[:3]}")
logger.info(f"棋子权重示例: {list(chess_weights.items())[:3]}")
return render_template('index.html',
synergies=all_synergies,
chess=all_chess,
@ -144,9 +159,10 @@ def create_app(config_path: Optional[str] = None):
for synergy_id, level in active_synergies.items():
synergy_info = data_api.get_synergy_by_id(synergy_id)
if synergy_info:
name = synergy_info.get('name', '')
active_synergies_list.append({
'id': synergy_id,
'name': synergy_info.get('name', ''),
'name': name,
'level': level,
'description': synergy_info.get('description', ''),
'image': f"synergy_{synergy_id}.png" # 假设有对应图片

View File

@ -556,30 +556,123 @@ function updateActiveStatus(results) {
// 收集所有被激活的羁绊和棋子
const activeSynergies = new Set();
const activeSynergyNames = new Set(); // 添加名称集合
const activeChess = new Set();
const activeChessNames = new Set(); // 添加名称集合
console.log('更新激活状态:', results);
results.forEach(result => {
// 添加激活的羁绊
result.active_synergies.forEach(synergy => {
activeSynergies.add(synergy.id);
console.log('激活羁绊:', synergy);
if (synergy.id) activeSynergies.add(synergy.id);
if (synergy.name) activeSynergyNames.add(synergy.name); // 添加名称
});
// 添加激活的棋子
result.chess_list.forEach(chess => {
activeChess.add(chess.id);
console.log('激活棋子:', chess);
if (chess.id) activeChess.add(chess.id);
if (chess.name) activeChessNames.add(chess.name); // 添加名称
});
});
// 设置羁绊激活状态
console.log('所有激活的羁绊ID', Array.from(activeSynergies));
console.log('所有激活的羁绊名称:', Array.from(activeSynergyNames));
console.log('所有激活的棋子ID', Array.from(activeChess));
console.log('所有激活的棋子名称:', Array.from(activeChessNames));
// 记录是否有成功匹配
let synergyMatched = false;
let chessMatched = false;
// 使用多种方式尝试匹配
// 1. 通过ID直接匹配
activeSynergies.forEach(synergyId => {
$(`.synergy-weight-item[data-synergy-id="${synergyId}"]`).addClass('active');
const selector = `.synergy-weight-item[data-synergy-id="${synergyId}"]`;
const $elements = $(selector);
console.log('查找羁绊元素(通过ID)', selector, $elements.length);
if ($elements.length > 0) {
$elements.addClass('active');
synergyMatched = true;
}
});
// 设置棋子激活状态
activeChess.forEach(chessId => {
$(`.chess-weight-item[data-chess-id="${chessId}"]`).addClass('active');
const selector = `.chess-weight-item[data-chess-id="${chessId}"]`;
const $elements = $(selector);
console.log('查找棋子元素(通过ID)', selector, $elements.length);
if ($elements.length > 0) {
$elements.addClass('active');
chessMatched = true;
}
});
// 2. 通过名称匹配
if (!synergyMatched) {
console.log('ID匹配失败尝试使用名称匹配羁绊');
$('.synergy-weight-item').each(function() {
const $item = $(this);
const synergyName = $item.find('label').text().trim();
const dataName = $item.data('synergy-name');
if (activeSynergyNames.has(synergyName) ||
(dataName && activeSynergyNames.has(dataName))) {
$item.addClass('active');
console.log('通过名称匹配到羁绊:', synergyName);
synergyMatched = true;
}
});
}
if (!chessMatched) {
console.log('ID匹配失败尝试使用名称匹配棋子');
$('.chess-weight-item').each(function() {
const $item = $(this);
const chessName = $item.find('label').text().trim();
const dataName = $item.data('chess-name');
if (activeChessNames.has(chessName) ||
(dataName && activeChessNames.has(dataName))) {
$item.addClass('active');
console.log('通过名称匹配到棋子:', chessName);
chessMatched = true;
}
});
}
// 3. 最后的尝试:直接遍历匹配名称(不区分大小写)
if (!synergyMatched) {
console.log('所有正常匹配方式失败,尝试不区分大小写的名称匹配');
const lowerSynergyNames = Array.from(activeSynergyNames).map(name => name.toLowerCase());
$('.synergy-weight-item').each(function() {
const $item = $(this);
const synergyName = $item.find('label').text().trim().toLowerCase();
if (lowerSynergyNames.includes(synergyName)) {
$item.addClass('active');
console.log('通过不区分大小写名称匹配到羁绊:', synergyName);
}
});
}
if (!chessMatched) {
const lowerChessNames = Array.from(activeChessNames).map(name => name.toLowerCase());
$('.chess-weight-item').each(function() {
const $item = $(this);
const chessName = $item.find('label').text().trim().toLowerCase();
if (lowerChessNames.includes(chessName)) {
$item.addClass('active');
console.log('通过不区分大小写名称匹配到棋子:', chessName);
}
});
}
// 如果勾选了"仅显示已激活",则更新显示状态
if ($('#show-only-active').is(':checked')) {
$('.synergy-weight-item').hide();
@ -590,4 +683,12 @@ function updateActiveStatus(results) {
$('.chess-weight-item').hide();
$('.chess-weight-item.active').show();
}
// 添加高亮样式,以便更好地区分激活项
$('.synergy-weight-item.active').css('background-color', '#e0e7ff');
$('.chess-weight-item.active').css('background-color', '#e0e7ff');
// 输出激活项目数量统计
console.log('成功激活的羁绊数量:', $('.synergy-weight-item.active').length);
console.log('成功激活的棋子数量:', $('.chess-weight-item.active').length);
}

View File

@ -44,6 +44,15 @@
.drawer-backdrop.open {
display: block;
}
/* 添加激活状态样式 */
.synergy-weight-item.active,
.chess-weight-item.active {
background-color: #e0e7ff;
border-left: 3px solid #4f46e5;
padding-left: 5px;
border-radius: 4px;
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
@ -109,7 +118,7 @@
<div id="synergy-weights-container" class="space-y-4 mb-6">
{% for synergy_id, weight in synergy_weights.items() %}
<div class="synergy-weight-item" data-synergy-id="{{ synergy_id }}">
<div class="synergy-weight-item" data-synergy-id="{{ synergy_id }}" data-synergy-name="{{ synergy_id }}">
<div class="flex items-center justify-between mb-1">
<label class="text-gray-700">{{ synergy_id }}</label>
<span class="synergy-weight-value text-xs text-gray-700">{{ weight }}</span>
@ -129,7 +138,7 @@
<div id="chess-weights-container" class="space-y-4">
{% for chess_id, weight in chess_weights.items() %}
<div class="chess-weight-item" data-chess-id="{{ chess_id }}">
<div class="chess-weight-item" data-chess-id="{{ chess_id }}" data-chess-name="{{ chess_id }}">
<div class="flex items-center justify-between mb-1">
<label class="text-gray-700">{{ chess_id }}</label>
<span class="chess-weight-value text-xs text-gray-700">{{ weight }}</span>