Java案例:统计犯规战术阻止反击次数
下面是一个完整的Java示例,模拟足球/篮球比赛中"犯规战术阻止反击"的统计场景。

场景说明
当对方发动快速反击(快攻)时,防守方采用战术犯规来阻止进攻,我们需要统计这种情况下犯规发生的次数。
完整代码实现
import java.util.*;
// 枚举:比赛事件类型
enum EventType {
FAST_BREAK, // 快速反击开始
TACTICAL_FOUL, // 战术犯规
NORMAL_FOUL, // 普通犯规
GOAL, // 进球
SHOT, // 射门
PASS // 传球
}
// 比赛事件类
class MatchEvent {
private int minute; // 比赛时间(分钟)
private String team; // 球队
private EventType type; // 事件类型
private String player; // 球员
public MatchEvent(int minute, String team, EventType type, String player) {
this.minute = minute;
this.team = team;
this.type = type;
this.player = player;
}
public int getMinute() { return minute; }
public String getTeam() { return team; }
public EventType getType() { return type; }
public String getPlayer() { return player; }
@Override
public String toString() {
return String.format("[%d'] %s - %s (%s)", minute, team, type, player);
}
}
// 统计结果类
class FoulStats {
private int totalTacticalFouls = 0; // 战术犯规总数
private int foulsStoppingFastBreak = 0; // 阻止反击的犯规次数
private Map<String, Integer> playerFouls = new HashMap<>(); // 各球员犯规次数
private List<MatchEvent> details = new ArrayList<>(); // 详细记录
public void addTacticalFoul(MatchEvent foul, boolean stoppFastBreak) {
totalTacticalFouls++;
playerFouls.merge(foul.getPlayer(), 1, Integer::sum);
details.add(foul);
if (stoppFastBreak) {
foulsStoppingFastBreak++;
}
}
public void printReport() {
System.out.println("========== 犯规战术统计报告 ==========");
System.out.println("战术犯规总次数: " + totalTacticalFouls);
System.out.println("阻止反击的犯规次数: " + foulsStoppingFastBreak);
System.out.println("\n各球员战术犯规次数:");
playerFouls.forEach((p, c) -> System.out.println(" " + p + ": " + c + " 次"));
System.out.println("\n详细记录:");
details.forEach(e -> System.out.println(" " + e));
System.out.println("=====================================");
}
public int getFoulsStoppingFastBreak() { return foulsStoppingFastBreak; }
}
// 主分析类
public class FoulTacticAnalyzer {
/**
* 核心逻辑:遍历事件流,识别"反击进行中"的战术犯规
* 规则:在 FastBreak 事件之后、FastBreak 结束(进球/射门/传球/普通犯规)之前,
* 如果发生 TACTICAL_FOUL,则视为"阻止反击的犯规"
*/
public static FoulStats analyze(List<MatchEvent> events) {
FoulStats stats = new FoulStats();
boolean inFastBreak = false;
for (MatchEvent event : events) {
switch (event.getType()) {
case FAST_BREAK:
inFastBreak = true;
break;
case TACTICAL_FOUL:
// 只有在快攻进行中发生的战术犯规才计入
stats.addTacticalFoul(event, inFastBreak);
if (inFastBreak) {
inFastBreak = false; // 犯规后反击被终止
}
break;
case GOAL:
case SHOT:
case NORMAL_FOUL:
case PASS:
// 这些事件会终止快攻状态
if (inFastBreak) {
inFastBreak = false;
}
break;
default:
break;
}
}
return stats;
}
public static void main(String[] args) {
List<MatchEvent> events = new ArrayList<>();
// 模拟一场比赛的事件流
events.add(new MatchEvent(10, "红队", EventType.PASS, "A"));
events.add(new MatchEvent(15, "蓝队", EventType.FAST_BREAK, "B"));
events.add(new MatchEvent(15, "红队", EventType.TACTICAL_FOUL, "C")); // ✅ 计入
events.add(new MatchEvent(25, "红队", EventType.FAST_BREAK, "D"));
events.add(new MatchEvent(26, "蓝队", EventType.SHOT, "E")); // 快攻结束(射门)
events.add(new MatchEvent(30, "蓝队", EventType.TACTICAL_FOUL, "F")); // ❌ 非快攻中,不计入反击
events.add(new MatchEvent(40, "红队", EventType.FAST_BREAK, "G"));
events.add(new MatchEvent(40, "蓝队", EventType.TACTICAL_FOUL, "H")); // ✅ 计入
events.add(new MatchEvent(55, "红队", EventType.FAST_BREAK, "I"));
events.add(new MatchEvent(55, "蓝队", EventType.NORMAL_FOUL, "J")); // 普通犯规,快攻结束
events.add(new MatchEvent(70, "蓝队", EventType.FAST_BREAK, "K"));
events.add(new MatchEvent(71, "红队", EventType.TACTICAL_FOUL, "L")); // ✅ 计入
events.add(new MatchEvent(80, "红队", EventType.FAST_BREAK, "M"));
events.add(new MatchEvent(80, "蓝队", EventType.GOAL, "N")); // 进球,快攻结束
FoulStats stats = analyze(events);
stats.printReport();
}
}
运行结果
========== 犯规战术统计报告 ==========
战术犯规总次数: 4
阻止反击的犯规次数: 3
各球员战术犯规次数:
C: 1 次
F: 1 次
H: 1 次
L: 1 次
详细记录:
[15'] 红队 - TACTICAL_FOUL (C)
[30'] 蓝队 - TACTICAL_FOUL (F)
[40'] 蓝队 - TACTICAL_FOUL (H)
[71'] 红队 - TACTICAL_FOUL (L)
=====================================
关键设计要点
| 设计点 | 说明 |
|---|---|
| 状态机 | 用 inFastBreak 布尔标志跟踪是否处于反击状态 |
| 事件驱动 | 遍历事件流,按类型切换状态 |
| 精准计数 | 只有 FAST_BREAK 之后、结束事件之前发生的 TACTICAL_FOUL 才计入 |
| 可扩展 | 可添加更多事件类型(如抢断、越位等)完善判断 |
扩展建议
- 多场比赛批量统计:将
analyze方法改为接受List<List<MatchEvent>>,累加结果。 - 时间窗口判断:如果快攻开始后超过 X 秒的犯规不算"阻止反击",可加入时间差判断(需事件带秒级时间戳)。
- 数据来源:实际可从 Opta、StatsBomb 等足球数据的 JSON/CSV 文件读取事件,替换硬编码列表。
- 可视化:用 JavaFX 或导出 CSV 再借助 Excel 生成柱状图展示各队犯规次数。
需要我扩展成从 JSON 文件读取或多场比赛汇总统计的版本吗?
版权声明:本站文章为原创整理,转载请注明出处。