93505


javascriptでオセロを作っています。  
ユーザーがpタグをクリックすると、クリックした盤面の位置がrun()に渡されます。  
プレイヤーが打った後ランダムに打つNPCを用意したのですが、ヴィジュアル的にそれぞれの処理に間を開けたいと思い、runNpc()の冒頭に下記のような記述をしました。

[code]

    let start = new Date();
    while (new Date() - start < 400);
    
[/code]

しかし、プレイヤーが打った後の盤面表示がされないまま、０.４秒後、NPCが打った後の盤面になってしまいます。  
盤面の表示はプレイヤーとNPCのどちらが打ったときにもreverse()内で呼び出しているので、プレイヤーが打った後の盤面表示はrunNpc()よりも先のはずなのですが、なぜこうなるのか原因が見つけられません。  
どなたかご教示いただければ幸いです。

下記URLソース全文です。  
<https://github.com/gr9pe/jsOsero/blob/main/osero.js>

[code]

    function runNpc(){
        let start = new Date();
        while (new Date() - start < 400);　//0.4秒待つ
    
        let list = canPutPosList(white);　//置ける場所を配列で返す(NPCは後攻の白)
        if(list.length!=0){
            let index = Math.floor(Math.random()*list.length);
            reverse(list[index]);
        }
        changeTurn();
    }
    
    function run(pos){
        let inputPos = [parseInt(pos.charAt(0)),parseInt(pos.charAt(1))];
        
        let canPutFlag = false;
        for(let canPutPos of canPutPosList(turn)) {
            if(canPutPos.toString()==inputPos.toString()) {
                canPutFlag = true;
                break;
            }
        }
        if(canPutFlag) {
            reverse(inputPos);
            if(isFinish()){
                printResult();
                document.getElementById("turn").textContent = "";
                return;
            }else{
                changeTurn();
                if(canPutPosList(turn).length==0 && !isFinish()){
                    changeTurn();
                    document.getElementById("message").textContent = "置ける場所がありません";
                }
                if(npc && turn==white){
                    runNpc();
                    return;
                }
                return;
            }
        }else{
            document.getElementById("message").textContent = "その場所には置けません";
        }
    }
    
    //盤面の表示
    function printField() {
        let f ='';
        document.getElementById("fields").innerHTML = f; 
        for(let i=0;i<10;i++) {
            for(let j=0;j<10;j++) {
                document.getElementById("fields").innerHTML += '<p>'+ field[i][j] +'</p>';
            }
            document.getElementById("fields").innerHTML += '<br/>'; 
        }
    }
    
    //ひっくり返して表示する
    function reverse(inputPos) {
        //割愛
        printField();
    }
    
[/code]


CC BY-SA 4.0
2023-01-21T10:25:02.237
93490
2023-01-22T09:38:40.650
2023-01-21T11:04:40.687
3060
56689
question
javascript html
JavaScriptでオセロを作っています。処理の一時停止をしたいのですが、思ったような挙動になりません。


ブラウザがイベントの処理でJavaScriptのコードを呼び出したら、ブラウザはそれが終了してから画面更新や次のイベントの処理に取り掛かります。

ですからプレイヤーが着手した直後の状態を表示したければ、NPCの着手をせずに`run`からリターンしなければいけません。

それではNPCの着手はどうするかですが、指定した時間が過ぎた後でJavaScriptのコードを呼んでもらう、`setTimeout` という方法があります。

`runNpc();` の代わりに `setTimeout(runNpc, 400);`
とすることで、ブラウザに制御が戻って画面更新した後でNPCの着手処理を実行してくれます。


CC BY-SA 4.0
2023-01-22T09:38:40.650
93505
2023-01-22T09:38:40.650
9464
93490
answer