在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而且我不知道为什么。
答案 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++;
}
(请注意,仍有案例丢失!)