蒙蒂霍尔游戏

时间:2014-10-10 18:00:46

标签: java logic probability

我是一名正在学习Java的新程序员。我在这里开了一款基于游戏的游戏让我们做个交易& monty hall问题(https://www.youtube.com/watch?v=mhlc7peGlGg)我和这段代码的逻辑一直存在问题。一切似乎都正常工作,除了我似乎无法让user_door切换到另一扇门,并确定他们是否是正确的赢家。如果有人能帮助我理解我在这里做错了什么,我很想借此机会学习,谢谢!

import java.util.Random;
import java.util.Scanner;
public class GameShow {

public static void main(String[] args) {
    Scanner scan = new Scanner (System.in);
    Random generator = new Random();

    // Initialize Variables
    int user_door,
        open_door,
        other_door,
        prize_door;

    // Generate random value 1-3
    prize_door = generator.nextInt(3)+1;
    open_door = prize_door;

    while(open_door == prize_door){
        open_door = generator.nextInt(3)+1;
    }

    other_door = open_door;

    while (other_door == open_door || other_door == prize_door){
        other_door = generator.nextInt(3)+1;
    }

    // Begin Game
    System.out.println("*** Welcome to the game show! ***");  
    System.out.println("Select the door (1, 2, or 3): ");
    user_door = scan.nextInt();


    // User Validation
        if (user_door > 3 || user_door < 0) {
            System.out.println("Please select door 1, 2, or 3");
            user_door = scan.nextInt();
        } else if(user_door == 1 || user_door == 2 ||  user_door == 3) {

    //Continue Game
    System.out.println("\nIn a moment, I will show you where the prize is located,");
    System.out.println("but first I will show you what is behind one of the other doors");

    //Continue Dialogue
    System.out.println("\nBehind door number " + open_door + " are goats!");
    System.out.println("You selected door number " + user_door);
    System.out.println("\nWould you like to switch your door(y/n)? ");

    //User Input Yes or No
    char userReply = scan.next().charAt(0);

    //If statement with nested while statements for user input
        if (userReply == 'y'){
                user_door = other_door;
                } while(userReply != 'y' && userReply != 'n')
                {
                    //User Validation
                    System.out.println("Please enter either y/n");
                    userReply = scan.next().charAt(0);
                } 

    System.out.println("The prize is behind door number: " + prize_door); 

    //Check to see if user won or lost
        if(user_door == prize_door){
            System.out.println("Congratulations! You won the prize!");
            } else {
                    System.out.println("Sorry. You lost.");
                    }       

        }
    }
}

5 个答案:

答案 0 :(得分:2)

你从未正确分配另一扇门。你分配的另一扇门是一个随机数字,你的实施也没有正确描述蒙蒂霍尔问题。

打破程序的示例

所以,让我们说奖品门= 1,开门= 2,然后其他门= 3默认。

让我们说用户选择门2.然后,当门2打开时,实际上有两个可能的门:1和3。

Monty Hall问题的一个关键部分是用户未选择的门被打开。

当您选择用户的门时,您需要确定other_door是什么。此代码有点难以理解,因此我会在尝试查找您的问题时查看我发现的一些问题。

门奖生成

// Generate random value 1-3
prize_door = generator.nextInt(3)+1; //assigns a value to the prize
open_door = prize_door;

while(open_door == prize_door){
    open_door = generator.nextInt(3)+1; //assigns a value to the door to open, not the prize
}

other_door = open_door;

while (other_door == open_door || other_door == prize_door){
    other_door = generator.nextInt(3)+1; //assigns the last value to this
}

此代码正确分配了prize_door,但其余部分尚未完成。我们可以简化其实现。

prize_door = generator.nextInt(3) + 1; //we know what the prize is

这比3个变量更容易管理,并且更少依赖于随机性。我们只需要跟踪选择者的门,以及奖品所在的门。

获取用户的门

user_door = -1; //instantiate to -1 here

// User Validation
while (user_door > 3 || user_door < 0) {
    System.out.println("Please select door 1, 2, or 3");
    user_door = scan.nextInt();
}

如果我在被告知不要输入4后,您的用户验证将失败。您应该将它们锁定在循环中,直到他们选择一扇门。

这也消除了对if的需要,因为一旦离开循环,该数字将为1,2或3

打开门

此时,我们实例化了两个数字。

System.out.println("\nBehind door number " + open_door + " are goats!");
System.out.println("You selected door number " + user_door);

在最初的Monty Hall游戏中,您应该打开选择器未选择的门。用户的门永远不会打开。在这种情况下,我们有两个输入,user_door和prize_door 使用俗气的逻辑,我们可以通过将它们组合在一起来确定要打开哪扇门,或者如果要验证则可以执行true。我会提出俗气,因为写作速度更快,但仍然有道理。

if(prize_door + user_door == 4) { // 1 and 3
    open_door = 2;
}
else if(prize_door + user_door == 5) { // 2 and 3
    open_door = 1;
}
else { //1 and 2
    open_door = 3;
}

非俗气的选择是:

boolean oneIsTaken = false;
boolean twoIsTaken = false;

if(prize_door == 1 || user_door == 1) {
    oneIsTaken = true;
}
if(prize_door == 2 || user_door == 2) {
    twoIsTaken = true;
}

if(oneIsTaken && twoIsTaken) {
    open_door = 3;
}
else if(oneIsTaken) {
    open_door = 2;
}
else {
    open_door = 1;
}

获得可以切换到的门

使用敞开的门和用户的原始门,我们可以选择开关门,因为这两个门不是您要切换到的门。

if(open_door + user_door == 4) { // 1 and 3
    user_door = 2;
}
else if(open_door + user_door == 5) { // 2 and 3
    user_door = 1;
}
else { //1 and 2
    user_door = 3;
}

确定用户是否赢了

与以前相同:

    if(user_door == prize_door){
        System.out.println("Congratulations! You won the prize!");
        } else {
                System.out.println("Sorry. You lost.");
                }       

    }

没有问题。

答案 1 :(得分:2)

我同意Srikanth上面所说的话。缺少的是测试用户回复的部分。你应该切换“if”和“while”语句。这有助于解决您的车门切换问题。

 if (userReply == 'y')
     {
     user_door = other_door;
     }  
 while(userReply != 'y' && userReply != 'n')
     {
     //User Validation
     System.out.println("Please enter either y/n");
     userReply = scan.next().charAt(0);
     } 

更改为

 while(userReply != 'y' && userReply != 'n')
    {
        //User Validation
        System.out.println("Please enter either y/n");
        userReply = scan.next().charAt(0);
    }
 if (userReply == 'y')
    {
     user_door = other_door;
    } 

您这样做只会在第一次输入字符时进行检查。如果他们做错了并试图再做一次,那么它就不会换门,因为你已经超过了程序的那一部分。

答案 2 :(得分:2)

我已经完成了一些代码优化,重要的是我已经解决了它。您在代码中犯的错误将在下面解释。

import java.util.Random;
import java.util.Scanner;

public class table {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        Random generator = new Random();

        // Initialize Variables
        int user_door, open_door, other_door, prize_door;

        // Generate random value 1-3
        prize_door = generator.nextInt(3) + 1;
        other_door = prize_door;

        // Begin Game
        System.out.println("*** Welcome to the game show! ***");

        // User Validation
        do{
            System.out.println("Select the door (1, 2, or 3): ");
            user_door = scan.nextInt();
        }while(user_door > 3 || user_door < 0);
        do{
            open_door = generator.nextInt(3)+1;
        }while(open_door == prize_door || open_door == user_door);

        System.out.println("\nIn a moment, I will show you where the prize is located,");
        System.out.println("but first I will show you what is behind one of the other doors");
        System.out.println("\nBehind door number " + open_door+ " are goats!");
        System.out.println("You selected door number " + user_door);
        char userReply;
        do{
            System.out.println("\nWould you like to switch your door(y/n)? ");
            userReply = scan.next().charAt(0);
        }while(userReply!='y' && userReply!='n');       

        int user_duplicate = user_door;
        if (userReply == 'y') {
            do{
                user_door = generator.nextInt(3)+1;
            }while(user_door == open_door || user_door == user_duplicate);
        }

        System.out.println("The prize is behind door number: " + prize_door);

        if (user_door == prize_door) {
            System.out.println("Congratulations! You won the prize!");
        } else {
            System.out.println("Sorry. You lost.");
        }
    }
}

在获得prize_door之后,您应该只分配user_door,在获得user_door后必须分配open_door,如果您选择other_door切换你的门。

答案 3 :(得分:1)

让我们通过示例

逐步了解您的代码所执行的操作
import java.util.Random;
import java.util.Scanner;
public class GameShow {

public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
Random generator = new Random();

// Initialize Variables
int user_door,
    open_door,
    other_door,
    prize_door;

// Generate random value 1-3
prize_door = generator.nextInt(3)+1; 

让我们假设生成器将2分配给price_door

open_door = prize_door;

while(open_door == prize_door){
    open_door = generator.nextInt(3)+1;
}

让我们假设在循环之后,生成器将1分配给open_door

other_door = open_door;

while (other_door == open_door || other_door == prize_door){
    other_door = generator.nextInt(3)+1;
}

让我们假设在循环之后,生成器将3分配给other_door

// Begin Game
System.out.println("*** Welcome to the game show! ***");  
System.out.println("Select the door (1, 2, or 3): ");

让我们回想一下变量的值 open_door = 1 other_door = 3 prize_door = 2

user_door = scan.nextInt();
// User Validation
    if (user_door > 3 || user_door < 0) {
        System.out.println("Please select door 1, 2, or 3");
        user_door = scan.nextInt();
    } else if(user_door == 1 || user_door == 2 ||  user_door == 3) {

让我们假设用户输入1 user_door = 1

//Continue Game
System.out.println("\nIn a moment, I will show you where the prize is located,");
System.out.println("but first I will show you what is behind one of the other doors");

//Continue Dialogue
System.out.println("\nBehind door number " + open_door + " are goats!");

在这里您打开的门1(open_door = 1)与user_door = 1

相同

根据游戏逻辑,这是错误的

System.out.println("You selected door number " + user_door);
System.out.println("\nWould you like to switch your door(y/n)? ");

//User Input Yes or No
char userReply = scan.next().charAt(0);

//If statement with nested while statements for user input
    if (userReply == 'y'){
            user_door = other_door;
            } while(userReply != 'y' && userReply != 'n')
            {
                //User Validation
                System.out.println("Please enter either y/n");
                userReply = scan.next().charAt(0);
            } 

System.out.println("The prize is behind door number: " + prize_door); 

//Check to see if user won or lost
    if(user_door == prize_door){
        System.out.println("Congratulations! You won the prize!");
        } else {
                System.out.println("Sorry. You lost.");
                }       

    }
}
}

您需要根据用户的输入更改门的选择,因为作为主持人,您知道汽车/黄金在哪里以及山羊在程序中缺失的位置

你应该在游戏开始之前修正prize_door你正在做的是正确但open_doorother_door应该根据user_door

决定

答案 4 :(得分:0)

很多答案,很多东西指出错误或无效(但不知何故没有人评论以这种方式随机化3个元素,而不是仅仅基于随机函数对它们进行一次洗牌),但没有人明确地解决了这个问题:“。 ..除了我似乎无法让user_door切换到另一扇门..“

三扇门标有prize_dooropen_doorother_dooruser_door可以是其中任何一个。这是错的,但无论如何。

if (userReply == 'y')
    user_door = other_door;

此处使用的语句将user_door更改为other_door(非奖品关门)的具体值,而不考虑user_door的值是什么。它应该将其从prize_door更改为other_door,反之亦然。

if (userReply == 'y')
{
    if (user_door == other_door)
        user_door = prize_door;
    else
        user_door = other_door;
}

禁止案件user_door == open_door,这确实不存在。