首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的Monty Hall Paradox

Java中的Monty Hall Paradox
EN

Code Review用户
提问于 2015-03-14 17:28:05
回答 7查看 4.5K关注 0票数 14

我想知道这段代码看上去是否整洁,是否应该做任何更改。我计划明天在上面实现框架(或JFrame)。使用函数是个好主意吗?

代码语言:javascript
复制
import java.lang.Math.*;
import java.util.Random;
import java.util.Scanner;

public class Paradox {
public static void main(String[] args){
    System.out.println("\n\nYou have got three doors, there is a price inside each of them. Pick a door: A, B, or C.");
    Door A = new Door();
    Door B = new Door();
    Door C = new Door();
    A.open=0;
    B.open=0;
    C.open=0;

    Random rand = new Random();
    int i = rand.nextInt(3);
    /*System.out.println(i);*/

    if(i==0) {
        A.goatorcar="Car";
        B.goatorcar="Goat";
        C.goatorcar="Goat";
    }
    else if (i==1){
        A.goatorcar="Goat";
        B.goatorcar="Car";
        C.goatorcar="Goat";
    }
    else if (i==2) {
        A.goatorcar="Goat";
        B.goatorcar="Goat";
        C.goatorcar="Car";
    } else { System.out.println("Unexpected error"); }



    int pickedA=0;
    int pickedB=0;
    int pickedC=0;

    Scanner sc = new Scanner(System.in);
    String pickedDoor = sc.nextLine();
    System.out.println("\n");

    if (pickedDoor.equals("A") || pickedDoor.equals("1") || pickedDoor.equals("a")){
        pickedA = 1;
    }
    if (pickedDoor.equals("B") || pickedDoor.equals("2") || pickedDoor.equals("b")){
        pickedB = 1;
    }
    if (pickedDoor.equals("C") || pickedDoor.equals("3") || pickedDoor.equals("c")){
        pickedC = 1;
    }

    if(pickedA==1) {
        if (A.goatorcar.equals("Car")){
            i = rand.nextInt(2);
            if (i==0){ System.out.println("The door B contains a Goat"); B.open=1; }
            else if (i==1){ System.out.println("The door C contains a Goat"); C.open=1; }
        }
        else {
        if (B.goatorcar=="Goat") { System.out.println("The door B contains a Goat"); B.open=1; }
        else if (C.goatorcar=="Goat") { System.out.println("The door C contains a Goat"); C.open=1; }
        }
    }
    else if (pickedB==1) {
        if (B.goatorcar.equals("Car")){
            i = rand.nextInt(2);
            if (i==0){ System.out.println("The door A contains a Goat"); A.open=1; }
            else if (i==1){ System.out.println("The door C contains a Goat"); C.open=1; }
        }
        else {
            if (A.goatorcar=="Goat") { System.out.println("The door A contains a Goat"); A.open=1; }
            else if (C.goatorcar=="Goat") { System.out.println("The door C contains a Goat"); C.open=1; }
        }
    }
    else if (pickedC==1) {
        if (C.goatorcar.equals("Car")){
            i = rand.nextInt(2);
            if (i==0){ System.out.println("The door A contains a Goat"); A.open=1; }
            else if (i==1){ System.out.println("The door B contains a Goat"); B.open=1; }
        }
        else {
            if (A.goatorcar=="Goat") { System.out.println("The door A contains a Goat"); A.open=1; }
            else if (B.goatorcar=="Goat") { System.out.println("The door B contains a Goat"); B.open=1; }
        }
    }
    else { System.out.println("You haven't picked any door"); System.exit(0); }


    System.out.println("\nKnowing where one of the Goats are, do you wish to stay on your current door, or do you want to change?");

    String changeornot = sc.nextLine();
    int change=2;
    System.out.println();

    if (changeornot.equals("change") || changeornot.equals("1") || changeornot.equals("yes")){
        change=1;
    }
    else if (changeornot.equals("stay") || changeornot.equals("0") || changeornot.equals("no")){
        change=0;
    }


    if(change==0){
        System.out.print("Congratulations! You stayed, and won a ");
        if(pickedA==1){
            System.out.println(A.goatorcar);
        }
        if(pickedB==1){
            System.out.println(B.goatorcar);
        }
        if (pickedC==1){
            System.out.println(C.goatorcar);
        }
    }

    else if (change==1){
        System.out.print("Congratulations! You changed, and won a ");
        if (pickedA==1 && B.open==1) {
            System.out.println(C.goatorcar);
        }
        if (pickedA==1 && C.open==1) {
            System.out.println(B.goatorcar);
        }

        if (pickedB==1 && A.open==1) {
            System.out.println(C.goatorcar);
        }
        if (pickedB==1 && C.open==1) {
            System.out.println(A.goatorcar);
        }

        if (pickedC==1 && A.open==1) {
            System.out.println(B.goatorcar);
        }
        if (pickedC==1 && B.open==1) {
            System.out.println(A.goatorcar);
        }   
    }
    else if (change==2){ System.out.println("Error at change"); }


/*System.out.println("Door A: " + A.goatorcar);
System.out.println("Door B: " + B.goatorcar);
System.out.println("Door C: " + C.goatorcar);*/

}
}
class Door {
String goatorcar;
int open;
} 
EN

回答 7

Code Review用户

发布于 2015-03-14 19:15:53

几点想法:

  • 你的一些台词很长。虽然安装在屏幕上似乎很方便,但随着代码行的变长,代码变得更加难以理解。许多人有充分的理由想要一个80焦耳的线限制。这是我个人的喜好;许多人会不同意;但我发现System.out.println(导言);比System.out.println更和蔼可亲(“\n你有三扇门,每个门都有一个价格。选一扇门: A、B或C”);.主要是因为这样的话,我就不需要把我的屏幕房地产花在一个文件上了。如果我同时处理多个窗口中的多个文件,或者如果我使用的是Linux,那么如果我需要向四个方向滚动而不是两个,那么长行就会变得很痛苦。正如精明的读者所指出的那样,这种做法也是过时的。现在,你很容易就可以用超过80个字符的行来逃避。
  • 编写模块化代码是确保代码不受攻击的重要一步。黑客基本上就是不能随意修改的代码。当代码被分割成方法时,就更容易理解、修改和调试。例如,如果您有一个doorOption方法来确定根据String选择了哪个门,那么只要您希望用户选择一个门,就可以简单地调用该方法。该方法可以在一个地方执行if (pickedDoor.toLowerCase().equals("a") \x\x pickedDoor.equals("1"))的任务。您还可以枚举该方法的结果;这样您就可以按名称引用结果:DOOR_ONEDOOR_TWO等等。编写模块化代码可能有点令人望而生畏,但回报是非常可取的。模块化代码是划分为模块的代码;每个模块执行特定的任务。根据Wikipedia,模块化编程是一种软件设计技术,它强调将程序的功能分离成独立的、可互换的模块,这样每个模块都包含执行所需功能的一个方面所必需的一切。
  • 你有很多硬编码字符串。根据Google:硬编码在程序中修正(数据或参数)的方式是,如果不修改程序,它们就不能被修改。您也许可以通过将这些输入到static final字段中而不受影响。类似静态的最后字符串导入=“你有三扇门,每个门都有一个价格。选择一扇门: A,B,或C”;final意味着变量在赋值后不能修改。
  • 在生成GUI之前,我将研究如何使您的代码更易于维护。这一过程不应过于牵扯。我通常尝试将所有GUI方法保存在一个单独的类中。
票数 10
EN

Code Review用户

发布于 2015-03-14 20:23:21

单线

这并不是什么大问题,但我注意到您有几个一行程序,其中包含多个命令。尽管这在技术上没有“错误”,但它可能会给下一个不得不维护您的代码的人带来一些混乱。

例如:

否则if (pickedC==1) { if (C.goatorcar.equals("Car")){ i= rand.nextInt(2);if (i==0){ System.out.println(“门A包含山羊”);A.open=1;} if (i==1){ System.out.println(“门B包含山羊”);B.open=1;}{如果(A.goatorcar==“山羊”){System.out.println(“门A包含山羊”);A.open=1;}B.goatorcar==(“山羊”){System.out.println(“门B包含山羊”);B.open=1;}{System.out.println(“您没有选择任何门”);System.exit(0);}}

这样的格式比打印到控制台更容易表示正在进行的操作。

代码语言:javascript
复制
else if (pickedC==1) {
    if (C.goatorcar.equals("Car")){
        i = rand.nextInt(2);
        if (i==0){ System.out.println("The door A contains a Goat"); 
            A.open=1; }
        else if (i==1){ System.out.println("The door B contains a Goat"); 
            B.open=1; }
    }
    else {
        if (A.goatorcar=="Goat") { System.out.println("The door A contains a Goat"); 
            A.open=1; }
        else if (B.goatorcar=="Goat") { System.out.println("The door B contains a Goat"); 
            B.open=1; }
    }
}
else { System.out.println("You haven't picked any door"); 
    System.exit(0); }

不过,理想情况下,许多人可能会说,您应该始终遵循标准的Java缩进,尽管它占用更多的垂直空间,但它使事情变得非常清楚,如下所示:

代码语言:javascript
复制
else if (pickedC==1) {
    if (C.goatorcar.equals("Car")) {
        i = rand.nextInt(2);
        if (i==0) { 
            System.out.println("The door A contains a Goat"); 
            A.open=1; 
        }
        else if (i==1) { 
            System.out.println("The door B contains a Goat"); 
            B.open=1; 
        }
    }
    else {
        if (A.goatorcar=="Goat") { 
            System.out.println("The door A contains a Goat"); 
            A.open=1; 
        }
        else if (B.goatorcar=="Goat") { 
            System.out.println("The door B contains a Goat"); 
            B.open=1; 
        }
    }
}
else { 
    System.out.println("You haven't picked any door"); 
    System.exit(0); 
}

命名与间距

就像这样:

if(i==0) { A.goatorcar="Car";B.goatorcar="Goat";C.goatorcar="Goat";}

首先,如果您使用camelCase (多词变量和方法的惯例),那么这样的变量的命名就更容易理解了。所以goatorcar变得更容易读,goatOrCar

另外,在操作人员之间留有一点喘息的空间会更好。如下所示:

代码语言:javascript
复制
if(i == 0) {
    A.goatOrCar = "Car";
    B.goatOrCar = "Goat";
    C.goatOrCar = "Goat";
}
票数 8
EN

Code Review用户

发布于 2015-03-14 21:15:41

如果您有一个获得用户输入的函数,那么肯定会有所帮助:您将有一个更好的分离关注点,行为将更容易改变,用户界面也会稍微更直观和更友好。

我的Java有点生疏,但是类似的东西(下面的代码是不正确的,重要的是这个想法比代码本身更重要):

代码语言:javascript
复制
public static boolean getBooleanFromUser(String prompt, String retry, List<String> yesOptions, List<String> noOptions)
{
    System.out.println(prompt);
    while (true)
    {
        String userInput = sc.nextLine();
        System.out.println();
        if (yesOptions.contains(userInput))
            return true;
        if (noOptions.contains(userInput))
            return false;
        System.out.println(retry);
}

public static boolean userStaysOrNot()
{
    return getBooleanFromUser("\nKnowing where one of the Goats are, do you wish to stay on your current door, or do you want to change?", "Invalid input, please retry", ["change", "1", "yes"], ["stay", "0", "false"]);
}
票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/84085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档