本文目录导读:

我理解您想了解如何使用Java来统计类似SofaScore的综合评分,SofaScore的评分系统基于多个维度的加权计算,下面我会提供一个完整的Java实现示例。
完整的评分系统实现
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
/**
* SofaScore风格的球员综合评分系统
*/
public class SofaScoreRatingSystem {
// 评分维度及权重配置
private static final Map<RatingDimension, Double> DIMENSION_WEIGHTS = new LinkedHashMap<>();
static {
// 配置各维度权重(总和为1.0)
DIMENSION_WEIGHTS.put(RatingDimension.ATTACK, 0.15);
DIMENSION_WEIGHTS.put(RatingDimension.DEFENSE, 0.10);
DIMENSION_WEIGHTS.put(RatingDimension.PASSING, 0.15);
DIMENSION_WEIGHTS.put(RatingDimension.DRIBBLING, 0.10);
DIMENSION_WEIGHTS.put(RatingDimension.SHOOTING, 0.15);
DIMENSION_WEIGHTS.put(RatingDimension.PHYSICAL, 0.10);
DIMENSION_WEIGHTS.put(RatingDimension.MENTAL, 0.10);
DIMENSION_WEIGHTS.put(RatingDimension.CONSISTENCY, 0.05);
DIMENSION_WEIGHTS.put(RatingDimension.MATCH_IMPACT, 0.10);
}
/**
* 评分维度枚举
*/
public enum RatingDimension {
ATTACK("进攻"),
DEFENSE("防守"),
PASSING("传球"),
DRIBBLING("盘带"),
SHOOTING("射门"),
PHYSICAL("身体"),
MENTAL("心理"),
CONSISTENCY("稳定性"),
MATCH_IMPACT("比赛影响力");
private final String description;
RatingDimension(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
/**
* 球员评分数据类
*/
public static class PlayerRating {
private String playerId;
private String playerName;
private Map<RatingDimension, Double> dimensionRatings;
private double overallRating;
private int matchCount;
public PlayerRating(String playerId, String playerName) {
this.playerId = playerId;
this.playerName = playerName;
this.dimensionRatings = new EnumMap<>(RatingDimension.class);
this.matchCount = 0;
}
// Getter/Setter方法
public String getPlayerId() { return playerId; }
public String getPlayerName() { return playerName; }
public Map<RatingDimension, Double> getDimensionRatings() { return dimensionRatings; }
public double getOverallRating() { return overallRating; }
public int getMatchCount() { return matchCount; }
public void setOverallRating(double overallRating) {
this.overallRating = overallRating;
}
public void setMatchCount(int matchCount) {
this.matchCount = matchCount;
}
}
/**
* 单场比赛数据
*/
public static class MatchData {
private String playerId;
private String matchId;
private int goals;
private int assists;
private int shots;
private int passes;
private int successfulPasses;
private int tackles;
private int interceptions;
private int dribbles;
private int successfulDribbles;
private int minutesPlayed;
private int foulsCommitted;
private int wonDuels;
private int lostDuels;
private boolean cleanSheet;
private boolean scoredBraces;
private boolean scoredHatTrick;
private boolean starPerformer;
// 构造器和getter/setter
public MatchData(String playerId, String matchId) {
this.playerId = playerId;
this.matchId = matchId;
}
// Getters and Setters
public String getPlayerId() { return playerId; }
public String getMatchId() { return matchId; }
public int getGoals() { return goals; }
public void setGoals(int goals) { this.goals = goals; }
public int getAssists() { return assists; }
public void setAssists(int assists) { this.assists = assists; }
public int getShots() { return shots; }
public void setShots(int shots) { this.shots = shots; }
public int getPasses() { return passes; }
public void setPasses(int passes) { this.passes = passes; }
public int getSuccessfulPasses() { return successfulPasses; }
public void setSuccessfulPasses(int successfulPasses) { this.successfulPasses = successfulPasses; }
public int getTackles() { return tackles; }
public void setTackles(int tackles) { this.tackles = tackles; }
public int getInterceptions() { return interceptions; }
public void setInterceptions(int interceptions) { this.interceptions = interceptions; }
public int getDribbles() { return dribbles; }
public void setDribbles(int dribbles) { this.dribbles = dribbles; }
public int getSuccessfulDribbles() { return successfulDribbles; }
public void setSuccessfulDribbles(int successfulDribbles) { this.successfulDribbles = successfulDribbles; }
public int getMinutesPlayed() { return minutesPlayed; }
public void setMinutesPlayed(int minutesPlayed) { this.minutesPlayed = minutesPlayed; }
public int getFoulsCommitted() { return foulsCommitted; }
public void setFoulsCommitted(int foulsCommitted) { this.foulsCommitted = foulsCommitted; }
public int getWonDuels() { return wonDuels; }
public void setWonDuels(int wonDuels) { this.wonDuels = wonDuels; }
public int getLostDuels() { return lostDuels; }
public void setLostDuels(int lostDuels) { this.lostDuels = lostDuels; }
public boolean isCleanSheet() { return cleanSheet; }
public void setCleanSheet(boolean cleanSheet) { this.cleanSheet = cleanSheet; }
public boolean isScoredBraces() { return scoredBraces; }
public void setScoredBraces(boolean scoredBraces) { this.scoredBraces = scoredBraces; }
public boolean isScoredHatTrick() { return scoredHatTrick; }
public void setScoredHatTrick(boolean scoredHatTrick) { this.scoredHatTrick = scoredHatTrick; }
public boolean isStarPerformer() { return starPerformer; }
public void setStarPerformer(boolean starPerformer) { this.starPerformer = starPerformer; }
}
/**
* 评分计算器接口
*/
public interface RatingCalculator {
double calculateDimensionRating(RatingDimension dimension, List<MatchData> matches);
double calculateOverallRating(Map<RatingDimension, Double> dimensionRatings);
}
/**
* 默认评分计算器实现
*/
public static class DefaultRatingCalculator implements RatingCalculator {
@Override
public double calculateDimensionRating(RatingDimension dimension, List<MatchData> matches) {
double totalScore = 0.0;
double maxScore = 0.0;
for (MatchData match : matches) {
double matchRating = calculateMatchDimensionRating(dimension, match);
totalScore += matchRating;
maxScore = Math.max(maxScore, matchRating);
}
// 平均分与最佳表现的加权
double avgScore = totalScore / Math.max(1, matches.size());
return Math.min(10.0, avgScore * 0.6 + maxScore * 0.4);
}
private double calculateMatchDimensionRating(RatingDimension dimension, MatchData match) {
double rating = 5.0; // 基础分
// 根据维度计算
switch (dimension) {
case ATTACK:
rating += match.getGoals() * 1.5;
rating += match.getAssists() * 1.0;
rating += (match.getShots() * 0.3);
break;
case DEFENSE:
rating += match.getTackles() * 0.8;
rating += match.getInterceptions() * 0.6;
rating -= match.getFoulsCommitted() * 0.2;
if (match.isCleanSheet()) rating += 0.5;
break;
case PASSING:
double passAccuracy = match.getPasses() > 0 ?
(double) match.getSuccessfulPasses() / match.getPasses() : 0;
rating += match.getSuccessfulPasses() * 0.1;
rating += passAccuracy * 2.0;
break;
case DRIBBLING:
double dribbleSuccess = match.getDribbles() > 0 ?
(double) match.getSuccessfulDribbles() / match.getDribbles() : 0;
rating += match.getSuccessfulDribbles() * 0.8;
rating += dribbleSuccess * 1.5;
break;
case SHOOTING:
double shotAccuracy = match.getShots() > 0 ?
(double) match.getGoals() / match.getShots() : 0;
rating += match.getGoals() * 1.8;
rating += shotAccuracy * 2.0;
if (match.isScoredBraces()) rating += 1.0;
if (match.isScoredHatTrick()) rating += 2.0;
break;
case PHYSICAL:
rating += match.getWonDuels() * 0.4;
rating -= match.getLostDuels() * 0.2;
rating += Math.min(match.getMinutesPlayed() * 0.01, 2.0);
break;
case MENTAL:
rating += match.isStarPerformer() ? 1.5 : 0;
rating += Math.min(match.getMinutesPlayed() * 0.02, 1.0);
break;
case CONSISTENCY:
rating += Math.min(match.getShots() + match.getPasses() +
match.getTackles() + match.getDribbles(), 10) * 0.1;
break;
case MATCH_IMPACT:
rating += (match.getGoals() + match.getAssists()) * 2.0;
rating += match.isStarPerformer() ? 1.0 : 0;
if (match.isScoredHatTrick()) rating += 2.0;
if (match.isScoredBraces()) rating += 1.0;
break;
}
// 限制在0-10范围内
return Math.max(0, Math.min(10, rating));
}
@Override
public double calculateOverallRating(Map<RatingDimension, Double> dimensionRatings) {
double totalWeightedRating = 0.0;
for (Map.Entry<RatingDimension, Double> entry : dimensionRatings.entrySet()) {
double weight = DIMENSION_WEIGHTS.getOrDefault(entry.getKey(), 0.0);
totalWeightedRating += entry.getValue() * weight;
}
// 保留2位小数
BigDecimal result = new BigDecimal(totalWeightedRating)
.setScale(2, RoundingMode.HALF_UP);
return result.doubleValue();
}
}
/**
* 评分统计服务
*/
public static class RatingStatisticsService {
private final RatingCalculator calculator;
private final Map<String, List<MatchData>> playerMatches = new HashMap<>();
public RatingStatisticsService(RatingCalculator calculator) {
this.calculator = calculator;
}
public void addMatchData(MatchData match) {
playerMatches.computeIfAbsent(match.getPlayerId(), k -> new ArrayList<>())
.add(match);
}
/**
* 计算单个球员的综合评分
*/
public PlayerRating calculatePlayerRating(String playerId, String playerName) {
List<MatchData> matches = playerMatches.getOrDefault(playerId, List.of());
PlayerRating rating = new PlayerRating(playerId, playerName);
if (matches.isEmpty()) {
rating.setMatchCount(0);
return rating;
}
// 计算各维度评分
for (RatingDimension dimension : RatingDimension.values()) {
double dimensionRating = calculator.calculateDimensionRating(dimension, matches);
rating.getDimensionRatings().put(dimension, dimensionRating);
}
// 计算综合评分
rating.setOverallRating(calculator.calculateOverallRating(rating.getDimensionRatings()));
rating.setMatchCount(matches.size());
return rating;
}
/**
* 计算所有球员的评分排行
*/
public List<PlayerRating> getRatingLeaderboard() {
return playerMatches.keySet().stream()
.map(playerId -> {
// 假设playerName需要从其他数据源获取
// 这里用一个简单的方式生成
String playerName = "Player " + playerId;
return calculatePlayerRating(playerId, playerName);
})
.sorted((p1, p2) -> Double.compare(p2.getOverallRating(), p1.getOverallRating()))
.collect(Collectors.toList());
}
/**
* 获取球员最佳维度评分
*/
public RatingDimension getBestDimension(PlayerRating rating) {
return rating.getDimensionRatings().entrySet().stream()
.max(Map.Entry.comparingByValue())
.map(Map.Entry::getKey)
.orElse(RatingDimension.CONSISTENCY);
}
/**
* 生成评分报告
*/
public String generateRatingReport(String playerId, String playerName) {
PlayerRating rating = calculatePlayerRating(playerId, playerName);
StringBuilder report = new StringBuilder();
report.append("SofaScore综合评分报告\n");
report.append("=".repeat(40)).append("\n");
report.append("球员: ").append(playerName).append("\n");
report.append("比赛场次: ").append(rating.getMatchCount()).append("\n");
report.append("综合评分: ").append(rating.getOverallRating()).append("\n\n");
report.append("维度评分明细:\n");
report.append("-".repeat(40)).append("\n");
rating.getDimensionRatings().entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEach(entry -> {
report.append(String.format("%-10s: %.2f%n",
entry.getKey().getDescription(), entry.getValue()));
});
report.append("\n最佳维度: ").append(getBestDimension(rating).getDescription());
return report.toString();
}
}
/**
* 测试类
*/
public static void main(String[] args) {
// 创建评分服务
RatingStatisticsService service = new RatingStatisticsService(new DefaultRatingCalculator());
// 创建示例比赛数据
// 球员1 - 表现出色
MatchData match1 = createMatchData("1", "match1");
match1.setGoals(2);
match1.setAssists(1);
match1.setShots(5);
match1.setPasses(45);
match1.setSuccessfulPasses(40);
match1.setTackles(3);
match1.setInterceptions(2);
match1.setDribbles(8);
match1.setSuccessfulDribbles(6);
match1.setMinutesPlayed(90);
match1.setWonDuels(8);
match1.setLostDuels(3);
match1.setStarPerformer(true);
match1.setScoredBraces(true);
service.addMatchData(match1);
MatchData match2 = createMatchData("1", "match2");
match2.setGoals(1);
match2.setShots(4);
match2.setPasses(52);
match2.setSuccessfulPasses(48);
match2.setTackles(2);
match2.setInterceptions(1);
match2.setDribbles(5);
match2.setSuccessfulDribbles(4);
match2.setMinutesPlayed(85);
match2.setWonDuels(5);
match2.setLostDuels(2);
service.addMatchData(match2);
// 球员2 - 表现一般
MatchData match3 = createMatchData("2", "match1");
match3.setShots(2);
match3.setPasses(40);
match3.setSuccessfulPasses(35);
match3.setTackles(4);
match3.setInterceptions(3);
match3.setDribbles(3);
match3.setSuccessfulDribbles(2);
match3.setMinutesPlayed(88);
match3.setWonDuels(3);
match3.setLostDuels(5);
service.addMatchData(match3);
MatchData match4 = createMatchData("2", "match2");
match4.setShots(3);
match4.setAssists(1);
match4.setPasses(38);
match4.setSuccessfulPasses(33);
match4.setTackles(2);
match4.setInterceptions(2);
match4.setDribbles(4);
match4.setSuccessfulDribbles(3);
match4.setMinutesPlayed(78);
match4.setWonDuels(2);
match4.setLostDuels(4);
service.addMatchData(match4);
// 生成评分报告
System.out.println(service.generateRatingReport("1", "梅西"));
System.out.println("\n");
System.out.println(service.generateRatingReport("2", "普通球员"));
System.out.println("\n");
// 排行榜
System.out.println("球员评分排行榜:");
service.getRatingLeaderboard().forEach(r ->
System.out.printf("%s: %.2f (比赛%d场)%n",
r.getPlayerName(), r.getOverallRating(), r.getMatchCount()));
}
private static MatchData createMatchData(String playerId, String matchId) {
return new MatchData(playerId, matchId);
}
}
关键特性说明
1 评分维度
- 进攻: 进球、助攻、射门次数
- 防守: 抢断、拦截、犯规
- 传球: 传球成功率、传球次数
- 盘带: 成功盘带次数、突破成功率
- 射门: 射门转化率、帽子戏法等奖励
- 身体: 对抗胜利、出场时间
- 心理: 关键时刻表现
- 稳定性: 综合数据稳定性
- 比赛影响力: 对比赛结果的关键影响
2 优势特点
- 模块化设计: 易于扩展新维度
- 可配置权重: 可调整各维度的重要性
- 实时计算: 支持单场比赛和多场比赛统计
- 排行榜功能: 内置球员排名系统
- 详细报告: 生成完整的评分报告
3 适用场景
- 球员转会评估
- 赛季表现分析
- 战术决策支持
- 球迷数据分析
- 游戏评分系统
这个实现提供了完整的SofaScore风格评分系统,您可以根据实际需求调整权重、添加新维度或修改评分规则。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播