From e16b9d0610254af5b6a80803b5e02f77b2940b76 Mon Sep 17 00:00:00 2001 From: Roman Olearski Date: Tue, 29 Nov 2016 17:38:37 +0100 Subject: [PATCH] fxing #11 Fix operation of "insurance" parameter implementing #12 Add tournament rules to prevent a game from lasting too long due to ties --- libraries/chain/game_object.cpp | 42 ++++++++++++++++++--------- libraries/chain/match_object.cpp | 26 +++++++++++++++-- libraries/chain/tournament_object.cpp | 10 ++++--- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/libraries/chain/game_object.cpp b/libraries/chain/game_object.cpp index 30a646ad..ea2ac76a 100644 --- a/libraries/chain/game_object.cpp +++ b/libraries/chain/game_object.cpp @@ -351,7 +351,7 @@ namespace graphene { namespace chain { void game_object::evaluate_move_operation(const database& db, const game_move_operation& op) const { - const match_object& match_obj = match_id(db); + //const match_object& match_obj = match_id(db); if (game_details.which() == game_specific_details::tag::value) { @@ -451,18 +451,31 @@ namespace graphene { namespace chain { const match_object& match_obj = match_id(db); const tournament_object& tournament_obj = match_obj.tournament_id(db); const rock_paper_scissors_game_options& game_options = tournament_obj.options.game_options.get(); - for (unsigned i = 0; i < 2; ++i) + if (!game_options.insurance_enabled) // no automatic moves { - if (!rps_game_details.commit_moves[i] || - no_player_has_reveal_move) - { - struct rock_paper_scissors_throw_reveal reveal; - reveal.nonce2 = 0; - reveal.gesture = (rock_paper_scissors_gesture)db.get_random_bits(game_options.number_of_gestures); - rps_game_details.reveal_moves[i] = reveal; - ilog("Player ${player} failed to commit a move, generating a random move for them: ${gesture}", - ("player", i)("gesture", reveal.gesture)); - } + struct rock_paper_scissors_throw_reveal reveal; + reveal.nonce2 = 0; + reveal.gesture = (rock_paper_scissors_gesture)db.get_random_bits(game_options.number_of_gestures); + rps_game_details.reveal_moves[0] = + rps_game_details.reveal_moves[1] = reveal; + ilog("Both players failed to commit a move, generating a random move for them: ${gesture}", + ("gesture", reveal.gesture)); + } + else + { + for (unsigned i = 0; i < 2; ++i) + { + if (!rps_game_details.commit_moves[i] || + no_player_has_reveal_move) + { + struct rock_paper_scissors_throw_reveal reveal; + reveal.nonce2 = 0; + reveal.gesture = (rock_paper_scissors_gesture)db.get_random_bits(game_options.number_of_gestures); + rps_game_details.reveal_moves[i] = reveal; + ilog("Player ${player} failed to commit a move, generating a random move for him: ${gesture}", + ("player", i)("gesture", reveal.gesture)); + } + } } } } @@ -501,8 +514,11 @@ namespace graphene { namespace chain { ilog("Player 0 didn't commit or reveal their move, player 1 wins"); winners.insert(players[1]); } - else if (rps_game_details.reveal_moves[1]) + else // if (rps_game_details.reveal_moves[1]) + { + // should never reach this point ? ilog("Neither player made a move, both players lose"); + } } diff --git a/libraries/chain/match_object.cpp b/libraries/chain/match_object.cpp index 3ea3d250..235037f5 100644 --- a/libraries/chain/match_object.cpp +++ b/libraries/chain/match_object.cpp @@ -94,22 +94,40 @@ namespace graphene { namespace chain { "Match ${id} is complete", ("id", match.id)); + optional last_game_winner; std::map scores_by_player; for (const flat_set& game_winners : match.game_winners) for (const account_id_type& account_id : game_winners) + { ++scores_by_player[account_id]; + last_game_winner = account_id; + } + bool all_scores_same = true; optional high_scoring_account; unsigned high_score = 0; for (const auto& value : scores_by_player) if (value.second > high_score) { + if (high_scoring_account) + all_scores_same = false; high_score = value.second; high_scoring_account = value.first; } if (high_scoring_account) - match.match_winners.insert(*high_scoring_account); + { + if (all_scores_same && last_game_winner) + match.match_winners.insert(*last_game_winner); + else + match.match_winners.insert(*high_scoring_account); + } + else + { + unsigned i = event.db.get_random_bits(match.players.size()-1); + match.match_winners.insert(match.players[i]); + } + match.end_time = event.db.head_block_time(); const tournament_object& tournament_obj = match.tournament_id(event.db); @@ -137,11 +155,15 @@ namespace graphene { namespace chain { typedef match_state_machine_ x; // makes transition table cleaner - // Guards bool was_final_game(const game_complete& event) { const tournament_object& tournament_obj = match_obj->tournament_id(event.db); + if (match_obj->games.size() >= tournament_obj.options.number_of_wins * 4) + { + return true; + } + for (unsigned i = 0; i < match_obj->players.size(); ++i) { // this guard is called before the winner of the current game factored in to our running totals, diff --git a/libraries/chain/tournament_object.cpp b/libraries/chain/tournament_object.cpp index 28b7b756..fa8830ee 100644 --- a/libraries/chain/tournament_object.cpp +++ b/libraries/chain/tournament_object.cpp @@ -234,7 +234,7 @@ namespace graphene { namespace chain { event.db.modify(next_round_match, [&](match_object& next_match_obj) { - if (!event.match.match_winners.empty()) // if there is a winner + if (!event.match.match_winners.empty()) // if there is a winner { if (winner_index_in_next_match == 0) next_match_obj.players.insert(next_match_obj.players.begin(), *event.match.match_winners.begin()); @@ -359,14 +359,16 @@ namespace graphene { namespace chain { ("value", tournament_obj->registered_players == tournament_obj->options.number_of_players - 1)); return tournament_obj->registered_players == tournament_obj->options.number_of_players - 1; } - + bool was_final_match(const match_completed& event) { const tournament_details_object& tournament_details_obj = tournament_obj->tournament_details_id(event.db); + auto final_match_id = tournament_details_obj.matches[tournament_details_obj.matches.size() - 1]; + bool was_final = event.match.id == final_match_id; fc_ilog(fc::logger::get("tournament"), "In was_final_match guard, returning ${value}", - ("value", event.match.id == tournament_details_obj.matches[tournament_details_obj.matches.size()])); - return event.match.id == tournament_details_obj.matches[tournament_details_obj.matches.size() - 1]; + ("value", was_final)); + return was_final; } void register_player(const player_registered& event)