Как я могу использовать условные выражения и циклы для имитации проблемы Монти Холла? - PullRequest
1 голос
/ 30 января 2020

Я начинаю изучать программирование и сейчас работаю с c и условными циклами. И я хотел сделать интерактивную симуляцию проблемы машины Монти в зале за дверями (за одной из трех дверей стоит машина, у двух других есть козы. это и позволяет пользователю переключаться на другую дверь). Согласно тому, что я прочитал из C Программирование современного подхода К. Н. Кинга, это должно быть возможно с помощью нескольких функций, условий и циклов. Но код, который я написал, циклически повторяется в одной из моих функций, и я не уверен почему, вот мой код:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// A function that gets a valid door input from the user
int chooseDoor(){
    int choice = 0;
    while(choice < 1 || choice > 3){
        printf("Choose a door from 1 to 3: ");
        scanf("%d",&choice);
        printf("%d\n", choice);
    }
    return choice;
    }
// A function to get a valid yes or no response from the user
int validateYn(){
    char yn[1];
    fgets(yn,1,stdin);
    while(yn[0] != "Y" && yn[0] != "y" && yn[0] != "N" && yn[0] != "n"){
        printf("Error: Please enter Y or N: ");
        fgets(yn,1,stdin);}
    if(yn[0] == "Y" || yn[0] == "y"){
        return 1;}
    else{
        return 0;}}
int main(){
    bool play = true; //conditional boolean to repeat the game
    while(play){
        int car, shown, other, choice; //initialisers for the door with the car, door that monty will reveal, the remaining door and door chosen by player
        bool swap;
        car = rand()%3; //select a random door between 1 and 3
        choice = chooseDoor(); //call function to get user input of chosen door
        printf("You picked door #%d", choice);
        // A loop to find the lowest door that is not picked by the user and has a goat behind it
        for(int i = 0; i<3; ++i){
            if( i == car || i == choice){
                continue;}
            shown = i;
            break;}
        // A loop to find the remaining door besides the one revealed and the one user picks
        for(int i = 0; i<3; ++i){
            if( i == car || i == choice || i == shown){
                continue;}
            other = i;
            break;}
        printf("Monty opens door #%d, there's a goat!\nWould you like to switch to door #%d?", shown, other);
        swap = validateYn();
        // Change user choice if user says yes to swap
        if(swap){
            choice = other;}
        // win if user choice had car, lose otherwise 
        if(choice == car){
            printf("Monty opens door #%d, it's the car! You win!", car);}
        else{
            printf("Monty opens door #%d, there's a goat. You lose.", choice);}
        } 
        printf("Would you like to play again?");
        play = validateYn();
return 0;}

Мой друг также сказал мне, что оператор switch должен упростить ситуацию, но Я понятия не имею, как правильно их использовать, спасибо

1 Ответ

1 голос
/ 30 января 2020

в вашем коде есть только одна проблема: вы спрашиваете пользователя, хочет ли он продолжить работу за пределами l oop. Иногда это случается, это не так сложно решить. Вам просто нужно переместить последний блок кода взаимодействия с пользователем (последний printf и последний scanf), внутри скобок l oop.

Я приведу здесь код, который полностью работает. Я также сделал некоторые обновления и изменения:

  • Изменено для итерации циклов. Вместо 0 .. <3; ++ я сейчас 1 .. <4; i ++ </li>
  • Изменены fgets с помощью getchar, так как вы берете на вход только один символ, а не строку.
  • Добавлен fflu sh (stdin) для освобождения буфера ввода после этого вы возьмите символ, так как, когда вы берете другой тип ввода, scanf может go сойти с ума и показать грязный результат.
  • Изменена случайность. Теперь начальное число будет менять каждую итерацию с помощью srand и time
#include <stdio.h>
#include <stdlib.h>
#include <time.h> 
#include <stdbool.h>

// A function that gets a valid door input from the user
int chooseDoor()
{
    int choice = 0;
    while (choice < 1 || choice > 3)
    {
        printf("Choose a door from 1 to 3: ");
        scanf("%d", &choice);
    }
    return choice;
}

// A function to get a valid yes or no response from the user
int validateYn()
{
    char yn;
    yn = getchar();
    while (yn != 'Y' && yn != 'y' && yn != 'N' && yn != 'n')
    {
        printf("Error: Please enter Y or N: ");
        yn = getchar();
    }
    if (yn == 'Y' || yn == 'y')
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main()
{
    srand((unsigned int) time(NULL)); // generating number with better randomness
    bool play = true; //conditional boolean to repeat the game
    while (play)
    {
        int car, shown, other, choice; //initialisers for the door with the car, door that monty will reveal, the remaining door and door chosen by player
        bool swap;

        car = 1 + rand() % 3;      //select a random door between 1 and 3
        choice = chooseDoor(); //call function to get user input of chosen door
        printf("You picked door #%d", choice);
        // A loop to find the lowest door that is not picked by the user and has a goat behind it
        for (int i = 1; i < 4; i++) 
        {
            if (i == car || i == choice)
            {
                continue;
            }
            shown = i;
            break;
        }
        // A loop to find the remaining door besides the one revealed and the one user picks
        for (int i = 1; i < 4; i++)
        {
            if (i == car || i == choice || i == shown)
            {
                continue;
            }
            other = i;
            break;
        }
        printf("\nMonty opens door #%d, there's a goat!\nWould you like to switch to door #%d? (y/n).\nChoose: ", shown, other);
        fflush(stdin);
        swap = validateYn();
        // Change user choice if user says yes to swap
        if (swap)
        {
            choice = other;
        }
        // win if user choice had car, lose otherwise
        if (choice == car)
        {
            printf("\nMonty opens door #%d, it's the car! You win!", car);
        }
        else
        {
            printf("\nMonty opens door #%d, there's a goat. You lose. ", choice);
        }
        printf("\n\nWould you like to play again?"); //here now it is inside the while loop
        play = validateYn();
    }
    return 0;
}

Совет. Постарайтесь быть немного более четкими с отступом. В следующий раз вы сможете легко отследить такого рода «ошибки в скобках и области видимости».

Более того, вы можете сделать эту программу с переключателем, чтобы упростить ее. Они не так сложны в использовании. Удачи !!

-Денни

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...