模拟踢球问题的Java程序,试了好久还是失败…… 请各位帮忙找一下错误
问题描述:有甲乙两名球员在进行射门比赛,甲的进球概率为a(假设a=0.5),乙的进球概率为b(假设b=0.5)。甲先开始射门,进球后可以再射一次,否则轮到对手射门。若任何一名球员比对方先多进两个球,则比赛结束,进球多的球员获胜。求甲乙两方获胜的概率各是多少?
以下是我用Java写的程序(我先后试了好多种程序流程):
import java.util.Random;
/**
* FootballPlayer类是足球运动员的抽象表示
*
* @since 1.0
* @version 1.0
*/
public class FootballPlayer {
private Random r = new Random(); // 获得一个Random类的实例
/**
* 这是足球运动员射门的方法
*
* @param p为运动员进球的概率
* 若参数p不合法,则抛出IllegalArgumentException异常
* @return 如果本次射门进球就返回true,否则返回false
*/
public boolean shoot(double p) {
if (p <= 0.0 || p >= 1.0)
throw new IllegalArgumentException("足球运动员进球的概率不合法!");
double d = r.nextDouble();
if (d < p)
return true;
else
return false; // 如果随机双精度浮点数d小于p,表示射门进球,否则表示没有进球
}
}
/**
* 这是模拟踢球问题的主类
*
* @since 1.0
* @version 1.0
*/
public class FootballMatch {
/**
* 程序入口点
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
FootballPlayer player1 = new FootballPlayer();
FootballPlayer player2 = new FootballPlayer();
int player1WinCount = 0; // 运动员player1获胜的次数
int player2WinCount = 0; // 运动员player2获胜的次数
for (int i = 0; i < 10000; i++) { // 进行10000场比赛来统计甲乙两方获胜的概率
int player1Count = 0; // 运动员player1在本次比赛中的累计进球数
int player2Count = 0; // 运动员player2在本次比赛中的累计进球数
// 比赛规则:任何一方比对方多进两个球就算获胜,比赛也就结束
// 比赛开始,player1先踢
for (;;) {
while (player1.shoot(0.5)) {
player1Count++;
if (player1Count >= player2Count + 2) {
player1WinCount++;
break; // 满足player1获胜的条件,停止射门,跳出while循环
}
}
if (player1Count >= player2Count + 2) {
break; // 满足player1获胜的条件,跳出无限for循环
}
while (player2.shoot(0.5)) {
player2Count++;
if (player2Count >= player1Count + 2) {
player2WinCount++;
break; // 满足player2获胜的条件,停止射门,跳出while循环
}
}
if (player2Count >= player1Count + 2) {
break; // 满足player1获胜的条件,跳出无限for循环
}
}
}
double player1WinP = player1WinCount
/ (player1WinCount + player2WinCount); // 运动员player1获胜的概率
double player2WinP = player2WinCount
/ (player1WinCount + player2WinCount); // 运动员player2获胜的概率
System.out.println("运动员player1获胜的概率:" + player1WinP);
System.out.println("运动员player2获胜的概率:" + player2WinP);
}
}
以上程序在Windows XP+Eclipse 3.3+Jre 1.6环境上运行的结果为:
运动员player1获胜的概率:0.0
运动员player2获胜的概率:0.0
这样的结果显然是错误的,可是我总是找不出Bug。随便说明一下,这个踢球的问题是我读高中时我的一位同学提出的,他那时候花了三个星期,写了十几页的证明,推出了甲乙获胜的一般表达式。他计算的结果和在电脑上模拟一亿次的比赛结果所得出的概率只有万分之一左右的误差,那他当然是对了!现在想起来,就一个字“汗”……而我到了现在就连这样的小程序都写不对。