【问题标题】:Coin toss simulation/game in JavaJava中的掷硬币模拟/游戏
【发布时间】:2015-12-20 00:58:48
【问题描述】:

我目前正在上一门技术上面向初学者的计算机科学课程,但我觉得他们给我的所有作业都比我能处理的复杂。

这个作业要求我做一个抛硬币的模拟。三个人玩游戏,每个人都有特定的获胜要求:

  • 如果有 2 个结果头和总投掷次数,则获胜 甚至是
  • 如果有 2 个结果反面且总投掷次数为偶数,则获胜
  • 如果有 2 个结果为正面或反面且掷骰总数为奇数,则获胜

我应该做 300 次实验。每次我都应该确定三个人中谁赢了,赢了多少次。我真的被困住了。我几乎没有任何代码,但我对代码应该是什么样子有一个非常基本的想法,但我无法将它放入 Java 语言中。

对于我的作业,我需要显示导致某人获胜的二进制序列。

我的想法:

  1. 为每个人初始化一个计数器(1、2、3),以便我可以跟踪他们赢了多少次
  2. 初始化头数和尾数以跟踪随机生成的序列
  3. 实际上整个实验都使用 for 循环。应该有一个外部循环定义实验应该运行 300 次,内部循环应该包含检查谁获胜的 if 语句。每个 if 语句中都应该有一个计数器,以便我可以为每个人更新它。我需要一个 System.out.println();打印实验的每一个结果。
  4. 使用先前确定的计数器打印实验的最终结果

编辑: 我试图改变大家所说的,现在看起来更好了,谢谢!但它仍然没有做它应该做的事情,我想知道为什么。我运行代码,我只得到一个输出;不是我希望它运行的 300 次。此外,最后的计数器不保存有关谁获胜的信息,它们每次都会重置。有时两个人会赢,而这是不可能的。谁能澄清一下?

编辑: 这是代码的另一个更新。我相信它现在确实运行了 300 次!现在的问题是输出。有时它说; 1 伯尼获胜,而伯尼显然需要至少 2 个结果才能获胜。此外,它说 1 Penny 获胜,而这也不应该是可能的。我是否在 if 语句中搞砸了?

import java.util.Random;

public class Assignment3e
{
public static void main(String[] args)
{                
    int counter1 = 0;
    int counter2 = 0;
    int counter3 = 0;

    Random coin = new Random();


    for(int i = 0; i <= 300; i++){
        int headCount = 0;
        int tailsCount = 0;
        for(int coinToss = 0; coinToss <= 3; coinToss++){
            int random = (int) (Math.random() * 6) + 1;
            String binary = Integer.toBinaryString(random);

          boolean result = coin.nextBoolean();
          if(result){
              headCount++;
              }
              else{
                  tailsCount++;
                  }
         if(headCount == 2 && binary.length() % 2 ==0){
                //Amy wins
                counter1 = counter1 + 1;
                System.out.println(binary + " Amy wins.");
            }
            else if(tailsCount == 2 && binary.length() % 2 == 0){
                //Penny wins
                counter2 = counter2 + 1;
                System.out.println(binary + " Penny wins.");
            }
            else if(headCount == 2 || tailsCount == 2 && binary.length() % 2 != 0){
                //Bernie wins
                counter3 = counter3 + 1;
                System.out.println(binary + " Bernie wins.");
            }
         }
      }
        System.out.println("Amy wins " + counter1 + " times.");
        System.out.println("Penny wins " + counter2 + " times.");
        System.out.println("Bernie wins " + counter3 + " times.");
}

}

【问题讨论】:

  • 所以你想基本上停止for 循环?您可以为此使用 break
  • 如果您使用Math.random() 并且从不使用dice,则您不会使用Random dice
  • 删除这个无用的二进制字符串。并使用coinTossvalue,而不是binary.length(),这没有意义
  • 我尝试删除二进制字符串,但它不起作用。对于我的任务,我需要显示导致一个人获胜的二进制序列。因此,如果我删除二进制文件,我将无法再显示它。另外,我不确定头/尾计数器是否正常工作。
  • 我编辑了我的答案和您的问题以添加此要求。

标签: java simulation


【解决方案1】:

如果您对硬币 nextBoolean() 使用 Random() 对象,为什么不将 int random = (int) (Math.random() * 6) + 1; 替换为 int random = coin.nextInt([range here])

【讨论】:

    【解决方案2】:

    你几乎猜对了。

    这部分不再相关,因为 OP 在 cmets 中添加了要求。

    您的第二个for 循环最多只需要运行 3 次,因为至少会有 2 个正面或 2 个反面,而不是 10 个。

    编辑:您最多可以掷 2 次:如果有 1 头和 1 尾,则获胜者是第三位玩家 (Bernie)

    现在,在每次迭代中,您可以绘制一个介于 0 和 1 之间的随机十进制数,并假设如果它超过 0.5,它是一个头部,因此您增加 headCount,否则您增加 tailCount。然后你可以对计数器(和投掷次数)进行测试。

    这比使用二进制字符串更容易。

    编辑: 要回答您的评论: 看看你在哪里初始化了headCounttailCount。请记住,一旦获胜,必须重置那些计数器。

    因为是作业,我就不贴代码了:)

    编辑: OP jsut 添加一条评论,说明他需要打印导致每场比赛结果的序列。

    我们假设二进制 1 是头部,0 是尾部。如果Bernie 获胜,您需要掷硬币 3 次才能知道顺序。所以转换成二进制字符串的整数值random只需3位(1位=1次折腾)。

    random 只能取 0 到 7 之间的值。

    当您一次获得所有值时,您不再需要coinToss for 循环。您需要做的就是检查二进制字符串的开头是否匹配任何获胜模式(11 表示 2 个正面,00 表示 2 个反面,否则 Bernie 获胜)

    【讨论】:

    • 谢谢,我更改了评论和 0.5!现在我仍然有一个问题,即使它只输出一个 1,我的程序仍然说有人赢了,而事实并非如此。而且我似乎无法让它运行我打算运行的 300 次;它现在只给了我 3 个案例。
    • 由于我不知道您是如何实现修改的,所以我无法为您提供更多帮助。
    • 我上传了我更改的代码,对不起,我忘记了!
    • 为什么是第三个循环?您已经在第二个循环中掷了 3 次硬币,但是由于第三次和这个二进制字符串,就像每次掷硬币都包含随机数量的硬币一样。而且您仍然需要将头尾计数设置为 0在开始新游戏之前,即在 300 次迭代中的每一次
    • 既然你提到它,那确实没有多大意义。我试图再次运行我的代码,但现在它有时只输出 1 并声明有人赢了。另外,我现在的总胜数是 340、91 和 80。这显然太多了。哇,这真是令人困惑!
    【解决方案3】:

    所以我在这里注意到了几件事:

    • 您不会在任何地方更新headCounttailCount。这应该是您用来记录掷硬币次数的方法。

      当您返回以在后续循环中重用它们时,请务必再次将它们归零。

    • 您使用的结果范围非常广泛,而一个简单的nextBoolean 就足够了。您可以在循环中使用它:

      boolean result = coin.nextBoolean(); // this renames dice to coin
      if(result) {
          headCount++;
      } else {
          tailCount++;
      }
      
    • 总投掷次数总是当前迭代的当前值(加 1)。因此,在您的情况下,您可以简单地将 sum 替换为 j,但您希望给它一个更有意义的名称,例如 coinTosses

    【讨论】:

    • 谢谢,我编辑了我的代码。尽管如此,我仍然遇到麻烦,因为它让不止一个人在一轮中获胜。它还说 1 是有效的获胜,而我认为我已经确定它不是。没有人应该能够只用一次翻转就获胜。我被困在如何使这项工作上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    • 2013-03-07
    • 2021-03-12
    相关资源
    最近更新 更多