2

我正在使用 OpenGL 图形在 C++ 上编写游戏(奥赛罗),在用户放置一块后,我需要一些东西来“等待”或“休眠”游戏。用户玩完后CPU播放太快,所以无法看到用户的动作。我尝试了睡眠功能,但它不起作用。基本上,这个想法是:

播放器插入新棋子----休眠1秒---- CPU插入新棋子

有没有办法做到这一点?

4

2 回答 2

4

我假设你只是在学习编程。你正在发现一个重要的步骤。

人们写的第一个代码很可能是在控制台上,它是串行的:写一个问题,等待输入,做某事。打印输出。这很好,许多程序都是这样工作的。

不幸的是,图形用户界面没有。它们大致有三个独立的部分:

  • 计算机工作(就像你的游戏中的人工智能)
  • 玩家做某事,比如点击棋盘移动
  • 在屏幕上显示当前正在发生的事情

现在,所有这些事情都可能在其中之一发生的同时发生。有些人需要互相等待。但它们基本上可以随机发生。混乱!如果玩家在 AI 还在思考的时候点击了怎么办?由于操作系统移动了窗口,因此可能需要重新绘制板。

您没有说您正在使用什么操作系统,但 OpenGL 应该始终只执行第 3 项。准确显示板的原样。如果你想让计算机变慢,它应该在第 1 点。

解决这个问题的经典方法是消息循环和队列。

如果您的第一个程序如下所示:

while ( gamenotdecided )
    ask human to enter move (wait for it)
    update board (and show it)
    compute AI move
    update board (and show it)
do

新的方式更像是这样:

while ( gamenotdecided )
    get the next message:
        if it is show board: show board;
        if it is input: if it is not the humans turn print an error. 
                        else make it, and send yourself a message to show the board and start AI
        if it is AI: Do a small part of AI thinking. 
                     Send yourself a message to keep doing AI if there is no good move yet. 
                     If the AI is decided:
                         if enough time passed
                              make the move, send yourself a message to show the board
                         else 
                              wait a tiny bit and send yourself a message to do AI again 
do   

人工智能思维的一部分是,如果人工智能太快,你可以等待时间。关键是你可以随时展示板子,不管是用户轮还是AI轮。所有的 GUI 操作系统也有一种方法,只有在一定时间后才发送消息。但即使没有,你也可以轻松做到:如果你收到一条 AI 消息,AI 知道该做什么,但现在还不是时候,不要做任何事情,给自己发送一条 AI 消息。你的想法是推迟画板。但你真正想做的是延迟人工智能让它移动。这是一个微妙但非常重要的区别。

重要的是要记住董事会及其“状态”始终存在。但是任何消息都可能随时发生:如果用户在 AI 思考时点击?没问题,董事会告诉你轮到谁了。如果您需要绘制窗口,因为它被移动了?没问题,董事会就在那里,无论轮到谁。人工智能太快了?没问题,在更新电路板之前继续旋转一段时间。人工智能太慢了?没问题,让它想一想,再发个展板和AI。

我希望这能解释一下你应该看的概念。睡眠或线程与它无关。它们是优化。人们处理此问题的一种方式称为 MVC、模型、视图、控制器。在这种情况下,模型将是董事会状态,包括轮到谁了。视图是您的 GL 代码。玩家和 AI 都是控制器。

但首先,如果你从这里拿走一件事:GUI 不是连续的。任何事情都可能随时发生。消息队列是处理此问题的一种简单方法。

我有点好奇您使用的是哪种语言和操作系统,如果我知道的话,我可能会给出更好的例子。您是否使用任何 OpenGL 框架?

于 2013-08-03T08:58:01.317 回答
0

C++11this_thread::sleep_for()作为线程支持库的一部分提供。
如果您无权访问 C++11,则可以尝试POSIX 线程库

于 2013-08-03T07:18:46.233 回答