我正在使用 OpenGL 图形在 C++ 上编写游戏(奥赛罗),在用户放置一块后,我需要一些东西来“等待”或“休眠”游戏。用户玩完后CPU播放太快,所以无法看到用户的动作。我尝试了睡眠功能,但它不起作用。基本上,这个想法是:
播放器插入新棋子----休眠1秒---- CPU插入新棋子
有没有办法做到这一点?
我假设你只是在学习编程。你正在发现一个重要的步骤。
人们写的第一个代码很可能是在控制台上,它是串行的:写一个问题,等待输入,做某事。打印输出。这很好,许多程序都是这样工作的。
不幸的是,图形用户界面没有。它们大致有三个独立的部分:
现在,所有这些事情都可能在其中之一发生的同时发生。有些人需要互相等待。但它们基本上可以随机发生。混乱!如果玩家在 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 框架?
C++11this_thread::sleep_for()
作为线程支持库的一部分提供。
如果您无权访问 C++11,则可以尝试POSIX 线程库