C 上的石头、剪刀、布,使用 fork() 和 pipe()

问题描述 投票:0回答:1

我有一个课堂练习,这是练习: 练习 2. 用 C++ 编写一个名为“Game”的类,它执行以下操作:

创建一个子进程,负责随机返回“石头”、“布”或“剪刀”。要创建这个子进程,可以使用任何编程语言来生成相应的可执行文件。每次从父进程收到执行请求时,该子进程都会将“Rock”、“Paper”或“Scissors”写入其标准输出。

父进程从标准输入中读取,检查用户是否输入了“Rock”、“Paper”或“Scissors”,如果是,则调用子进程来显示机器返回的内容。

最后,家长将显示该轮的获胜者是谁。比赛将在三轮两胜决出后结束。

我们必须用pipe()和fork()来做到这一点,但是5个多小时后,我还没有找到解决方案...... 我的老师没有帮助我们,因为他说“看看我给你的材料(它是用java编写的)。

这就是我目前的情况:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#define MAX_ROUNDS 3

// Function to generate the random option for the child process
const char *generateRandomOption()
{
    int num = rand() % 3;
    switch (num)
    {
    case 0:
        return "Rock";
    case 1:
        return "Paper";
    case 2:
        return "Scissors";
    default:
        return NULL;
    }
}

int main()
{
    srand(time(NULL)); // Initialize the seed for random numbers

    int parentScore = 0;
    int childScore = 0;
    int round = 0;

    int pipefd[2]; // Declare the pipe
    if (pipe(pipefd) == -1)
    {
        perror("Error creating the pipe");
        exit(1);
    }

    while (round < MAX_ROUNDS)
    {
        printf("Round %d\n", round + 1);

        // Create a child process
        pid_t pid = fork();

        if (pid < 0)
        {
            perror("Error creating the child process");
            exit(1);
        }
        else if (pid == 0)
        {
            // Child process
            const char *randomOption = generateRandomOption();
            if (randomOption == NULL)
            {
                fprintf(stderr, "Error generating random option\n");
                exit(1);
            }

            // Close the write end of the pipe in the child
            close(pipefd[1]);

            // Send the option to the parent through the pipe
            write(pipefd[0], randomOption, strlen(randomOption) + 1);
            exit(0);
        }
        else
        {
            // Parent process
            close(pipefd[1]); // Close the write end of the pipe

            char childOption[10];
            read(pipefd[0], childOption, sizeof(childOption));

            // Simulate the game and determine the round winner
            char parentOption[10];
            printf("Parent, enter your option (Rock, Paper, or Scissors): ");
            scanf("%s", parentOption);

            // Validate user's option
            if (strcmp(parentOption, "Rock") != 0 && strcmp(parentOption, "Paper") != 0 && strcmp(parentOption, "Scissors") != 0)
            {
                printf("Invalid option. Enter Rock, Paper, or Scissors.\n");
                continue;
            }

            printf("Child: %s\n", childOption);
            printf("Parent: %s\n", parentOption);

            // Logic to determine the round winner
            if (strcmp(parentOption, childOption) == 0)
            {
                printf("It's a tie in this round.\n");
            }
            else if ((strcmp(parentOption, "Rock") == 0 && strcmp(childOption, "Scissors") == 0) ||
                     (strcmp(parentOption, "Paper") == 0 && strcmp(childOption, "Rock") == 0) ||
                     (strcmp(parentOption, "Scissors") == 0 && strcmp(childOption, "Paper") == 0))
            {
                printf("Parent wins this round.\n");
                parentScore++;
            }
            else
            {
                printf("Child wins this round.\n");
                childScore++;
            }
            round++;
        }
    }

    // Determine the game winner
    if (parentScore > childScore)
    {
        printf("Parent wins the game with a score of %d to %d.\n", parentScore, childScore);
    }
    else if (childScore > parentScore)
    {
        printf("Child wins the game with a score of %d to %d.\n", childScore, parentScore);
    }
    else
    {
        printf("It's a tie in the game with a score of %d to %d.\n", parentScore, childScore);
    }

    close(pipefd[0]);
    return 0;
}

孩子从来不发消息,我已经做到了同时发剪刀石头布,总是有同样的消息,但还是没有解决办法...

c++ pipe fork
1个回答
0
投票

pipe(pipefd)
导致
pipefd[0]
成为管道的读取端,而
pipefd[1]
成为写入端。子进程在调用
write
时应使用写入端,并在使用后关闭管道的每一端,或者如果根本不使用它。

        // Close the read end of the pipe in the child (Since we didn't use it)
        close(pipefd[0]);
        
        // Send the option to the parent through the pipe
        write(pipefd[1], randomOption, strlen(randomOption) + 1);
        
        // Close the write end of the pipe in the child (After we used it)
        close(pipefd[1]);
        
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.