0

在过去的四天里,我一直在研究承诺、协程、纤程、延续等。

我仍然不知道如何解决我的多人回合制纸牌游戏动作,其中起始玩家实际上是最多五个 AI 或人类玩家的游戏“控制器”。

下面的代码有效,但有一个问题:-

它无法检测到人类 oppo 的牌移动,因此在没有它们的情况下继续玩,这当然会造成混乱。

任何人都可以建议改变我的整体概念或使用承诺或任何其他“同步”构造的方法吗?

以下是我的代码的四个关键区域:

function oppoPlays () {
    // can only go through here if game starter
    if (joiner!="") {return;}
    for (pp=1; pp<numberofplayers; pp++) {
        if (oppoType[pp] == "AI") {
            // an AI player moves
            .
            .
        } else {
            // non-AI player
            var yourTurnmsg="It's "+playerNames[pp]+"'s turn";
            // tell human player that it's their turn
            $("#text_message").val(yourTurnmsg).trigger(jQuery.Event('keypress', { keyCode: 13, which: 13 }));
            // how to detect human oppo's card moved?

        }
    }
}

// chat functionality
$("#text_message").on("keypress", function(e) {
    if (e.keyCode == 13){
        payload = new Object();
        payload.action = 'chat_text';
        payload.chat_text = tmsg; // It's michael29's turn
        payload.user_id = playerNames[pp];
        payload.game_no = game_no;
        socket.send(JSON.stringify(payload));
    }
});

// socket gets oppo's response
function checkJson(res, sttr_id, game_no) {
    if(res.action=="game_move"){
        // find player
        var pp=playerNames.indexOf(res.user_id);
        cpos=res.cardno;
        playCard_oppo(pp, cpos);
    }
}

// turn an oppo's card face up and update scores
function playCard_oppo(pp, cardno) {
    //  and move it to the stack
    topoc= parseInt($("#oppo_card" + cardno).css('top'));
    leftoc=parseInt($("#oppo_card" + cardno).css('left'));
    $("#oppo_card" + cardno).css({ top: topoc, left: leftoc, opacity: "50%" });
    .
    .
    if (joiner=="") {
        // tell oppoPlays fn that the card has moved 
    }
}

该游戏在概念上类似于 uno,但具有评分组件

(旨在帮助孩子掌握基本算术)。

4

3 回答 3

1

考虑让棋盘状态是全局的,玩家/AI 移动会对其进行修改。然后,当 AI 对手需要下棋时,它会参考当前棋盘状态并决定下棋。

如果您的板状态仅由页面上的元素表示,您将需要一种方法来扫描它并计算板状态的有用内存表示。如果没有您的实施细节,很难更具体。

于 2018-01-21T08:56:44.247 回答
0

也许开始考虑一个播放周期,像这样:

  1. (host) 广播游戏状态。
  2. (主机)等待所有客户端确认收到广播。
  3. (客户端)渲染游戏状态。
  4. (主机)接收确认,然后通知下一个客户端(以及它的玩家)轮到他/她/它了。
  5. (主持人)等待玩家移动
  6. (客户端)解锁允许玩家移动的 UI。
  7. (玩家)移动。
  8. (客户端)发送移动命令并重新锁定 UI。
  9. (主机)接收移动命令并相应地修改游戏状态。

然后回到1。

此外,将 AI 玩家视为人类玩家的特例。如果你能把它用于人类,那么(重新)引入人工智能应该是相当简单的。

于 2018-01-21T11:24:07.153 回答
0

解决方案取决于两件事:-

  1. 将 AI 玩家代码与人类玩家代码分开;

  2. 添加和删​​除在检测到人类移动后触发的窗口事件。

压缩代码现在看起来像这样:-

// if this is game starter give each player a turn
if (joiner == "") {
    //  there's always at least one
    pp = 1;
    if (oppoType[pp] == "AI") { AIplays(); } else { humanPlays(); }
}

function humanPlays () {
    // tell human player that it's their turn
    var yourTurnmsg="It's "+playerNames[pp]+"'s turn"
    $("#text_message").val(yourTurnmsg).trigger(jQuery.Event('keypress', { keyCode: 13, which: 13 }));

    //window.addEventListener("humanPlayed", function(evnt) {
    $(window).on("humanPlayed", function(evnt) {
        endOfTurn();
    });
}

function endOfTurn () {
    if (!(winner)) {
        if (pp++ != numberofplayers) {
            if (oppoType[pp] == "AI") {
                setTimeout(function (){ $("#clickForNextPlayer").show(); }, 1000);
            } else {
                $("#clickForNextPlayer").trigger('click');
            }
        }
    }
}

// click for next player
$("#clickForNextPlayer").on('click', function() {
    $("#clickForNextPlayer").hide();
    $(window).off("humanPlayed");
    if (pp == numberofplayers) {
        // uncover outStack for game starter to play
        $("#outStackcover").hide();
        return;
    }
    if (oppoType[pp] == "AI") { AIplays(); } else { humanPlays(); }
});

function AIplays () {
    AIcardno = chooseCard(pp, diffLevel);
    .
    .
    if ($("#chatWindow").is(":visible")) {
        payload = new Object();
        payload.action="game_move";
        payload.game_no=gamestarted;
        payload.user_id=playerNames[pp];
        payload.cardno=AIcardno;
        socket.send(JSON.stringify(payload));
    }
    $("#oppo_card" + cc).css('background-image', "url(JerseyTeam" + playerNumbers[(pp == numberofplayers ? 1 : pp)] + ".gif)");
    outStackturn();
    endOfTurn();
}
于 2018-01-22T14:59:26.487 回答