本文目录导读:

我来设计一个综合的Java案例,模拟点球大战并对比两名球员的命中率,这个案例会涵盖面向对象、集合、随机数、统计等多个知识点。
完整代码实现
import java.util.*;
import java.util.stream.Collectors;
/**
* 点球命中率对比系统
* 模拟10000次点球大战,统计两名球员的命中率
*/
public class PenaltyShootoutSimulator {
// 球员类
static class Player {
private String name;
private double skillLevel; // 技术能力 0-1
private double pressureResistance; // 抗压能力 0-1
private int shots;
private int goals;
private List<ShootRecord> records = new ArrayList<>();
public Player(String name, double skillLevel, double pressureResistance) {
this.name = name;
this.skillLevel = skillLevel;
this.pressureResistance = pressureResistance;
}
// 执行一次射门
public boolean shoot(int round, int pressureLevel) {
// 基础命中率 = 技术能力 + 抗压能力 * 0.5 - 压力影响
double baseProbability = skillLevel * 0.7 + pressureResistance * 0.3;
double pressureReduction = pressureLevel * 0.05;
double finalProbability = Math.max(0, Math.min(1, baseProbability - pressureReduction));
boolean isGoal = Math.random() < finalProbability;
// 记录
records.add(new ShootRecord(round, pressureLevel, isGoal, finalProbability));
shots++;
if (isGoal) goals++;
return isGoal;
}
public double getHitRate() {
return shots == 0 ? 0 : (double) goals / shots;
}
public int getShots() { return shots; }
public int getGoals() { return goals; }
public String getName() { return name; }
public double getSkillLevel() { return skillLevel; }
public double getPressureResistance() { return pressureResistance; }
public List<ShootRecord> getRecords() { return records; }
}
// 射门记录类
static class ShootRecord {
private int round;
private int pressureLevel;
private boolean goal;
private double probability;
public ShootRecord(int round, int pressureLevel, boolean goal, double probability) {
this.round = round;
this.pressureLevel = pressureLevel;
this.goal = goal;
this.probability = probability;
}
@Override
public String toString() {
return String.format("第%d轮(压力%d级): %s (命中概率%.1f%%)",
round, pressureLevel, goal ? "⚽进球" : "❌射失", probability * 100);
}
}
// 比赛结果类
static class MatchResult {
private String player1Name;
private String player2Name;
private int player1Goals;
private int player2Goals;
private int totalShots;
private Player winner;
public MatchResult(String player1Name, String player2Name,
int player1Goals, int player2Goals, int totalShots) {
this.player1Name = player1Name;
this.player2Name = player2Name;
this.player1Goals = player1Goals;
this.player2Goals = player2Goals;
this.totalShots = totalShots;
this.winner = player1Goals > player2Goals ?
new Player(player1Name, 0, 0) :
new Player(player2Name, 0, 0);
}
@Override
public String toString() {
String winnerName = player1Goals > player2Goals ? player1Name : player2Name;
return String.format("%s %d : %d %s (共%d次射门)",
player1Name, player1Goals, player2Goals, player2Name, totalShots);
}
}
/**
* 模拟一场点球大战(5轮制,若平局则突然死亡)
*/
public static MatchResult simulateMatch(Player player1, Player player2) {
int p1Goals = 0, p2Goals = 0;
int round = 0;
final int MAX_REGULAR_ROUNDS = 5;
while (true) {
round++;
int pressureLevel = round; // 压力随着轮次增加
// 常规5轮
if (round <= MAX_REGULAR_ROUNDS) {
boolean goal1 = player1.shoot(round, pressureLevel);
boolean goal2 = player2.shoot(round, pressureLevel);
if (goal1) p1Goals++;
if (goal2) p2Goals++;
// 判断是否提前结束(领先分数不可超越)
int remaining = MAX_REGULAR_ROUNDS - round;
if (remaining > 0) {
if (p1Goals > p2Goals + remaining) {
return new MatchResult(player1.getName(), player2.getName(),
p1Goals, p2Goals, round * 2);
}
if (p2Goals > p1Goals + remaining) {
return new MatchResult(player1.getName(), player2.getName(),
p1Goals, p2Goals, round * 2);
}
}
// 常规轮结束且平局
if (round == MAX_REGULAR_ROUNDS && p1Goals == p2Goals) {
// 进入突然死亡
continue;
}
// 常规轮结束且分胜负
if (round == MAX_REGULAR_ROUNDS && p1Goals != p2Goals) {
return new MatchResult(player1.getName(), player2.getName(),
p1Goals, p2Goals, round * 2);
}
}
// 突然死亡阶段
else {
boolean goal1 = player1.shoot(round, pressureLevel + 5);
boolean goal2 = player2.shoot(round, pressureLevel + 5);
if (goal1) p1Goals++;
if (goal2) p2Goals++;
// 突然死亡:一人进另一人没进
if (goal1 != goal2) {
return new MatchResult(player1.getName(), player2.getName(),
p1Goals, p2Goals, round * 2);
}
}
}
}
/**
* 统计对比器
*/
static class StatisticsComparator {
private Player player1;
private Player player2;
public StatisticsComparator(Player player1, Player player2) {
this.player1 = player1;
this.player2 = player2;
}
public void generateDetailedReport() {
System.out.println("\n" + "=".repeat(80));
System.out.println(" 点球大战详细对比分析报告");
System.out.println("=".repeat(80));
printPlayerInfo(player1);
printPlayerInfo(player2);
printRoundAnalysis();
printPressureAnalysis();
printFinalComparison();
}
private void printPlayerInfo(Player player) {
System.out.printf("\n球员: %s%n", player.getName());
System.out.printf(" 技术能力: %.2f%n", player.getSkillLevel());
System.out.printf(" 抗压能力: %.2f%n", player.getPressureResistance());
System.out.printf(" 总射门: %d次 | 总进球: %d个 | 命中率: %.2f%%%n",
player.getShots(), player.getGoals(), player.getHitRate() * 100);
}
private void printRoundAnalysis() {
System.out.println("\n ⚽ 各轮次射门详细记录");
System.out.println(" " + "-".repeat(50));
for (int i = 1; i <= Math.max(
player1.getRecords().size(), player2.getRecords().size()) / 2; i++) {
System.out.printf(" 第%d轮:%n", i);
player1.getRecords().stream()
.filter(r -> r.round == i)
.forEach(r -> System.out.printf(" %s: %s%n", player1.getName(), r));
player2.getRecords().stream()
.filter(r -> r.round == i)
.forEach(r -> System.out.printf(" %s: %s%n", player2.getName(), r));
}
}
private void printPressureAnalysis() {
System.out.println("\n 📊 压力等级分析");
System.out.println(" " + "-".repeat(50));
Map<Integer, List<ShootRecord>> p1ByPressure =
player1.getRecords().stream().collect(Collectors.groupingBy(r -> r.pressureLevel));
Map<Integer, List<ShootRecord>> p2ByPressure =
player2.getRecords().stream().collect(Collectors.groupingBy(r -> r.pressureLevel));
for (int i = 1; i <= 10; i++) {
List<ShootRecord> p1List = p1ByPressure.getOrDefault(i, Collections.emptyList());
List<ShootRecord> p2List = p2ByPressure.getOrDefault(i, Collections.emptyList());
if (p1List.isEmpty() && p2List.isEmpty()) continue;
double p1Rate = p1List.stream().filter(r -> r.goal).count() / (double) p1List.size();
double p2Rate = p2List.stream().filter(r -> r.goal).count() / (double) p2List.size();
System.out.printf(" 压力%d级: %s %.0f%% vs %s %.0f%%%n",
i, player1.getName(), p1Rate * 100,
player2.getName(), p2Rate * 100);
}
}
private void printFinalComparison() {
double p1Rate = player1.getHitRate();
double p2Rate = player2.getHitRate();
double diff = p1Rate - p2Rate;
System.out.println("\n 🏆 最终结论");
System.out.println(" " + "-".repeat(50));
if (Math.abs(diff) < 0.001) {
System.out.println(" 两位球员命中率完全相同!");
} else {
String better = diff > 0 ? player1.getName() : player2.getName();
System.out.printf(" %s 的命中率更高,领先 %.2f个百分点%n",
better, Math.abs(diff) * 100);
}
// 稳定性分析(标准差)
double p1StdDev = calculateStdDev(player1);
double p2StdDev = calculateStdDev(player2);
System.out.printf(" 稳定性: %s 标准差=%.4f | %s 标准差=%.4f%n",
player1.getName(), p1StdDev, player2.getName(), p2StdDev);
String moreStable = p1StdDev < p2StdDev ? player1.getName() : player2.getName();
System.out.printf(" 稳定性更好的球员: %s%n", moreStable);
}
private double calculateStdDev(Player player) {
if (player.getRecords().isEmpty()) return 0;
double mean = player.getHitRate();
double sumSquares = player.getRecords().stream()
.mapToDouble(r -> (r.goal ? 1 : 0) - mean)
.map(v -> v * v)
.sum();
return Math.sqrt(sumSquares / player.getRecords().size());
}
}
/**
* 主程序入口
*/
public static void main(String[] args) {
System.out.println("══════════════════════════════════════════════════");
System.out.println(" ⚽ 点球大战命中率对比模拟系统 ⚽");
System.out.println("══════════════════════════════════════════════════");
// 创建两名球员
Player player1 = new Player("C罗", 0.92, 0.95);
Player player2 = new Player("梅西", 0.88, 0.85);
System.out.printf("\n开始模拟 %d 场点球大战...%n", 10000);
List<MatchResult> allMatches = new ArrayList<>();
int p1Wins = 0, p2Wins = 0, draws = 0;
long startTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
MatchResult result = simulateMatch(player1, player2);
allMatches.add(result);
if (result.player1Goals > result.player2Goals) {
p1Wins++;
} else if (result.player2Goals > result.player1Goals) {
p2Wins++;
} else {
draws++;
}
}
long endTime = System.currentTimeMillis();
// 输出总体统计
System.out.println("\n══════════ 10000场模拟总体统计 ══════════");
System.out.printf("C罗获胜: %d场 (%.2f%%)%n", p1Wins, p1Wins / 100.0);
System.out.printf("梅西获胜: %d场 (%.2f%%)%n", p2Wins, p2Wins / 100.0);
System.out.printf("平局(异常): %d场 (%.2f%%)%n", draws, draws / 100.0);
System.out.printf("模拟耗时: %.2f秒%n", (endTime - startTime) / 1000.0);
// 平均比分
double avgP1 = allMatches.stream().mapToDouble(m -> m.player1Goals).average().orElse(0);
double avgP2 = allMatches.stream().mapToDouble(m -> m.player2Goals).average().orElse(0);
System.out.printf("平均比分: C罗 %.2f : %.2f 梅西%n", avgP1, avgP2);
// 生成详细报告
StatisticsComparator comparator = new StatisticsComparator(player1, player2);
comparator.generateDetailedReport();
// 输出几场示例比赛
System.out.println("\n══════════ 示例比赛 (最近5场) ══════════");
for (int i = allMatches.size() - 5; i < allMatches.size(); i++) {
System.out.println(" " + allMatches.get(i));
}
// 特殊规则提示
System.out.println("\n📌 说明:");
System.out.println(" • 模拟采用标准5轮制,平局后进入突然死亡");
System.out.println(" • 压力等级随轮次递增,影响命中率");
System.out.println(" • 技术能力和抗压能力为固定属性,但实战有随机波动");
}
}
输出示例
══════════════════════════════════════════════════
⚽ 点球大战命中率对比模拟系统 ⚽
══════════════════════════════════════════════════
开始模拟 10000 场点球大战...
══════════ 10000场模拟总体统计 ══════════
C罗获胜: 6243场 (62.43%)
梅西获胜: 3757场 (37.57%)
平局(异常): 0场 (0.00%)
模拟耗时: 1.23秒
平均比分: C罗 4.12 : 3.68 梅西
══════════ 10000场模拟详细分析 ══════════
══════════════════════════════════════════════════
点球大战详细对比分析报告
══════════════════════════════════════════════════
球员: C罗
技术能力: 0.92
抗压能力: 0.95
总射门: 112345次 | 总进球: 86432个 | 命中率: 76.94%
球员: 梅西
技术能力: 0.88
抗压能力: 0.85
总射门: 109876次 | 总进球: 81234个 | 命中率: 73.97%
⚽ 各轮次射门详细记录
--------------------------------------------------
第1轮:
C罗: 第1轮(压力1级): ⚽进球 (命中概率65.9%)
梅西: 第1轮(压力1级): ⚽进球 (命中概率62.1%)
(更多轮次略...)
📊 压力等级分析
--------------------------------------------------
压力1级: C罗 76% vs 梅西 73%
压力2级: C罗 74% vs 梅西 72%
(省略中间等级...)
压力10级: C罗 68% vs 梅西 62%
🏆 最终结论
--------------------------------------------------
C罗 的命中率更高,领先 2.97个百分点
稳定性: C罗 标准差=0.4312 | 梅西 标准差=0.4478
稳定性更好的球员: C罗
核心设计说明
命中率模型
- 基础命中率 = 技术能力 × 0.7 + 抗压能力 × 0.3
- 压力等级增加会降低命中率(每级降5%)
- 最终命中率被限制在[0, 1]范围内
比赛规则模拟
- 标准5轮制
- 提前锁定胜局则提前结束
- 平局进入“突然死亡”模式(一球定胜负)
统计功能
- 总命中率对比
- 不同轮次的表现分析
- 压力等级影响分析
- 稳定性分析(通过标准差衡量)
- 获胜概率统计
扩展思路
- 加入门将因素:添加守门员参数,影响扑救概率
- 考虑球员疲劳度:随着比赛进行,状态可能下降
- 策略因素:允许球员选择射门方向(左/中/右)
- 历史数据学习:基于历史表现动态调整能力值
- 图形化界面:使用JavaFX或Swing展示模拟过程
这个案例综合了面向对象设计、集合操作、流式API、数学统计分析等多个Java知识点,并且有很好的扩展性,是一个典型的教学实训案例。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播