OpenGL グラフィックスを使用して C++ でゲーム (オセロ) を作成しています。ユーザーがピースを配置した後、ゲームを「待機」または「スリープ」する何かが必要です。ユーザーがプレイした直後は CPU のプレイが速すぎて、ユーザーの動きが見えません。スリープ機能を試してみましたが、うまくいきません。基本的に、アイデアは次のとおりです。
プレーヤーが新しい駒を挿入 ----1 秒間スリープ ---- CPU が新しい駒を挿入
これを行う方法はありますか?
プログラミングを学んでいるだけだと思います。そして、あなたは重要なステップを発見しています。
人々が最初に書くコードはコンソール上にある可能性が高く、シリアルです: 質問を書き、入力を待ち、何かをします。出力を印刷します。それはまったく問題なく、多くのプログラムはこのように機能します。
残念ながら、GUI にはありません。それらには、およそ 3 つの独立した部分があります。
現在、これらすべてのことは、他のいずれかが進行している間に発生する可能性があります。お互いに待つ必要がある人もいます。しかし、それらは基本的にランダムな順序で発生する可能性があります。混沌!AI がまだ考えている間にプレイヤーがクリックするとどうなりますか? OSがウィンドウを移動したため、ボードを再描画する必要があるかもしれません。
どの OS で作業しているかはわかりませんでしたが、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 の思考の部分は、AI が速すぎる場合に、時間を待つことができる場所です。重要なのは、ユーザーまたは AI のターンに関係なく、いつでもボードを表示できることです。すべての GUI OS には、一定の時間が経過した後にのみメッセージを送信する方法もあります。しかし、それがなくても簡単に実行できます。AI メッセージを受け取った場合、AI は何をすべきかを知っていますが、まだその時ではありません。何もせずに別の AI メッセージを自分に送信してください。あなたのアイデアは、ボードの描画を遅らせることでした。しかし、本当にやりたいことは、AI の動きを遅らせることです。これは微妙ですが、非常に重要な違いです。
ボードとその「状態」は常に存在することに注意してください。しかし、メッセージはいつでも発生する可能性があります。AI が考えているときにユーザーがクリックした場合は? 問題ありません。ボードは誰の番かを示します。移動したためにウィンドウを描画する必要がある場合は? 誰の番でも、ボードはすぐそこにあります。AI速すぎない?問題ありません。ボードを更新する前に、しばらく回転し続けてください。AIが遅すぎる?問題ありません。少し考えて、ショー ボードと AI を再度送信します。
これが、あなたが見るべき概念を少し説明してくれることを願っています。スリープやスレッドはまだ関係ありません。それらは最適化です。これにアプローチする 1 つの方法は、MVC、モデル、ビュー、コントローラーと呼ばれます。この場合、モデルはボードの状態であり、誰のターンであるかを含みます。ビューはGLコードです。そして、プレイヤーと AI の両方がコントローラーです。
しかし、まず、これから 1 つのことを取り上げると、GUI はシーケンシャルではありません。いつでも何でも起こりえます。メッセージ キューは、これに対処する簡単な方法です。
あなたが使用している言語と OS について少し興味があります。それがわかれば、より良い例を挙げることができるでしょう。OpenGL 用のフレームワークを使用していますか?
C++11 はthis_thread::sleep_for()
、スレッド サポート ライブラリの一部として提供します。
C++11 にアクセスできない場合は、POSIX スレッド ライブラリを試すことができます。