Противник двигает обещание в сетевой игре

Я провел последние четыре дня, изучая обещания, сопрограммы, волокна, продолжения и т. Д.

Я до сих пор не могу понять, как решить мои пошаговые ходы карточных игр в многопользовательском режиме, в которых начинающий игрок фактически является "игровым" контролером "до пяти, будь то ИИ или человек-игрок.

Код ниже работает, но есть одна проблема:

он не может обнаружить движения карт оппонента и поэтому продолжает играть без них, что, конечно, создает беспорядок.

Может кто-нибудь предложить, пожалуйста, изменение моей общей концепции или способ использования обещания или одну из других "синхронизирующих" конструкций?

Вот четыре ключевых области моего кода:

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, но с компонентом выигрыша

(направлено на то, чтобы помочь детям с основной арифметикой).

3 ответа

Подумайте о наличии состояния доски, которое является глобальным, и ходы игрока / ИИ изменяют его. Затем, когда пришло время для противника ИИ сделать ход, он проверяет текущее состояние доски и решает ход.

Если ваше состояние доски просто представлено элементами на странице, вам потребуется способ его сканирования и вычисления полезного представления состояния платы в памяти. Без деталей вашей реализации трудно быть более конкретным.

Решение основывалось на двух вещах:

  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();
}

Может быть, начать думать с точки зрения игрового цикла, что-то вроде этого:

  1. (хост) Трансляция состояния игры.
  2. (хост) Ожидает подтверждения от всех клиентов, что широковещание было получено.
  3. (клиенты) Визуализация состояния игры.
  4. (хост) Получает подтверждения, а затем сообщает следующему клиенту (и, следовательно, его игроку), что это его очередь.
  5. (хост) Ожидает ход игрока
  6. (клиент) Разблокирует пользовательский интерфейс, позволяющий игроку сделать ход.
  7. (игрок) заставляет двигаться.
  8. (клиент) Отправляет команду перемещения и повторно блокирует пользовательский интерфейс.
  9. (host) Получает команду перемещения и соответственно изменяет состояние игры.

Затем вернемся к 1.

Кроме того, думайте об игроках ИИ как об особом случае игроков-людей. Если вы можете сделать это правильно для людей, то (повторное) введение ИИ должно быть довольно простым.

Другие вопросы по тегам