问题优化
This commit is contained in:
parent
5d4c52fba4
commit
265dd6bfa3
99
README.md
99
README.md
@ -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
BIN
analysis_summary.txt
Normal file
Binary file not shown.
@ -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" # 假设有对应图片
|
||||
|
@ -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);
|
||||
}
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user