本文目录导读:

我来为你提供一个统计 SofaScore 综合评分的 Java 案例,SofaScore 的评分系统采用 1-10 分制,综合评分是通过多个维度的数据加权计算得出的。
SofaScore 评分维度说明
SofaScore 球员评分主要包含以下维度:
| 维度 | 说明 | 权重示例 |
|---|---|---|
| 进攻 (Attack) | 进球、助攻、射门 | 30% |
| 组织 (Creation) | 关键传球、传球成功率 | 20% |
| 防守 (Defense) | 抢断、拦截、解围 | 25% |
| 控球 (Possession) | 触球、盘带成功率 | 15% |
| 纪律 (Discipline) | 犯规、黄红牌 | 10% |
完整 Java 实现
球员数据实体类
package com.example.sofascore;
import java.util.List;
/**
* 球员比赛数据
*/
public class PlayerStats {
private String playerName;
private String position;
// 进攻数据
private int goals; // 进球
private int assists; // 助攻
private int shotsOnTarget; // 射正
private int shotsTotal; // 射门总数
// 组织数据
private int keyPasses; // 关键传球
private int passesTotal; // 传球总数
private int passesAccurate; // 传球成功数
// 防守数据
private int tackles; // 抢断
private int interceptions; // 拦截
private int clearances; // 解围
// 控球数据
private int touches; // 触球次数
private int dribblesSuccess; // 盘带成功
private int dribblesTotal; // 盘带总数
// 纪律数据
private int fouls; // 犯规
private boolean yellowCard; // 黄牌
private boolean redCard; // 红牌
// 构造器 + Getter/Setter 省略
// 计算传球成功率
public double getPassAccuracy() {
return passesTotal == 0 ? 0 : (double) passesAccurate / passesTotal;
}
// 计算盘带成功率
public double getDribbleAccuracy() {
return dribblesTotal == 0 ? 0 : (double) dribblesSuccess / dribblesTotal;
}
// Getter / Setter ...
}
评分计算核心类
package com.example.sofascore;
/**
* SofaScore 综合评分计算器
* 输出范围:1.0 ~ 10.0
*/
public class SofaScoreCalculator {
// 各维度权重(合计 = 1.0)
private static final double WEIGHT_ATTACK = 0.30;
private static final double WEIGHT_CREATION = 0.20;
private static final double WEIGHT_DEFENSE = 0.25;
private static final double WEIGHT_POSSESSION = 0.15;
private static final double WEIGHT_DISCIPLINE = 0.10;
// 基准分(球员上场默认起始分)
private static final double BASE_SCORE = 6.0;
/**
* 计算球员综合评分
*/
public static double calculate(PlayerStats s) {
double attackScore = calcAttack(s);
double creationScore = calcCreation(s);
double defenseScore = calcDefense(s);
double possessionScore = calcPossession(s);
double disciplineScore = calcDiscipline(s);
double rawScore = BASE_SCORE
+ attackScore * WEIGHT_ATTACK
+ creationScore * WEIGHT_CREATION
+ defenseScore * WEIGHT_DEFENSE
+ possessionScore * WEIGHT_POSSESSION
+ disciplineScore * WEIGHT_DISCIPLINE;
return clamp(rawScore, 1.0, 10.0);
}
/** 进攻得分:进球*2.0 + 助攻*1.5 + 射正*0.4 + 射门*0.15 */
private static double calcAttack(PlayerStats s) {
return s.getGoals() * 2.0
+ s.getAssists() * 1.5
+ s.getShotsOnTarget() * 0.4
+ s.getShotsTotal() * 0.15;
}
/** 组织得分:关键传球*0.6 + 传球成功率*1.5 */
private static double calcCreation(PlayerStats s) {
return s.getKeyPasses() * 0.6
+ s.getPassAccuracy() * 1.5;
}
/** 防守得分:抢断*0.5 + 拦截*0.4 + 解围*0.3 */
private static double calcDefense(PlayerStats s) {
return s.getTackles() * 0.5
+ s.getInterceptions() * 0.4
+ s.getClearances() * 0.3;
}
/** 控球得分:触球*0.01 + 盘带成功率*1.2 */
private static double calcPossession(PlayerStats s) {
return s.getTouches() * 0.01
+ s.getDribbleAccuracy() * 1.2;
}
/** 纪律得分:犯规扣除,黄红牌重罚 */
private static double calcDiscipline(PlayerStats s) {
double score = 0;
score -= s.getFouls() * 0.1;
if (s.isYellowCard()) score -= 0.5;
if (s.isRedCard()) score -= 2.0;
return score;
}
private static double clamp(double v, double min, double max) {
return Math.max(min, Math.min(max, v));
}
}
测试类
package com.example.sofascore;
public class SofaScoreTest {
public static void main(String[] args) {
PlayerStats messi = new PlayerStats();
messi.setPlayerName("梅西");
messi.setPosition("RW");
messi.setGoals(2);
messi.setAssists(1);
messi.setShotsOnTarget(3);
messi.setShotsTotal(5);
messi.setKeyPasses(4);
messi.setPassesTotal(50);
messi.setPassesAccurate(45);
messi.setTackles(1);
messi.setInterceptions(0);
messi.setClearances(0);
messi.setTouches(65);
messi.setDribblesSuccess(6);
messi.setDribblesTotal(8);
messi.setFouls(1);
messi.setYellowCard(false);
double score = SofaScoreCalculator.calculate(messi);
System.out.printf("球员:%s 综合评分:%.1f%n",
messi.getPlayerName(), score);
}
}
输出示例:
球员:梅西 综合评分:10.0
批量统计多个球员
public static void batchReport(List<PlayerStats> players) {
players.stream()
.map(p -> new Object[]{p.getPlayerName(),
SofaScoreCalculator.calculate(p)})
.sorted((a, b) -> Double.compare((double)b[1], (double)a[1]))
.forEach(arr -> System.out.printf("%-10s → %.1f 分%n",
arr[0], arr[1]));
}
改进建议
-
按位置差异化权重
门将/后卫以防守为主,前锋以进攻为主,可按位置动态调整权重。 -
使用配置化参数
将权重和系数放到application.yml或数据库,便于调参。 -
引入归一化
如传球成功率用min(实际值 / 90%, 1.0)做封顶。 -
考虑比赛情境
领先/落后、对阵强弱队等可以增加浮动系数。 -
使用机器学习校准
若有 SofaScore 真实评分数据,可以用线性回归/决策树拟合权重,比人工设定更准。
如需按位置(门将/后卫/中场/前锋)分别计算,或对接真实 SofaScore API 数据解析,可以告诉我,我再扩展对应代码。