java案例统计门球短传配合成功率?

wen java案例 3

本文目录导读:

java案例统计门球短传配合成功率?

  1. 系统设计
  2. 扩展功能建议
  3. 使用说明

下面我为您设计一个Java案例,用于统计门球(冰壶/地掷球类运动)比赛中短传配合的成功率。

系统设计

核心类结构

// 枚举:传球类型
enum PassType {
    SHORT_PASS("短传"),      // 短距离传球
    LONG_PASS("长传"),       // 长距离传球
    CROSS_PASS("横传");      // 横传
    private String desc;
    PassType(String desc) { this.desc = desc; }
    public String getDesc() { return desc; }
}
// 枚举:传球结果
enum PassResult {
    SUCCESS("成功"),
    FAILURE("失败"),
    INTERCEPTED("被拦截");
    private String desc;
    PassResult(String desc) { this.desc = desc; }
    public String getDesc() { return desc; }
}
// 球员类
class Player {
    private int id;
    private String name;
    private String position;  // 位置:前锋、中场、后卫
    public Player(int id, String name, String position) {
        this.id = id;
        this.name = name;
        this.position = position;
    }
    // getters and setters
    public int getId() { return id; }
    public String getName() { return name; }
    public String getPosition() { return position; }
}
// 传球事件类
class PassEvent {
    private Player passer;       // 传球者
    private Player receiver;     // 接球者
    private PassType passType;   // 传球类型
    private PassResult result;   // 传球结果
    private int distance;        // 传球距离(米)
    private String timestamp;    // 时间戳
    public PassEvent(Player passer, Player receiver, PassType passType, 
                    PassResult result, int distance, String timestamp) {
        this.passer = passer;
        this.receiver = receiver;
        this.passType = passType;
        this.result = result;
        this.distance = distance;
        this.timestamp = timestamp;
    }
    // getters
    public Player getPasser() { return passer; }
    public Player getReceiver() { return receiver; }
    public PassType getPassType() { return passType; }
    public PassResult getResult() { return result; }
    public int getDistance() { return distance; }
    public String getTimestamp() { return timestamp; }
}
// 球队类
class Team {
    private String teamName;
    private List<Player> players;
    private List<PassEvent> passEvents;
    public Team(String teamName) {
        this.teamName = teamName;
        this.players = new ArrayList<>();
        this.passEvents = new ArrayList<>();
    }
    public void addPlayer(Player player) {
        players.add(player);
    }
    public void addPassEvent(PassEvent event) {
        passEvents.add(event);
    }
    public String getTeamName() { return teamName; }
    public List<Player> getPlayers() { return players; }
    public List<PassEvent> getPassEvents() { return passEvents; }
}

统计服务类

import java.util.*;
import java.util.stream.Collectors;
public class PassStatisticsService {
    private Team team;
    public PassStatisticsService(Team team) {
        this.team = team;
    }
    // 获取短传成功率的统计算法
    public Map<String, Object> getShortPassStatistics() {
        Map<String, Object> stats = new HashMap<>();
        // 1. 获取所有短传事件
        List<PassEvent> shortPasses = team.getPassEvents().stream()
                .filter(event -> event.getPassType() == PassType.SHORT_PASS)
                .collect(Collectors.toList());
        // 2. 统计总数和成功数
        int totalPasses = shortPasses.size();
        long successfulPasses = shortPasses.stream()
                .filter(event -> event.getResult() == PassResult.SUCCESS)
                .count();
        long failedPasses = shortPasses.stream()
                .filter(event -> event.getResult() == PassResult.FAILURE)
                .count();
        long interceptedPasses = shortPasses.stream()
                .filter(event -> event.getResult() == PassResult.INTERCEPTED)
                .count();
        // 3. 计算成功率
        double successRate = 0;
        if (totalPasses > 0) {
            successRate = (double) successfulPasses / totalPasses * 100;
        }
        // 4. 按传球者统计
        Map<String, Integer> passerStats = new HashMap<>();
        Map<String, Integer> passerSuccessful = new HashMap<>();
        for (PassEvent event : shortPasses) {
            String passerName = event.getPasser().getName();
            passerStats.merge(passerName, 1, Integer::sum);
            if (event.getResult() == PassResult.SUCCESS) {
                passerSuccessful.merge(passerName, 1, Integer::sum);
            }
        }
        // 5. 按距离段统计
        Map<String, Integer> distanceStats = new HashMap<>();
        Map<String, Integer> distanceSuccessful = new HashMap<>();
        for (PassEvent event : shortPasses) {
            String distanceRange = getDistanceRange(event.getDistance());
            distanceStats.merge(distanceRange, 1, Integer::sum);
            if (event.getResult() == PassResult.SUCCESS) {
                distanceSuccessful.merge(distanceRange, 1, Integer::sum);
            }
        }
        // 组装统计结果
        stats.put("totalShortPasses", totalPasses);
        stats.put("successfulPasses", successfulPasses);
        stats.put("failedPasses", failedPasses);
        stats.put("interceptedPasses", interceptedPasses);
        stats.put("successRate", String.format("%.2f%%", successRate));
        stats.put("passerStats", passerStats);
        stats.put("passerSuccessful", passerSuccessful);
        stats.put("distanceStats", distanceStats);
        stats.put("distanceSuccessful", distanceSuccessful);
        return stats;
    }
    // 按球员统计短传成功率
    public Map<String, Object> getPlayerShortPassStats() {
        Map<String, Object> playerStats = new HashMap<>();
        Map<String, Integer> totalPasses = new HashMap<>();
        Map<String, Integer> successfulPasses = new HashMap<>();
        Map<String, Integer> failedPasses = new HashMap<>();
        Map<String, Integer> interceptedPasses = new HashMap<>();
        for (PassEvent event : team.getPassEvents()) {
            if (event.getPassType() != PassType.SHORT_PASS) {
                continue;
            }
            String playerName = event.getPasser().getName();
            // 统计总数
            totalPasses.merge(playerName, 1, Integer::sum);
            // 统计结果
            switch (event.getResult()) {
                case SUCCESS:
                    successfulPasses.merge(playerName, 1, Integer::sum);
                    break;
                case FAILURE:
                    failedPasses.merge(playerName, 1, Integer::sum);
                    break;
                case INTERCEPTED:
                    interceptedPasses.merge(playerName, 1, Integer::sum);
                    break;
            }
        }
        // 计算每个球员的成功率
        for (String playerName : totalPasses.keySet()) {
            int total = totalPasses.get(playerName);
            int success = successfulPasses.getOrDefault(playerName, 0);
            double rate = total > 0 ? (double) success / total * 100 : 0;
            Map<String, Object> playerInfo = new HashMap<>();
            playerInfo.put("total", total);
            playerInfo.put("success", success);
            playerInfo.put("failed", failedPasses.getOrDefault(playerName, 0));
            playerInfo.put("intercepted", interceptedPasses.getOrDefault(playerName, 0));
            playerInfo.put("successRate", String.format("%.2f%%", rate));
            playerStats.put(playerName, playerInfo);
        }
        return playerStats;
    }
    // 按传球组合统计
    public Map<String, Object> getPassCombinationStats() {
        Map<String, Object> combinationStats = new HashMap<>();
        Map<String, Integer> combinations = new HashMap<>();
        Map<String, Integer> successfulCombinations = new HashMap<>();
        for (PassEvent event : team.getPassEvents()) {
            if (event.getPassType() != PassType.SHORT_PASS) {
                continue;
            }
            String combination = event.getPasser().getName() + " -> " + 
                               event.getReceiver().getName();
            combinations.merge(combination, 1, Integer::sum);
            if (event.getResult() == PassResult.SUCCESS) {
                successfulCombinations.merge(combination, 1, Integer::sum);
            }
        }
        // 计算组合成功率
        Map<String, Double> combinationRates = new HashMap<>();
        for (Map.Entry<String, Integer> entry : combinations.entrySet()) {
            int total = entry.getValue();
            int success = successfulCombinations.getOrDefault(entry.getKey(), 0);
            double rate = total > 0 ? (double) success / total * 100 : 0;
            combinationRates.put(entry.getKey(), rate);
        }
        combinationStats.put("totalCombinations", combinations);
        combinationStats.put("successfulCombinations", successfulCombinations);
        combinationStats.put("combinationRates", combinationRates);
        return combinationStats;
    }
    // 辅助方法:获取距离范围
    private String getDistanceRange(int distance) {
        if (distance <= 5) return "0-5米";
        if (distance <= 10) return "5-10米";
        if (distance <= 15) return "10-15米";
        return "15米以上";
    }
}

主程序示例

import java.util.*;
import java.text.SimpleDateFormat;
public class Main {
    public static void main(String[] args) {
        // 创建球队
        Team team = new Team("门球一队");
        // 创建球员
        Player player1 = new Player(1, "张伟", "前锋");
        Player player2 = new Player(2, "李强", "前锋");
        Player player3 = new Player(3, "王浩", "中场");
        Player player4 = new Player(4, "赵明", "后卫");
        Player player5 = new Player(5, "孙立", "中场");
        team.addPlayer(player1);
        team.addPlayer(player2);
        team.addPlayer(player3);
        team.addPlayer(player4);
        team.addPlayer(player5);
        // 模拟传球数据
        addSamplePassEvents(team, player1, player2, player3, player4, player5);
        // 创建统计服务
        PassStatisticsService service = new PassStatisticsService(team);
        // 输出统计结果
        printStatistics(service, team);
    }
    private static void addSamplePassEvents(Team team, Player p1, Player p2, 
                                          Player p3, Player p4, Player p5) {
        // 模拟一些短传事件
        addPass(team, p1, p2, PassType.SHORT_PASS, PassResult.SUCCESS, 5, "12:00:01");
        addPass(team, p1, p3, PassType.SHORT_PASS, PassResult.SUCCESS, 8, "12:00:05");
        addPass(team, p2, p3, PassType.SHORT_PASS, PassResult.SUCCESS, 12, "12:00:10");
        addPass(team, p3, p1, PassType.SHORT_PASS, PassResult.FAILURE, 6, "12:00:15");
        addPass(team, p3, p4, PassType.SHORT_PASS, PassResult.SUCCESS, 10, "12:00:20");
        addPass(team, p4, p5, PassType.SHORT_PASS, PassResult.SUCCESS, 4, "12:00:25");
        addPass(team, p5, p1, PassType.SHORT_PASS, PassResult.INTERCEPTED, 9, "12:00:30");
        addPass(team, p1, p4, PassType.LONG_PASS, PassResult.SUCCESS, 20, "12:00:35");
        addPass(team, p2, p5, PassType.SHORT_PASS, PassResult.SUCCESS, 7, "12:00:40");
        addPass(team, p3, p2, PassType.SHORT_PASS, PassResult.SUCCESS, 11, "12:00:45");
        addPass(team, p4, p1, PassType.SHORT_PASS, PassResult.FAILURE, 13, "12:00:50");
        addPass(team, p5, p3, PassType.SHORT_PASS, PassResult.SUCCESS, 6, "12:00:55");
        addPass(team, p1, p5, PassType.SHORT_PASS, PassResult.SUCCESS, 10, "12:01:00");
        addPass(team, p2, p1, PassType.SHORT_PASS, PassResult.SUCCESS, 9, "12:01:05");
        addPass(team, p3, p4, PassType.SHORT_PASS, PassResult.INTERCEPTED, 14, "12:01:10");
        addPass(team, p4, p2, PassType.SHORT_PASS, PassResult.SUCCESS, 8, "12:01:15");
        addPass(team, p5, p4, PassType.SHORT_PASS, PassResult.SUCCESS, 12, "12:01:20");
        addPass(team, p2, p3, PassType.SHORT_PASS, PassResult.SUCCESS, 7, "12:01:25");
        addPass(team, p4, p5, PassType.LONG_PASS, PassResult.SUCCESS, 25, "12:01:30");
        addPass(team, p5, p2, PassType.SHORT_PASS, PassResult.FAILURE, 5, "12:01:35");
        addPass(team, p1, p2, PassType.SHORT_PASS, PassResult.SUCCESS, 10, "12:01:40");
        addPass(team, p3, p5, PassType.SHORT_PASS, PassResult.SUCCESS, 11, "12:01:45");
        addPass(team, p4, p1, PassType.SHORT_PASS, PassResult.SUCCESS, 13, "12:01:50");
        addPass(team, p2, p4, PassType.SHORT_PASS, PassResult.SUCCESS, 9, "12:01:55");
    }
    private static void addPass(Team team, Player passer, Player receiver, 
                              PassType type, PassResult result, int distance, String time) {
        team.addPassEvent(new PassEvent(passer, receiver, type, result, distance, time));
    }
    private static void printStatistics(PassStatisticsService service, Team team) {
        System.out.println("========== 门球短传配合成功率统计 ==========");
        System.out.println("球队: " + team.getTeamName());
        // 总统计
        Map<String, Object> generalStats = service.getShortPassStatistics();
        System.out.println("\n【总体统计】");
        System.out.println("总短传次数: " + generalStats.get("totalShortPasses"));
        System.out.println("成功次数: " + generalStats.get("successfulPasses"));
        System.out.println("失败次数: " + generalStats.get("failedPasses"));
        System.out.println("被拦截次数: " + generalStats.get("interceptedPasses"));
        System.out.println("总体短传成功率: " + generalStats.get("successRate"));
        // 球员统计
        System.out.println("\n【球员短传数据】");
        Map<String, Object> playerStats = service.getPlayerShortPassStats();
        System.out.printf("%-15s %-10s %-10s %-10s %-15s %s%n", 
                         "球员", "总传球", "成功", "失败", "被拦截", "成功率");
        for (Map.Entry<String, Object> entry : playerStats.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        // 传球组合统计
        System.out.println("\n【传球组合数据】");
        Map<String, Object> combinationStats = service.getPassCombinationStats();
        Map<String, Integer> total = (Map<String, Integer>) combinationStats.get("totalCombinations");
        Map<String, Integer> success = (Map<String, Integer>) combinationStats.get("successfulCombinations");
        Map<String, Double> rates = (Map<String, Double>) combinationStats.get("combinationRates");
        System.out.printf("%-25s %-10s %-10s %s%n", "组合", "总次数", "成功次数", "成功率");
        for (Map.Entry<String, Integer> entry : total.entrySet()) {
            String comb = entry.getKey();
            int totalCount = entry.getValue();
            int successCount = success.getOrDefault(comb, 0);
            double rate = rates.get(comb);
            System.out.printf("%-25s %-10s %-10s %.2f%%%n", 
                             comb, totalCount, successCount, rate);
        }
        // 距离统计
        System.out.println("\n【距离段成功率】");
        Map<String, Integer> distanceStats = (Map<String, Integer>) generalStats.get("distanceStats");
        Map<String, Integer> distanceSuccessful = (Map<String, Integer>) generalStats.get("distanceSuccessful");
        for (Map.Entry<String, Integer> entry : distanceStats.entrySet()) {
            String range = entry.getKey();
            int totalCount = entry.getValue();
            int successCount = distanceSuccessful.getOrDefault(range, 0);
            double rate = totalCount > 0 ? (double) successCount / totalCount * 100 : 0;
            System.out.printf("%-15s 总传球: %-5d 成功: %-5d 成功率: %.2f%%%n", 
                             range, totalCount, successCount, rate);
        }
    }
}

扩展功能建议

添加实时监控

// 实时监控短传成功率
public class RealTimeMonitor {
    private Timer timer;
    private PassStatisticsService service;
    public void startMonitoring() {
        timer = new Timer(true);
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                Map<String, Object> stats = service.getShortPassStatistics();
                // 实时显示统计结果
                displayStats(stats);
            }
        }, 0, 5000); // 每5秒更新一次
    }
}

数据持久化(MySQL)

// 数据库存储示例
public class PassDataDAO {
    private Connection connection;
    // 保存传球记录
    public void savePassEvent(PassEvent event) throws SQLException {
        String sql = "INSERT INTO pass_events " +
                    "(passer_id, receiver_id, pass_type, result, distance) " +
                    "VALUES (?, ?, ?, ?, ?)";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setInt(1, event.getPasser().getId());
            pstmt.setInt(2, event.getReceiver().getId());
            pstmt.setInt(3, event.getPassType().ordinal());
            pstmt.setInt(4, event.getResult().ordinal());
            pstmt.setInt(5, event.getDistance());
            pstmt.executeUpdate();
        }
    }
}

图形化展示(JFreeChart)

// 绘制成功率图表
public class ChartGenerator {
    public JFreeChart createSuccessRateChart(PassStatisticsService service) {
        Map<String, Object> stats = service.getShortPassStatistics();
        // 创建柱状图显示各球员成功率
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        // ...填充数据...
        JFreeChart chart = ChartFactory.createBarChart(
            "短传成功率统计",
            "球员",
            "成功率(%)",
            dataset
        );
        return chart;
    }
}

使用说明

  1. 编译运行

    javac Main.java
    java Main
  2. 预期输出

  • 总体统计信息
  • 各球员的短传数据
  • 不同传球组合的成功率
  • 不同距离段的成功率

这个案例提供了完整的短传配合成功率统计功能,可以根据实际需求扩展更多功能,如添加更多维度的统计、可视化展示、数据库持久化等。

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