【问题标题】:Pseudocode for Synchronization Problem (Card Game)同步问题的伪代码(纸牌游戏)
【发布时间】:2019-12-08 15:47:33
【问题描述】:

这与学术有关。

我是基于同步的编程的新手,在为类似这样的程序创建伪代码时遇到了麻烦:

有一个导演和N个球员。这 导演(独立线程)洗牌(shuffle cards()),邀请玩家 (邀请玩家()),然后(分发卡片())。导演给 控制权交给第一个玩家,他暂停自己直到游戏结束。一旦导演 收到游戏结束的通知后,他检查记录(check game())以验证卡片是否 按照规则玩。

每个播放器都作为单独的线程运行。在可能的初始化之后,玩家等待直到她 示意打牌。然后她打出一张牌(play card())。 如果当前活跃的玩家检测到游戏已经结束(end of game() 为真),她 通知导演游戏结束并退出。如果游戏还没有结束,玩家会发出信号 下一位玩家并暂停自己,直到再次轮到她。

这是我想出的(记住消费者生产者问题)。请提供您的反馈和建议:

void Director()
{
  shuffle_cards();
  invite_players();
  distribute_cards();
  up(&full);
  down(&empty);
  check_game();
}
void Player()
{
  down(&full);
  down(&mutex);
  play_card();
  if (end_of_game == true){
      up(&empty);
  }
}

【问题讨论】:

  • 欢迎来到 SO!很好的问题,但我有点不清楚游戏玩法是如何进行的。玩家是否按照特定的顺序进行,比如0..n,它只是对所有人免费还是对卡牌/游戏影响排序做了一些事情(换句话说,你提到的“规则”是什么)?谢谢。
  • 我们没有收到任何有关订单的信息。但我猜想考虑它是从 0 到 N 或者可能根据分布顺序(只有在它不会太复杂的情况下)是有意义的。@ggorlen
  • 在这种情况下,我假设 check_game() 函数已经给出。 @ggorlen
  • 谢谢。另一个问题:线程是否应该在等待轮到他们的时候继续工作(例如考虑他们的动作是什么)还是阻塞?我假设是第一个,因为如果它们一个接一个地运行而没有重叠,就没有理由使用多线程。
  • 好吧,我们没有提供任何与此相关的信息。问题是“如果游戏还没有结束,玩家会向下一个玩家发出信号并暂停自己,直到再次轮到她。”也许现在,我们可以只考虑第一个回合的情况。 @ggorlen

标签: c multithreading synchronization semaphore


【解决方案1】:
  1. 只有一个信号量“满”不能唤醒下一个玩家。 每个玩家必须有 N 个信号灯来完成这项工作。

  2. Director 必须有一个信号量。

  3. 我在invite_players() 中担任主管;函数创建 N 个线程供 N 个玩家玩。

Sempahore Director = 0;

信号量播放器[N] = {0,0, ....0};

void Director()
{
    while (true) {
        shuffle_cards();
        invite_players();   // create the N player threads.
        distribute_cards(); // Distribute the cards to players.
        // Set all players semaphore in lock mode.
        Players[N] = {0,0, ....0};
        // Wakeup first player to start the game.
        up(&Players[0]);
        // Wait till the game is over
        down(&Director);
        check_game();
    }
}

void Player(int i) {
    // i is the player number playing the game in this thread.
    // Pick up the distributed cards.
    pickupCards();
    // Start the game.
    while (true) {
        // Wait for your turn.
        down(&Players[i]);
        // Check for end game condition.
        if (end_of_game == true){
            // Leave the game.
            break;
        }
        // Play the game.
        play_card();
        // Wake up next player.
        up(&Players[(i+1)%N]);
    }
    // You detected the game is over.
    // Now try to pass on that information to next neighbor. 
    // If next player is still playing, she will quit and pass on the same information.
    // If next player is not playing, the end of game is broadcasted to all.
    up(&Players[(i+1)%N]);
}

【讨论】:

  • 上面的代码有问题。在所有玩家退出之前,导演可以醒来并开始洗牌。您可以通过设置玩家计数器来阻止这种情况,并在玩家发现游戏结束时将其递减。当最后一个玩家检测到游戏结束时,她可以唤醒导演。
猜你喜欢
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多