随机生成的数字游戏,具有概率和循环

时间:2014-04-08 05:55:59

标签: java loops probability

在Puzzlevania的土地上,亚伦,鲍勃和查理对此有所争论 其中一个是有史以来最伟大的益智游戏。 结束论证一次 为了他们所有人,他们同意了对死的决斗。

亚伦是一个可怜的射手而且只能击中 他的目标概率为1> 3。

鲍勃好一点,用一个打击他的目标 概率为1> 2。

查理是一名专家射手,从未错过。命中意味着 一次杀戮和被击中的人从决斗中退出。

为了弥补他们的射击技巧的不公平,三人决定 他们会轮流射击,从Aaron开始,然后是Bob,然后是 查理。这个循环会重复,直到有一个人站着,那个人 将是有史以来最伟大的益智游戏。

一个明显而合理的策略是让每个男人以最准确的方式进行射击 射手仍然活着,理由是这个射手是最致命的并且拥有最好的射手 回击的可能性。用一种程序来编写一个程序来模拟决斗。

你的程序应该使用 随机数和问题中给出的概率来确定是否 射手击中目标。

创建一个名为Duelist的类,其中包含dueler 名称和射击精度,一个布尔值,表示是否还活着, 和一个方法ShootAtTarget(Duelist目标),如果将目标设置为死亡 thelerler击中他的目标(使用随机数和射击精度)和 否则什么都不做。

一旦您可以模拟单个决斗,请为您的模拟程序添加一个循环 10,000次决斗。计算每位参赛者获胜并打印的次数 每个参赛者获胜的概率(例如,对于Aaron你的计划可能会 输出“Aaron赢了3,595> 10,000决斗或35.95%”。

另一个策略是让Aaron故意错过他的第一枪。修改 程序以适应这种新策略并输出获胜的概率 对于每个参赛者。

对于亚伦来说哪种策略更好:故意错过了 第一枪还是尝试打出最好的射手?谁有最好的获胜机会, 最好的射手还是最差的射手?

好的,这样的问题。到目前为止,这是我的代码:

public class Duelist {

private String name;
private double probabilityOfHitting;
private boolean alive = true;


//Only declared instance variables. Must created setters and getters
public void setName(String newName){
    name = newName;
}
//name setter created

public void setProbabilityOfHitting( double newProbabilityOfHitting){
    probabilityOfHitting = newProbabilityOfHitting;
}
//probability of hitting setter created
public void setAlive(boolean newAlive){
    alive = newAlive;
}
//name setter created
//now must create getters
public String getName(){
    return name;
}
//created the name getter
public double getProbabilityOfHitting(){
    return probabilityOfHitting;
}
//created the probability of hitting getter
public boolean getAlive(){

return alive;
}
//created the alive getter
//no constructors created before
public Duelist(String tempName, double tempProbability){
    name = tempName;
    probabilityOfHitting = tempProbability;
}
//constructor is now created
//need to create a method for the duelists to shoot at each other
public void shootAtTarget(Duelist target){
    double randomNum = Math.random();
    if (this.probabilityOfHitting ==1){
        target.setAlive(false);
        target.getAlive();
    }

        else if (randomNum <= this.probabilityOfHitting){
        target.setAlive(false);
        target.getAlive();
        }
        else {
            target.getAlive();
        }
    }           
}


public class Tester {
public static void main(String[] args) {

    int winsA = 0;
    int winsB = 0;
    int winsC = 0;

Duelist aaron = new Duelist("Aaron",(1/3));
Duelist bob = new Duelist("Bob", (1/2));
Duelist charlie = new Duelist("Charlie", 1);

if(aaron.getAlive() == true){

    if(charlie.getAlive()== true){
        aaron.shootAtTarget(charlie);
        }
        else if(bob.getAlive() == true){
            aaron.shootAtTarget(bob);
        }
        else{
            winsA++;
        }

}
    else if(bob.getAlive() == true){
        if(charlie.getAlive() == true){
            bob.shootAtTarget(charlie);
        }
            else if(aaron.getAlive() == true){
                bob.shootAtTarget(aaron);
            }
            else{
                winsB++;
            }
    }
    else{
        if (bob.getAlive() == true){
            charlie.shootAtTarget(bob);
        }
            else if(aaron.getAlive() == true){
                charlie.shootAtTarget(aaron);
            }
            else{
                winsC++;
            }
    }
    System.out.println(winsA);
    System.out.println(winsB);
    System.out.println(winsC);


 }

}

我知道我还没有接近完成问题。我在我的测试者课上做的是尝试模拟一场决斗,一次模拟一场决斗时,我就可以循环播放,这样我就可以模拟更多。我遇到的问题是,当我运行代码时,Aaron,Bob和Charlie的胜利都达到了0而且我不知道为什么。

1 个答案:

答案 0 :(得分:0)

作为构造函数调用中的最后一个参数,您编写了

Duelist aaron = new Duelist("Aaron",(1/3));

您要将int除以另一个int,在这种情况下结果为0。这必须改为

Duelist aaron = new Duelist("Aaron",(1.0/3.0));

以便使用double值(根据需要,结果将为0.3333)。

您的大多数Duelist课程似乎都没有“错误”,但可以改进shootAtTarget方法。

一般提示:我建议你从不使用Math.random()。这将带来不可预测的结果。相反,您应该使用java.util.Random的实例。这可以用某个随机种子初始化,因此它总是提供相同的随机数序列。这使调试更容易。

另外,一些测试是多余的。当probabilityOfHitting为1.0时,则不需要进行特殊测试:随机数始终小于或等于1.0。你也偶尔会毫无理由地打电话给target.getAlive()

所以最后,方法可能如下所示:

private static Random random = new Random(0);

//need to create a method for the duelists to shoot at each other
public void shootAtTarget(Duelist target)
{
    double randomNum = random.nextDouble();
    if (randomNum <= this.probabilityOfHitting)
    {
        target.setAlive(false);
    }
}           

但是,主要问题出在您的Test课程中。我不确定这里的一般建议。人们可以在抽象方面走得很远。 (Java Enterprise Architect可能最终会在某处编写AbstractDuelistStrategyFactory ...)。但简单地说:目前,你最多只能 一次。一枪之后,没有人能赢。并且你不知道在只剩下一个决斗者之前必须拍多少次。

如果你将决斗者放入List<Duelist>,大部分都可以变得更加优雅和灵活。但如果没有这个,“结构上与你开始接近的”方法可能如下所示:

    int alive = 3;
    while (alive > 1)
    {
        System.out.println("Status: A:"+aaron.getAlive()+" B:"+bob.getAlive()+" C:"+charlie.getAlive());
        if (aaron.getAlive())
        {
            if(charlie.getAlive())
            {
                System.out.println("A shoots at C");
                aaron.shootAtTarget(charlie);
                if (!charlie.getAlive())
                {
                    System.out.println("A killed C");
                    alive--;
                }
            }
            else if(bob.getAlive())
            {
                System.out.println("A shoots at B");
                aaron.shootAtTarget(bob);
                if (!bob.getAlive())
                {
                    System.out.println("A killed B");
                    alive--;
                }
            }
        }
        // Other cases ...
    }

    if (aaron.getAlive())
    {
        winsA++;
    }
    if (bob.getAlive())
    {
        winsB++;
    }
    if (charlie.getAlive())
    {
        winsC++;
    }

(请注意,仍有案例丢失!)