From da9cd1f0431746a9789f6524f0e886472dd0958d Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Tue, 3 Jan 2023 18:40:16 +0900 Subject: [PATCH] WIP work on game Bug to fix is that players are stuck in "is ready" state. --- CMakeLists.txt | 2 + src/constants.h | 4 + src/ems.cc | 26 ++++- src/ems.h | 3 +- src/game.cc | 240 ++++++++++++++++++++++++++++++++++--------- src/game.h | 13 ++- src/helpers.cc | 5 + src/helpers.h | 10 ++ src/main.cc | 4 +- wasm_build/Makefile | 10 +- wasm_build/client.js | 19 ++-- wasm_build/logic.js | 113 ++++++++++---------- 12 files changed, 327 insertions(+), 122 deletions(-) create mode 100644 src/helpers.cc create mode 100644 src/helpers.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 02fd6d4..520559e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,8 @@ endif() set(RPSDuelNative_SOURCES src/main.cc src/game.cc + src/ems.cc + src/helpers.cc ) add_executable(RPSDuelNative ${RPSDuelNative_SOURCES}) diff --git a/src/constants.h b/src/constants.h index 0707fa0..58ac1f2 100644 --- a/src/constants.h +++ b/src/constants.h @@ -18,4 +18,8 @@ constexpr float READY_TIMER_MAX = 1.0F; constexpr float RESULTS_TIMER_MAX = 1.0F; +constexpr float SCORE_CHANGE_TIMER_MAX = 1.0F; + +constexpr float REQUEST_TIMER_MAX = 2.0F; + #endif diff --git a/src/ems.cc b/src/ems.cc index 975a2c2..6b1d8ce 100644 --- a/src/ems.cc +++ b/src/ems.cc @@ -4,14 +4,20 @@ #include #include -EM_JS(void, js_set_ready, (), { Rune.actions.set_ready("unused"); }); +EM_JS(void, js_set_ready, (bool is_ready), + { Rune.actions.set_ready({is_ready}); }); EM_JS(void, js_set_choices, (const char *first, const char *second, const char *third), { - Rune.actions.set_choices(UTF8ToString(first), UTF8ToString(second), - UTF8ToString(third)); + Rune.actions.set_choices({ + first : UTF8ToString(first), + second : UTF8ToString(second), + third : UTF8ToString(third) + }); }); +EM_JS(void, js_request_update, (), { Rune.actions.request_update("unused"); }); + EM_JS(int, canvas_get_width, (), { return document.getElementById("canvas").clientWidth; }); @@ -21,9 +27,9 @@ EM_JS(int, canvas_get_height, (), #include #endif -void call_js_set_ready() { +void call_js_set_ready(bool ready) { #ifdef __EMSCRIPTEN__ - js_set_ready(); + js_set_ready(ready); #else std::clog << "WARNING: emscripten not enabled, cannot call js_set_ready()!" << std::endl; @@ -40,6 +46,16 @@ void call_js_set_choices(const char *first, const char *second, #endif } +void call_js_request_update() { +#ifdef __EMSCRIPTEN__ + js_request_update(); +#else + std::clog + << "WARNING: emscripten not enabled, cannot call js_request_update()!" + << std::endl; +#endif +} + int call_js_get_canvas_width() { #ifdef __EMSCRIPTEN__ diff --git a/src/ems.h b/src/ems.h index 41209db..ee02345 100644 --- a/src/ems.h +++ b/src/ems.h @@ -1,9 +1,10 @@ #ifndef ROCK_PAPER_SCISSORS_DUEL_EMSCRIPTEN_H_ #define ROCK_PAPER_SCISSORS_DUEL_EMSCRIPTEN_H_ -extern void call_js_set_ready(); +extern void call_js_set_ready(bool ready = true); extern void call_js_set_choices(const char *first, const char *second, const char *third); +extern void call_js_request_update(); extern int call_js_get_canvas_width(); extern int call_js_get_canvas_height(); diff --git a/src/game.cc b/src/game.cc index e7f992a..35f010a 100644 --- a/src/game.cc +++ b/src/game.cc @@ -10,10 +10,12 @@ // local includes #include "constants.h" #include "ems.h" +#include "helpers.h" Game::Game() : spriteSheet(std::nullopt), status("Unknown status"), readyTimer(0.0F), - prevPos(0), cachedPos(0) { + resultsTimer(RESULTS_TIMER_MAX), scoreChangeTimer(SCORE_CHANGE_TIMER_MAX), + requestTimer(REQUEST_TIMER_MAX), prevPos(0), cachedPos(0) { spriteSheet = LoadTexture("resources/rockpaperscissorsSpriteSheet.png"); picked[0] = 0; @@ -29,21 +31,57 @@ void Game::update_state(const char *playerOne, const char *playerTwo, const char *currentPlayer, char first_first, char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, - bool second_ready, int pos) { + bool second_ready, int pos, int matchup_idx) { + // TODO DEBUG + if (std::strcmp(playerOne, currentPlayer) == 0) { + std::clog << "update_state:\n" + << " is p1: " + << (std::strcmp(playerOne, currentPlayer) == 0 ? "true" : "false") + << std::endl + << " p1: " << first_first << ", " << first_second << ", " + << first_third << "\n p2: " << second_first << ", " + << second_second << ", " << second_third << "\nfirst is " + << (first_ready ? "ready" : "not ready") << "\nsecond is " + << (second_ready ? "ready" : "not ready") << "\npos: " << pos + << " matchup_idx: " << matchup_idx << std::endl; + std::clog << "flags: " << flags.to_string().substr(32 - 13) << std::endl; + } // TODO handle changing choices from r/p/s to w/l and etc. if (playerOne) { this->playerOne = playerOne; - opponentPicked[0] = second_first; - opponentPicked[1] = second_second; - opponentPicked[2] = second_third; } if (playerTwo) { this->playerTwo = playerTwo; - opponentPicked[0] = first_first; - opponentPicked[1] = first_second; - opponentPicked[2] = first_third; } + if (std::strcmp(playerOne, currentPlayer) == 0) { + isPlayerOne = true; + if (Helpers::isValidChoice(second_first) && + Helpers::isValidChoice(second_second) && + Helpers::isValidChoice(second_third)) { + opponentPicked[0] = second_first; + opponentPicked[1] = second_second; + opponentPicked[2] = second_third; + } + } else if (std::strcmp(playerTwo, currentPlayer) == 0) { + isPlayerOne = false; + if (Helpers::isValidChoice(first_first) && + Helpers::isValidChoice(first_second) && + Helpers::isValidChoice(first_third)) { + opponentPicked[0] = first_first; + opponentPicked[1] = first_second; + opponentPicked[2] = first_third; + } + } else { + isPlayerOne = false; + } + + if ((!flags.test(10) && first_ready) || (!flags.test(11) && second_ready)) { + flags.set(12); + } + flags.set(10, first_ready); + flags.set(11, second_ready); + if (std::strcmp(currentPlayer, "undefined") == 0) { status = "Watching a Game..."; flags.set(2); @@ -59,12 +97,12 @@ void Game::update_state(const char *playerOne, const char *playerTwo, cachedPos = pos; } - if (flags.test(0) && flags.test(3) && first_ready && second_ready) { - flags.reset(3); - flags.set(4); - } else if (flags.test(0) && flags.test(4) && first_first == 0 && - first_second == 0 && first_third == 0 && second_first == 0 && - second_second == 0 && second_third == 0) { + if (flags.test(0) && flags.test(4) && flags.test(6) && flags.test(7) && + flags.test(8) && first_first == '?' && first_second == '?' && + first_third == '?' && second_first == '?' && second_second == '?' && + second_third == '?') { + std::cout << "Resetting for next round" << (isPlayerOne ? " (1) " : " (2) ") + << "..." << std::endl; flags.reset(0); flags.reset(1); flags.reset(3); @@ -73,13 +111,25 @@ void Game::update_state(const char *playerOne, const char *playerTwo, flags.reset(6); flags.reset(7); flags.reset(8); + flags.reset(9); + flags.reset(10); + flags.reset(11); + flags.reset(12); readyTimer = 0; - resultsTimer = 0; + resultsTimer = RESULTS_TIMER_MAX; picked[0] = 0; picked[1] = 0; picked[2] = 0; + + opponentPicked[0] = 0; + opponentPicked[1] = 0; + opponentPicked[2] = 0; + + call_js_set_ready(false); + + std::clog << "flags: " << flags.to_string().substr(32 - 13) << std::endl; } } @@ -93,12 +143,22 @@ void Game::update_impl() { return; } - readyTimer -= GetFrameTime(); + const float dt = GetFrameTime(); + + readyTimer -= dt; if (readyTimer <= 0.0F) { readyTimer = READY_TIMER_MAX; flags.flip(1); } + if (prevPos != cachedPos) { + scoreChangeTimer -= dt; + if (scoreChangeTimer <= 0) { + scoreChangeTimer = SCORE_CHANGE_TIMER_MAX; + prevPos = cachedPos; + } + } + if (IsMouseButtonPressed(0) && !flags.test(0)) { int triple_single_width = GetScreenWidth() / 3.0F + 0.5F; if (triple_single_width > ICON_MAX_WIDTH) { @@ -181,7 +241,7 @@ void Game::update_impl() { GetTouchY() <= GetScreenHeight() - triple_single_width * 2) { if (picked[0] != 0 && picked[1] != 0 && picked[2] != 0 && !flags.test(0)) { - call_js_set_ready(); + call_js_set_ready(true); flags.set(0); flags.set(3); } @@ -202,24 +262,57 @@ void Game::update_impl() { status = "Pick Moves!"; } - if (flags.test(0) && !flags.test(3) && flags.test(4)) { + if (flags.test(0) && flags.test(3) && flags.test(10) && flags.test(11)) { + char buf[6] = {picked[0], 0, picked[1], 0, picked[2], 0}; + call_js_set_choices(&buf[0], &buf[2], &buf[4]); + flags.reset(3); + flags.set(4); + } else if (flags.test(0) && !flags.test(3) && flags.test(4)) { // updates for result animations if (flags.test(5)) { flags.reset(5); + flags.reset(9); resultsTimer = RESULTS_TIMER_MAX; + } else if (flags.test(9)) { + if (!flags.test(8)) { + call_js_set_ready(true); + flags.reset(9); + flags.set(5); + } + } else { + resultsTimer -= dt; + if (resultsTimer <= 0) { + resultsTimer = RESULTS_TIMER_MAX; + if (!flags.test(6)) { + flags.set(6); + flags.set(9); + call_js_set_ready(true); + } else if (!flags.test(7)) { + flags.set(7); + flags.set(9); + call_js_set_ready(true); + } else if (!flags.test(8)) { + flags.set(8); + flags.set(9); + call_js_set_ready(true); + } + } } + } - resultsTimer -= GetFrameTime(); - if (resultsTimer <= 0) { - resultsTimer = RESULTS_TIMER_MAX; - if (!flags.test(6)) { - flags.set(6); - } else if (!flags.test(7)) { - flags.set(7); - } else if (!flags.test(8)) { - flags.set(8); - } + if (flags.test(12) && flags.test(10) && flags.test(11) && + prevPos == cachedPos && is_choices_set() && is_opponent_choices_set()) { + flags.reset(12); + call_js_request_update(); + std::cout << "Requesting update..." << std::endl; + } + + requestTimer -= dt; + if (requestTimer <= 0.0F) { + if (flags.test(10) && flags.test(11)) { + call_js_request_update(); + std::cout << "Requesting update (timer)..." << std::endl; } } } @@ -228,7 +321,8 @@ void Game::draw_impl() { if (flags.test(2)) { BeginDrawing(); ClearBackground(BLACK); - DrawText(status.c_str(), 0, 0, 30, RAYWHITE); + draw_score(); + DrawText(status.c_str(), 0, 20, 30, RAYWHITE); EndDrawing(); return; } @@ -243,46 +337,59 @@ void Game::draw_impl() { } if (flags.test(0)) { + draw_choice(0, picked[0], false, triple_single_width * 2.0F, WHITE); + draw_choice(1, picked[1], false, triple_single_width * 2.0F, WHITE); + draw_choice(2, picked[2], false, triple_single_width * 2.0F, WHITE); float ratio = 1.0F - resultsTimer / RESULTS_TIMER_MAX; + char otherPicked = + Helpers::isValidChoice(opponentPicked[0]) ? opponentPicked[0] : '?'; if (!flags.test(6)) { if (ratio < 1.0F) { - draw_choice(0, opponentPicked[0], false, triple_single_width, + draw_choice(0, otherPicked, false, triple_single_width, {255, 255, 255, (unsigned char)(ratio * 255.0F)}); draw_qm(0, false, triple_single_width, {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)}); } else { - draw_choice(0, opponentPicked[0], false, triple_single_width); + draw_choice(0, otherPicked, false, triple_single_width); } } else { - draw_choice(0, opponentPicked[0], false, triple_single_width); + draw_choice(0, otherPicked, false, triple_single_width); } + otherPicked = + Helpers::isValidChoice(opponentPicked[1]) ? opponentPicked[1] : '?'; if (!flags.test(7)) { - if (ratio < 1.0F) { - draw_choice(0, opponentPicked[1], false, triple_single_width, + if (!flags.test(6)) { + draw_qm(1, false, triple_single_width, WHITE); + } else if (ratio < 1.0F) { + draw_choice(1, otherPicked, false, triple_single_width, {255, 255, 255, (unsigned char)(ratio * 255.0F)}); - draw_qm(0, false, triple_single_width, + draw_qm(1, false, triple_single_width, {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)}); } else { - draw_choice(0, opponentPicked[1], false, triple_single_width); + draw_choice(1, otherPicked, false, triple_single_width); } } else { - draw_choice(0, opponentPicked[1], false, triple_single_width); + draw_choice(1, otherPicked, false, triple_single_width); } + otherPicked = + Helpers::isValidChoice(opponentPicked[2]) ? opponentPicked[2] : '?'; if (!flags.test(8)) { - if (ratio < 1.0F) { - draw_choice(0, opponentPicked[2], false, triple_single_width, + if (!flags.test(7)) { + draw_qm(2, false, triple_single_width, WHITE); + } else if (ratio < 1.0F) { + draw_choice(2, otherPicked, false, triple_single_width, {255, 255, 255, (unsigned char)(ratio * 255.0F)}); - draw_qm(0, false, triple_single_width, + draw_qm(2, false, triple_single_width, {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0f)}); } else { - draw_choice(0, opponentPicked[2], false, triple_single_width); + draw_choice(2, otherPicked, false, triple_single_width); } } else { - draw_choice(0, opponentPicked[2], false, triple_single_width); + draw_choice(2, otherPicked, false, triple_single_width); } - } else { + } else { // flags.test(0) unsigned char value = 0; if (flags.test(1)) { // fade ready bg to gray @@ -327,8 +434,10 @@ void Game::draw_impl() { {200, 200, 200, 255}); for (unsigned int i = 0; i < 3; ++i) { - draw_choice(i, picked[i], true, - (float)GetScreenHeight() - triple_single_width * 2.0F); + if (picked[i] != 0) { + draw_choice(i, picked[i], true, + (float)GetScreenHeight() - triple_single_width * 2.0F); + } } DrawRectangle(0, GetScreenHeight() - triple_single_width, @@ -339,7 +448,8 @@ void Game::draw_impl() { draw_choice(2, 's', true, (float)GetScreenHeight() - triple_single_width); } } - DrawText(status.c_str(), 0, 0, 20, RAYWHITE); + draw_score(); + DrawText(status.c_str(), 0, 20, 20, RAYWHITE); EndDrawing(); } @@ -379,7 +489,8 @@ void Game::draw_choice(const unsigned int idx, const char choice, default: // Should never happen. std::cerr << "WARNING: Invalid choice passed to draw_choice()!" - << std::endl; + " (value is \"" + << choice << "\" or \"" << (int)choice << "\")" << std::endl; break; } } @@ -434,13 +545,13 @@ void Game::draw_helper_coord(float *x, float *width, const unsigned int idx, switch (idx) { case 0: - *x = (GetScreenWidth() - *width * 4.0F) / 2.0F; + *x = GetScreenWidth() - *width * 4.0F; break; case 1: - *x = (GetScreenWidth() - *width * 3.0F) / 2.0F; + *x = GetScreenWidth() - *width * 3.0F; break; case 2: - *x = (GetScreenWidth() - *width * 2.0F) / 2.0F; + *x = GetScreenWidth() - *width * 2.0F; break; default: // Should never happen. @@ -451,3 +562,32 @@ void Game::draw_helper_coord(float *x, float *width, const unsigned int idx, } } } + +bool Game::is_choices_set() const { + return picked[0] != 0 && picked[1] != 0 && picked[2] != 0; +} + +bool Game::is_opponent_choices_set() const { + return opponentPicked[0] != 0 && opponentPicked[1] != 0 && + opponentPicked[2] != 0 && opponentPicked[0] != '?' && + opponentPicked[1] != '?' && opponentPicked[2] != '?'; +} + +void Game::draw_score() const { + char buf[6] = {prevPos < 0 ? '-' : ' ', + prevPos < 0 ? (char)('0' - prevPos) : (char)('0' + prevPos), + 0, + cachedPos < 0 ? '-' : ' ', + cachedPos < 0 ? (char)('0' - cachedPos) + : (char)('0' + cachedPos), + 0}; + if (prevPos != cachedPos) { + float ratio = 1.0F - scoreChangeTimer / SCORE_CHANGE_TIMER_MAX; + DrawText(&buf[3], 0, 0, 20, + {255, 255, 255, (unsigned char)(ratio * 255.0F)}); + DrawText(buf, 0, 0, 20, + {255, 255, 255, (unsigned char)((1.0F - ratio) * 255.0F)}); + } else { + DrawText(&buf[3], 0, 0, 20, WHITE); + } +} diff --git a/src/game.h b/src/game.h index 5373224..0d9f6c8 100644 --- a/src/game.h +++ b/src/game.h @@ -17,7 +17,7 @@ public: const char *currentPlayer, char first_first, char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, - bool second_ready, int pos); + bool second_ready, int pos, int matchup_idx); void do_update(); @@ -34,6 +34,11 @@ private: void draw_helper_coord(float *x, float *width, const unsigned int idx, const bool using_triple); + bool is_choices_set() const; + bool is_opponent_choices_set() const; + + void draw_score() const; + std::optional spriteSheet; std::string playerOne; std::string playerTwo; @@ -48,10 +53,16 @@ private: * 6 - revealed first moves * 7 - revealed second moves * 8 - revealed third moves + * 9 - finished revealing a move + * 10 - first ready + * 11 - second ready + * 12 - ready state dirty */ std::bitset<32> flags; float readyTimer; float resultsTimer; + float scoreChangeTimer; + float requestTimer; int prevPos; int cachedPos; char picked[3]; diff --git a/src/helpers.cc b/src/helpers.cc new file mode 100644 index 0000000..d8c277e --- /dev/null +++ b/src/helpers.cc @@ -0,0 +1,5 @@ +#include "helpers.h" + +bool Helpers::isValidChoice(char choice) { + return choice == 'r' || choice == 'p' || choice == 's'; +} diff --git a/src/helpers.h b/src/helpers.h new file mode 100644 index 0000000..9dcc0ce --- /dev/null +++ b/src/helpers.h @@ -0,0 +1,10 @@ +#ifndef ROCK_PAPER_SCISSORS_DUEL_HELPERS_H_ +#define ROCK_PAPER_SCISSORS_DUEL_HELPERS_H_ + +namespace Helpers { + +extern bool isValidChoice(char choice); + +} + +#endif diff --git a/src/main.cc b/src/main.cc index c90ddcc..0e3c7b6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -25,11 +25,11 @@ void EMSCRIPTEN_KEEPALIVE game_visual_update( const char *playerOne, const char *playerTwo, const char *currentPlayer, char first_first, char first_second, char first_third, char second_first, char second_second, char second_third, bool first_ready, bool second_ready, - int pos) { + int pos, int matchup_idx) { ((Game *)global_game_ptr) ->update_state(playerOne, playerTwo, currentPlayer, first_first, first_second, first_third, second_first, second_second, - second_third, first_ready, second_ready, pos); + second_third, first_ready, second_ready, pos, matchup_idx); } } // end em exposed functions diff --git a/wasm_build/Makefile b/wasm_build/Makefile index 8ff9c62..4f6f210 100644 --- a/wasm_build/Makefile +++ b/wasm_build/Makefile @@ -7,12 +7,14 @@ endif SOURCES = \ ../src/main.cc \ ../src/ems.cc \ - ../src/game.cc + ../src/game.cc \ + ../src/helpers.cc HEADERS = \ ../src/constants.h \ ../src/ems.h \ - ../src/game.h + ../src/game.h \ + ../src/helpers.h CXX = source ${HOME}/git/emsdk/emsdk_env.sh && em++ @@ -33,10 +35,10 @@ ${OUTDIR}/rock_paper_scissors_duel.html: ${SOURCES} ${HEADERS} ${OUTDIR}/client. ${OUTDIR}: mkdir ${OUTDIR} -${OUTDIR}/logic.js: +${OUTDIR}/logic.js: logic.js cp logic.js ${OUTDIR}/ -${OUTDIR}/client.js: +${OUTDIR}/client.js: client.js cp client.js ${OUTDIR}/ .PHONY: clean format index.html diff --git a/wasm_build/client.js b/wasm_build/client.js index 5d35abd..909813d 100644 --- a/wasm_build/client.js +++ b/wasm_build/client.js @@ -1,6 +1,6 @@ Rune.initClient({ visualUpdate: ({ newGame, yourPlayerId}) => { - const { player1, player2, first_choices, second_choices, first_ready, second_ready, pos } = newGame; + const { player1, player2, first_choices, second_choices, ready, pos, matchup_idx } = newGame; Module.ccall('game_visual_update', undefined, @@ -8,11 +8,16 @@ Rune.initClient({ 'number', 'number', 'number', 'number', 'number', 'number', 'boolean', 'boolean', - 'number'], - [player1, player2, yourPlayerId === undefined ? 'undefined' : yourPlayerId, - first_choices[0], first_choices[1], first_choices[2], - second_choices[0], second_choices[1], second_choices[2], - first_ready, second_ready, - pos]); + 'number', 'number'], + [player1, player2, + yourPlayerId === undefined ? 'undefined' : yourPlayerId, + first_choices[0].charCodeAt(0), + first_choices[1].charCodeAt(0), + first_choices[2].charCodeAt(0), + second_choices[0].charCodeAt(0), + second_choices[1].charCodeAt(0), + second_choices[2].charCodeAt(0), + ready[0], ready[1], + pos, matchup_idx]); }, }); diff --git a/wasm_build/logic.js b/wasm_build/logic.js index d7250e3..e03409c 100644 --- a/wasm_build/logic.js +++ b/wasm_build/logic.js @@ -4,15 +4,15 @@ Rune.initLogic({ setup: (players) => ({ player1: players[0], player2: players[1], - first_choices: new Array(3).fill(null), - second_choices: new Array(3).fill(null), - first_ready: false, - second_ready: false, + first_choices: new Array(3).fill('?'), + second_choices: new Array(3).fill('?'), + ready: new Array(2).fill(false), pos: 0, + matchup_idx: 0, }), actions: { - set_choices: (first, second, third, { game, playerId }) => { - if (!game.first_ready || !game.second_ready) { + set_choices: ({first, second, third}, { game, playerId }) => { + if (!game.ready[0] || !game.ready[1]) { throw Rune.invalidAction(); } @@ -20,7 +20,7 @@ Rune.initLogic({ function is_choices_filled(choices) { for (let i = 0; i < 3; ++i) { - if (choices[i] === null) { + if (choices[i] === null || choices[i] === '?') { return false; } } @@ -52,50 +52,67 @@ Rune.initLogic({ game.second_choices[1] = second; game.second_choices[2] = third; } + }, + set_ready: ({ is_ready }, { game, playerId }) => { + let is_first = game.player1 === playerId; + if (is_first) { + game.ready[0] = is_ready; + } else { + game.ready[1] = is_ready; + } + }, + request_update: (unused, {game, playerId}) => { + function is_choices_filled(choices) { + for (let i = 0; i < 3; ++i) { + if (choices[i] === null || choices[i] === '?') { + return false; + } + } + return true; + } - if (!is_choices_filled(game.first_choices) + if (!game.ready[0] + || !game.ready[1] + || !is_choices_filled(game.first_choices) || !is_choices_filled(game.second_choices)) { return; } // Both sides are ready, iterate through matchups - let has_remaining = false; - - for (let i = 0; i < 3; ++i) { - // Get next matchup - if (game.first_choices[i] === 'r' - || game.first_choices[i] === 'p' - || game.first_choices[i] === 's') { - // check if first won the matchup - if ((game.first_choices[i] === 'r' && game.second_choices[i] === 's') - || (game.first_choices[i] === 'p' && game.second_choices[i] === 'r') - || (game.first_choices[i] === 's' && game.second_choices[i] === 'p')) { - game.first_choices[i] = 'w'; - game.second_choices[i] = 'l'; - game.pos = game.pos + 1; - } - // check if second won the matchup - else if ((game.first_choices[i] === 'r' && game.second_choices[i] === 'p') - || (game.first_choices[i] === 'p' && game.second_choices[i] === 's') - || (game.first_choices[i] === 's' && game.second_choices[i] === 'r')) { - game.first_choices[i] = 'l'; - game.second_choices[i] = 'w'; - game.pos = game.pos - 1; - } - // matchup was a draw - else { - game.first_choices[i] = 'd'; - game.second_choices[i] = 'd'; - } - has_remaining = i === 2 ? false : true; - } + // check if first won the matchup + if ((game.first_choices[game.matchup_idx] === 'r' + && game.second_choices[game.matchup_idx] === 's') + || (game.first_choices[game.matchup_idx] === 'p' + && game.second_choices[game.matchup_idx] === 'r') + || (game.first_choices[game.matchup_idx] === 's' + && game.second_choices[game.matchup_idx] === 'p')) { + //game.first_choices[game.matchup_idx] = 'w'; + //game.second_choices[game.matchup_idx] = 'l'; + game.pos = game.pos + 1; + } + // check if second won the matchup + else if ((game.first_choices[game.matchup_idx] === 'r' + && game.second_choices[game.matchup_idx] === 'p') + || (game.first_choices[game.matchup_idx] === 'p' + && game.second_choices[game.matchup_idx] === 's') + || (game.first_choices[game.matchup_idx] === 's' + && game.second_choices[game.matchup_idx] === 'r')) { + //game.first_choices[game.matchup_idx] = 'l'; + //game.second_choices[game.matchup_idx] = 'w'; + game.pos = game.pos - 1; } + // matchup was a draw + //else { + //game.first_choices[game.matchup_idx] = 'd'; + //game.second_choices[game.matchup_idx] = 'd'; + //} + game.matchup_idx = game.matchup_idx + 1; - game.first_ready = false; - game.second_ready = false; - if (!has_remaining) { + game.ready[0] = false; + game.ready[1] = false; + if (game.matchup_idx >= 3) { if (game.pos <= -3) { // second won Rune.gameOver(); @@ -105,20 +122,12 @@ Rune.initLogic({ } else { // game is still going for (let i = 0; i < 3; ++i) { - game.first_choices[i] = null; - game.second_choices[i] = null; + game.first_choices[i] = '?'; + game.second_choices[i] = '?'; } + game.matchup_idx = 0; } } }, - set_ready: (unused, { game, playerId }) => { - let is_first = game.player1 === playerId; - - if (is_first) { - game.first_ready = true; - } else { - game.second_ready = true; - } - }, }, }) -- 2.49.0