java案例统计斜长传精准度如何?

wen java案例 3

本文目录导读:

java案例统计斜长传精准度如何?

  1. 完整的斜长传精准度统计系统
  2. 功能说明
  3. 使用建议

我可以为您提供一个Java案例来统计斜长传(Diagonal Long Pass)的精准度,这个统计系统通常用于足球数据分析。

完整的斜长传精准度统计系统

import java.util.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 主类
public class DiagonalPassAccuracyAnalyzer {
    // 传球事件类
    static class PassEvent {
        private String playerName;
        private double startX, startY;      // 起始位置(球场坐标 0-105m x 0-68m)
        private double endX, endY;           // 结束位置
        private boolean isAccurate;          // 是否精准
        private LocalDateTime timestamp;     // 时间戳
        private String matchId;              // 比赛ID
        private String opposition;           // 对手
        public PassEvent(String playerName, double startX, double startY, 
                        double endX, double endY, boolean isAccurate, 
                        String matchId, String opposition) {
            this.playerName = playerName;
            this.startX = startX;
            this.startY = startY;
            this.endX = endX;
            this.endY = endY;
            this.isAccurate = isAccurate;
            this.timestamp = LocalDateTime.now();
            this.matchId = matchId;
            this.opposition = opposition;
        }
        // 计算传球距离
        public double getPassDistance() {
            return Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
        }
        // 判断是否为斜长传(自定义条件)
        public boolean isDiagonalLongPass(double minDistance) {
            if (getPassDistance() < minDistance) return false;
            // 计算从出发点到终点的方向向量
            double dx = endX - startX;
            double dy = endY - startY;
            // 判断是否为斜向传球(与水平或垂直方向夹角大于30度)
            double angle = Math.abs(Math.atan2(dy, dx));
            return angle > Math.toRadians(30) && angle < Math.toRadians(150);
        }
        // getters and setters
        public String getPlayerName() { return playerName; }
        public boolean isAccurate() { return isAccurate; }
        public String getMatchId() { return matchId; }
        public String getOpposition() { return opposition; }
    }
    // 统计结果类
    static class StatisticsResult {
        private int totalPasses;
        private int accuratePasses;
        private double accuracyRate;
        private double averageDistance;
        private Map<String, PlayerStats> playerStatsMap;
        private Map<String, MatchStats> matchStatsMap;
        public StatisticsResult() {
            playerStatsMap = new HashMap<>();
            matchStatsMap = new HashMap<>();
        }
        // getters and setters
        public int getTotalPasses() { return totalPasses; }
        public void setTotalPasses(int totalPasses) { this.totalPasses = totalPasses; }
        public int getAccuratePasses() { return accuratePasses; }
        public void setAccuratePasses(int accuratePasses) { this.accuratePasses = accuratePasses; }
        public double getAccuracyRate() { return accuracyRate; }
        public void setAccuracyRate(double accuracyRate) { this.accuracyRate = accuracyRate; }
        public double getAverageDistance() { return averageDistance; }
        public void setAverageDistance(double averageDistance) { this.averageDistance = averageDistance; }
        public Map<String, PlayerStats> getPlayerStatsMap() { return playerStatsMap; }
        public Map<String, MatchStats> getMatchStatsMap() { return matchStatsMap; }
    }
    // 球员统计类
    static class PlayerStats {
        private String playerName;
        private int totalPasses;
        private int accuratePasses;
        private double accuracyRate;
        private double totalDistance;
        public PlayerStats(String playerName) {
            this.playerName = playerName;
        }
        public void addPass(PassEvent event) {
            totalPasses++;
            if (event.isAccurate()) {
                accuratePasses++;
            }
            totalDistance += event.getPassDistance();
        }
        public void calculateAccuracyRate() {
            accuracyRate = totalPasses > 0 ? 
                (double) accuratePasses / totalPasses * 100 : 0;
        }
        // getters
        public String getPlayerName() { return playerName; }
        public int getTotalPasses() { return totalPasses; }
        public int getAccuratePasses() { return accuratePasses; }
        public double getAccuracyRate() { return accuracyRate; }
        public double getTotalDistance() { return totalDistance; }
        public double getAverageDistance() { 
            return totalPasses > 0 ? totalDistance / totalPasses : 0; 
        }
    }
    // 比赛统计类
    static class MatchStats {
        private String matchId;
        private String opposition;
        private int totalPasses;
        private int accuratePasses;
        private double accuracyRate;
        public MatchStats(String matchId, String opposition) {
            this.matchId = matchId;
            this.opposition = opposition;
        }
        public void addPass(PassEvent event) {
            totalPasses++;
            if (event.isAccurate()) {
                accuratePasses++;
            }
        }
        public void calculateAccuracyRate() {
            accuracyRate = totalPasses > 0 ? 
                (double) accuratePasses / totalPasses * 100 : 0;
        }
        // getters
        public String getMatchId() { return matchId; }
        public String getOpposition() { return opposition; }
        public int getTotalPasses() { return totalPasses; }
        public int getAccuratePasses() { return accuratePasses; }
        public double getAccuracyRate() { return accuracyRate; }
    }
    // 分析器类
    static class PassAnalyzer {
        private List<PassEvent> passEvents;
        private double minLongPassDistance;
        public PassAnalyzer(double minLongPassDistance) {
            this.passEvents = new ArrayList<>();
            this.minLongPassDistance = minLongPassDistance;
        }
        public void addPassEvent(PassEvent event) {
            if (event.isDiagonalLongPass(minLongPassDistance)) {
                passEvents.add(event);
            }
        }
        public StatisticsResult analyze() {
            StatisticsResult result = new StatisticsResult();
            if (passEvents.isEmpty()) {
                result.setTotalPasses(0);
                result.setAccuracyRate(0);
                return result;
            }
            result.setTotalPasses(passEvents.size());
            // 计算整体统计数据
            int accuratePasses = 0;
            double totalDistance = 0;
            for (PassEvent event : passEvents) {
                if (event.isAccurate()) {
                    accuratePasses++;
                }
                totalDistance += event.getPassDistance();
                // 更新球员统计
                String playerName = event.getPlayerName();
                PlayerStats playerStats = result.getPlayerStatsMap()
                    .computeIfAbsent(playerName, PlayerStats::new);
                playerStats.addPass(event);
                // 更新比赛统计
                String matchId = event.getMatchId();
                MatchStats matchStats = result.getMatchStatsMap()
                    .computeIfAbsent(matchId, 
                        k -> new MatchStats(matchId, event.getOpposition()));
                matchStats.addPass(event);
            }
            result.setAccuratePasses(accuratePasses);
            result.setAccuracyRate((double) accuratePasses / passEvents.size() * 100);
            result.setAverageDistance(totalDistance / passEvents.size());
            // 计算各球员和比赛的精准率
            for (PlayerStats stats : result.getPlayerStatsMap().values()) {
                stats.calculateAccuracyRate();
            }
            for (MatchStats stats : result.getMatchStatsMap().values()) {
                stats.calculateAccuracyRate();
            }
            return result;
        }
        public List<PassEvent> getPassEvents() {
            return passEvents;
        }
    }
    // 报告生成器
    static class ReportGenerator {
        public void generateReport(StatisticsResult result) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            System.out.println("========================================");
            System.out.println("    斜长传精准度统计报告");
            System.out.println("    生成时间: " + LocalDateTime.now().format(formatter));
            System.out.println("========================================\n");
            // 总体统计
            System.out.println("【总体统计】");
            System.out.printf("总传球次数: %d%n", result.getTotalPasses());
            System.out.printf("精准传球次数: %d%n", result.getAccuratePasses());
            System.out.printf("精准率: %.2f%%%n", result.getAccuracyRate());
            System.out.printf("平均距离: %.2f米%n", result.getAverageDistance());
            System.out.println();
            // 球员统计
            System.out.println("【球员统计】");
            System.out.println("----------------------------------------");
            System.out.printf("%-15s %-8s %-8s %-10s%n", 
                "球员名称", "总传球", "精准传球", "精准率(%)");
            System.out.println("----------------------------------------");
            result.getPlayerStatsMap().values().stream()
                .sorted((s1, s2) -> Double.compare(s2.getAccuracyRate(), s1.getAccuracyRate()))
                .forEach(stats -> {
                    System.out.printf("%-15s %-8d %-8d %-10.2f%n",
                        stats.getPlayerName(),
                        stats.getTotalPasses(),
                        stats.getAccuratePasses(),
                        stats.getAccuracyRate());
                });
            System.out.println();
            // 比赛统计
            System.out.println("【比赛统计】");
            System.out.println("----------------------------------------");
            System.out.printf("%-15s %-15s %-10s %-10s %-10s%n",
                "比赛ID", "对手", "总传球", "精准传球", "精准率(%)");
            System.out.println("----------------------------------------");
            result.getMatchStatsMap().values().forEach(stats -> {
                System.out.printf("%-15s %-15s %-10d %-10d %-10.2f%n",
                    stats.getMatchId(),
                    stats.getOpposition(),
                    stats.getTotalPasses(),
                    stats.getAccuratePasses(),
                    stats.getAccuracyRate());
            });
            System.out.println("\n========================================\n");
        }
    }
    // 主测试方法
    public static void main(String[] args) {
        // 创建分析器,设置最小长传距离为30米
        PassAnalyzer analyzer = new PassAnalyzer(30);
        // 模拟一些斜长传数据
        // 示例数据(球员姓名,起始X, 起始Y, 结束X, 结束Y, 是否精准,比赛ID,对手)
        // 球员A的数据
        analyzer.addPassEvent(new PassEvent("球员A", 20, 30, 70, 55, true, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员A", 25, 25, 80, 60, true, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员A", 15, 35, 75, 50, false, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员A", 30, 20, 85, 65, true, "M002", "对手Y"));
        // 球员B的数据
        analyzer.addPassEvent(new PassEvent("球员B", 10, 40, 60, 55, true, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员B", 18, 45, 65, 70, false, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员B", 12, 42, 58, 48, true, "M002", "对手Y"));
        analyzer.addPassEvent(new PassEvent("球员B", 20, 38, 70, 62, true, "M002", "对手Y"));
        analyzer.addPassEvent(new PassEvent("球员B", 16, 44, 62, 50, false, "M002", "对手Y"));
        // 球员C的数据
        analyzer.addPassEvent(new PassEvent("球员C", 35, 25, 85, 45, true, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员C", 28, 30, 90, 40, true, "M001", "对手X"));
        analyzer.addPassEvent(new PassEvent("球员C", 32, 28, 88, 35, true, "M002", "对手Y"));
        // 添加一些非斜长传的数据(应该被过滤掉)
        analyzer.addPassEvent(new PassEvent("球员A", 10, 30, 45, 32, true, "M001", "对手X")); // 短传
        analyzer.addPassEvent(new PassEvent("球员B", 20, 30, 90, 30, true, "M001", "对手X")); // 直传
        // 分析数据
        PassAnalyzer.AnalyzerResult result = analyzer.analyze();  // 注意:这里需要修改analyze方法返回类型
        // 生成报告
        ReportGenerator reportGenerator = new ReportGenerator();
        reportGenerator.generateReport(result);
        // 输出过滤后的传球事件
        System.out.println("过滤后的有效斜长传次数: " + result.getTotalPasses());
    }
}

功能说明

核心功能

  • 收集和统计斜长传数据
  • 计算整体精准率、平均传球距离
  • 按球员和比赛分类统计
  • 生成详细的分析报告

判断标准

  • 斜长传定义
    • 距离超过最小值(可配置)
    • 传球方向与垂直/水平方向夹角在30°-150°之间

统计维度

  • 总体统计:所有斜长传的总数和精准率
  • 球员统计:每个球员的表现
  • 比赛统计:单场比赛的表现

输出格式

  • 清晰的表格展示
  • 按精准率排序

使用建议

可以根据实际需求调整:

  • minLongPassDistance:最小长传距离阈值
  • isDiagonalLongPass():斜向判断的角度范围
  • 添加更多统计维度(如区域分析、战术分析等)

这个系统可以直接用于足球比赛数据分析,或者作为更大数据分析系统的一部分。

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