0

I'm designing a simple browser based version of a popular game and I'm having trouble understanding how promises should be created by a button .onclick handler to deal with user input only at specific times. Here's the basic game logic:

<button id="button1">1</button>
<button id="button2">2</button>
<script>

var Game = {
  ready_for_input: false,
  game_over: false,
  play_round: async function () {

    //do some setup, check for a few initial win conditions, then......

    if (round_not_yet_won) {
      ready_for_input=true;
      while (round_not_yet_won) {
        await (//somehow get a promise that is fulfilled on button click from one of two buttons)
        //when promise fulfilled by click, do some additional condition checking
        if (win) {round_not_yet_won=false; ready_for_input=false; return;} else {//go back to while loop}
}
}
}

while (!Game.game_over){
  Game.play_round();
}

//get buttons by id and addEventListener('click', handle_button_x())
function handle_button_x() {//create a promise maybe?}

</script>

I realized while debugging previously that the reason things weren't flowing logically was that I hadn't used async/await on the while loop, so it was sporadically hanging on certain initial conditions and not letting the page send the click event. Now i realize i need to let play_round() await the button click and stop blocking so the page can do its thing, but i'm not understanding how I link up the promise both to the play_round() await structure and the handle_button_x() handler. It seems wrong to my brain to do something like this, e.g.:

await handle_button_x();

because this will return a promise, but it seemingly won't be linked to a button press event call of the same function. Does my failure of understanding lie in how Promise.resolve() is called maybe?

Thanks for any help.

  • 2
    You don't wait for button presses. You use event listeners. – Barmar Jul 25 '22 at 18:33
  • Yes, you can do that, see [Can I wait for a DOM event to resolve?](https://stackoverflow.com/q/58897433/1048572), [Resolve promise into addEventListener](https://stackoverflow.com/q/45613894/1048572) or [Is there a way to cleanly create a promise that resolves after left mouse up or down?](https://stackoverflow.com/q/65820279/1048572). However, notice that using `async`/`await` for button presses lets you always only wait for one button at a time, making it hard to model choice. – Bergi Jul 25 '22 at 19:00
  • @Barmar I think i understand why async/await is a non-standard choice here. But does that mean I need to not let execution remain within my play_round() code? Rather i should return execution to the page and then re-enter play_round() upon button press with a state test on the Game object based on the button id? I think the core problem with my code is that I'm getting handlers executing at unexpected times or not getting executed at all because of loop conditions in the "main" play_round() code. – defterGoose Jul 25 '22 at 19:49
  • @defterGoose Yes, it makes sense to model games as state machines – Bergi Jul 25 '22 at 19:51
  • It might be possible, but it will be really complicated. You need to wrap the event listener in a Promise. And each time it triggers, you'll need to wrap it again, because a promise can only resolve once. – Barmar Jul 25 '22 at 19:56
  • @Bergi Thanks. I think I'm used to things being very imperative so this is a good observation. – defterGoose Jul 25 '22 at 19:59

0 Answers0