java案例统计SofaScore综合评分?

wen java案例 3

本文目录导读:

java案例统计SofaScore综合评分?

  1. 完整的评分系统实现
  2. 关键特性说明

我理解您想了解如何使用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 优势特点

  1. 模块化设计: 易于扩展新维度
  2. 可配置权重: 可调整各维度的重要性
  3. 实时计算: 支持单场比赛和多场比赛统计
  4. 排行榜功能: 内置球员排名系统
  5. 详细报告: 生成完整的评分报告

3 适用场景

  • 球员转会评估
  • 赛季表现分析
  • 战术决策支持
  • 球迷数据分析
  • 游戏评分系统

这个实现提供了完整的SofaScore风格评分系统,您可以根据实际需求调整权重、添加新维度或修改评分规则。

抱歉,评论功能暂时关闭!