0

我有一个应该同时运行多个线程的程序。

这是纸牌游戏 Uno 的模拟,你应该为每个玩家设置一个线程。

现在问题来了:只要玩家手上的牌堆上的牌的数量和颜色与该牌相同,但轮到该牌手,他可以“切线”并放下牌。然后切线的玩家旁边的玩家继续。

我有一个类 Player :

class Player implements Runnable {

    public boolean isHisTurn = false;

    public Thread makeMove(final Card topCard, final boolean isHisTurn) {
        Thread thread = new Thread(this);
        thread.start();
        return thread;
    }
}

thread.start() 然后启动 run 方法,在这里我有我的逻辑和决策。在 run() 开始时,线程随机休眠 300 - 700 毫秒,以便在此时间范围内进行切割线。

我的问题是,我是否应该将线程存储在某个地方,如果是,那么当轮到其他玩家时,我可以在哪里以及如何在线程之间切换?我知道它与布尔isHisTurn有关,我只是不知道如何使用它。

是的,这是家庭作业,但我只要求其中的一小部分,我不想要一个完整的答案,只是为了把我推向正确的方向。

4

2 回答 2

3

当轮到其他玩家时,我如何在线程之间切换?

线程的显着特点是可以同时运行多个线程。如果您不使用该功能,则使用线程毫无意义。由于一个玩家在轮到他的时候也可以移动,因此所有玩家同时处于活动状态实际上是有道理的。因此,我会为每个玩家创建(并启动)一个线程。该线程将在睡眠和移动之间交替。

这就留下了线程如何交互的问题。为此,我会创建一个类,如:

class Game {
    Card topCard;
    Player nextPlayer;

    ...
}

并将游戏实例提供给每个玩家线程。当游戏线程在考虑他的举动时,他可以查看最上面的牌,以及是否轮到他。在进行移动时,他只需更新 Game 实例中的字段。

当然,由于不同的线程可以同时处于活动状态,所以有可能两个玩家同时尝试移动(或者换句话说,一个玩家可能决定出牌,但另一个玩家更快,使得初始玩家的移动不再有效)。通过同步对实例的访问,最容易避免这种Game情况。对于现实主义,您可能会在查看游戏状态时想要同步,然后思考,然后再次同步以进行移动。但是,在整个“观察、思考和移动”循环中同步可能会更容易,因为这样可以确保玩家不会干扰彼此的思考,并减少您需要处理的极端情况的数量。

另一个问题是终止。一旦第一个玩家没有剩余牌,游戏就会结束,因此其他玩家需要一种方法来注意到这一事实。最简单的可能是完成玩家宣布自己为获胜者(例如,通过winningPlayerGame实例中设置一个字段),并且其他线程在宣布获胜者后立即终止。

于 2013-05-19T08:45:42.580 回答
0

很难帮助解决家庭作业问题,因为通常教授正在寻找某种解决方案并正确解决问题,但以错误的方式仍然可能对您不利。例如,假设您应该每个玩家有一个线程,这是非常有帮助的,因为还有许多其他有效的方法可以做到这一点,但如果您这样做,那么您的家庭作业将是错误的。因此,如果您有其他有关预期解决方案的信息要分享,请分享。我认为选择这个问题是因为您还没有等待信号量。

如果您要为每个玩家创建一个线程,那么您可以根据人类玩家的游戏方式对程序进行建模。每个玩家都知道转储顶部的牌,其他玩家是谁,他们玩的顺序,最后玩的人以及他们玩的东西。因此,您希望在所有线程都可以看到的某些对象中表示所有这些事实。

每个线程(玩家)也有自己的手,只有它可以看到,因此应该将其建模为每个线程的对象。

关键是玩家(线程)做出动作!您的主程序只是启动线程并等待游戏结束。玩家可以随机睡一段时间,然后醒来,看看他们是否可以移动,如果可以移动,然后再继续睡觉。

于 2013-05-19T09:02:45.840 回答