diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index ebd84db9..c1863e67 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -371,12 +371,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.payout_interval = 7*24*60*60; a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID; }); -// const asset_bitasset_data_object& bit_asset = -// create([&](asset_bitasset_data_object& a) { -// a.current_feed.maintenance_collateral_ratio = 1750; -// a.current_feed.maximum_short_squeeze_ratio = 1500; -// a.current_feed_publication_time = genesis_state.initial_timestamp + fc::hours(1); -// }); const asset_object& core_asset = create( [&]( asset_object& a ) { @@ -392,7 +386,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.core_exchange_rate.quote.asset_id = asset_id_type(0); a.dynamic_asset_data_id = dyn_asset.id; a.dividend_data_id = div_asset.id; -// a.bitasset_data_id = bit_asset.id; }); assert( asset_id_type(core_asset.id) == asset().asset_id ); assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) ); @@ -411,12 +404,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.payout_interval = 7*24*60*60; a.dividend_distribution_account = TOURNAMENT_RAKE_FEE_ACCOUNT_ID; }); - const asset_bitasset_data_object& bit_asset1 = - create([&](asset_bitasset_data_object& a) { - a.current_feed.maintenance_collateral_ratio = 1750; - a.current_feed.maximum_short_squeeze_ratio = 1500; - a.current_feed_publication_time = genesis_state.initial_timestamp + fc::hours(1); - }); const asset_object& default_asset = create( [&]( asset_object& a ) { @@ -433,7 +420,6 @@ void database::init_genesis(const genesis_state_type& genesis_state) a.options.core_exchange_rate.quote.asset_id = asset_id_type(1); a.dynamic_asset_data_id = dyn_asset1.id; a.dividend_data_id = div_asset1.id; - a.bitasset_data_id = bit_asset1.id; }); assert( default_asset.id == asset_id_type(1) ); #endif diff --git a/libraries/chain/game_object.cpp b/libraries/chain/game_object.cpp index 2bbcdd92..02612a77 100644 --- a/libraries/chain/game_object.cpp +++ b/libraries/chain/game_object.cpp @@ -106,7 +106,6 @@ namespace graphene { namespace chain { fc_ilog(fc::logger::get("tournament"), "game ${id} received a commit move, still expecting another commit move", ("id", game.id)); - set_next_timeout(event.db, game); } }; struct expecting_reveal_moves : public msm::front::state<> @@ -131,14 +130,16 @@ namespace graphene { namespace chain { game_object& game = *fsm.game_obj; if (event.move.move.which() == game_specific_moves::tag::value) + { fc_ilog(fc::logger::get("tournament"), "game ${id} received a commit move, now expecting reveal moves", ("id", game.id)); + set_next_timeout(event.db, game); + } else fc_ilog(fc::logger::get("tournament"), "game ${id} received a reveal move, still expecting reveal moves", ("id", game.id)); - set_next_timeout(event.db, game); } }; @@ -146,9 +147,9 @@ namespace graphene { namespace chain { { void clear_next_timeout(database& db, game_object& game) { - const match_object& match_obj = game.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(); + //const match_object& match_obj = game.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(); game.next_timeout = fc::optional(); } void on_entry(const timeout& event, game_state_machine_& fsm) @@ -200,7 +201,7 @@ namespace graphene { namespace chain { const rock_paper_scissors_game_details& game_details = game_obj->game_details.get(); for (unsigned i = 0; i < game_details.commit_moves.size(); ++i) - if (!game_details.reveal_moves[i] && i != this_reveal_index) + if (game_details.commit_moves[i] && !game_details.reveal_moves[i] && i != this_reveal_index) return false; return true; } @@ -350,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) { @@ -450,18 +451,22 @@ 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) { - 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)); - } + 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)); + } + } } } } @@ -500,8 +505,10 @@ 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 + { 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..4f762deb 100644 --- a/libraries/chain/match_object.cpp +++ b/libraries/chain/match_object.cpp @@ -94,22 +94,39 @@ 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 + { + match.match_winners.insert(match.players[event.db.get_random_bits(match.players.size())]); + } + match.end_time = event.db.head_block_time(); const tournament_object& tournament_obj = match.tournament_id(event.db); @@ -137,11 +154,16 @@ 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) + { + wdump((match_obj->games.size())); + 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 0ef5b364..fa8830ee 100644 --- a/libraries/chain/tournament_object.cpp +++ b/libraries/chain/tournament_object.cpp @@ -199,13 +199,6 @@ namespace graphene { namespace chain { } } -#ifdef HELPFULL_DUMP_WHEN_SOLVING_BYE_MATCH_PROBLEM - wlog("###"); - wdump((tournament_details_obj.matches[tournament_details_obj.matches.size() - 1])); - for( match_id_type mid : tournament_details_obj.matches ) - wdump((mid(event.db))); -#endif - } void on_entry(const match_completed& event, tournament_state_machine_& fsm) { @@ -241,13 +234,7 @@ namespace graphene { namespace chain { event.db.modify(next_round_match, [&](match_object& next_match_obj) { -#ifdef HELPFULL_DUMP_WHEN_SOLVING_BYE_MATCH_PROBLEM - wdump((event.match.get_state())); - wdump((event.match)); - wdump((other_match.get_state())); - wdump((other_match)); -#endif - 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()); @@ -257,10 +244,6 @@ namespace graphene { namespace chain { if (other_match.get_state() == match_state::match_complete) { -#ifdef HELPFULL_DUMP_WHEN_SOLVING_BYE_MATCH_PROBLEM - wdump((next_match_obj.get_state())); - wdump((next_match_obj)); -#endif next_match_obj.on_initiate_match(event.db); } @@ -376,21 +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()])); -#ifdef HELPFULL_DUMP_WHEN_SOLVING_BYE_MATCH_PROBLEM - wlog("###"); - wdump((event.match.id)); - wdump((tournament_details_obj.matches[tournament_details_obj.matches.size() - 1])); - for( match_id_type mid : tournament_details_obj.matches ) - wdump((mid(event.db))); -#endif - 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) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c1eced4e..c8de1558 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,10 +17,6 @@ file(GLOB PERFORMANCE_TESTS "performance/*.cpp") add_executable( performance_test ${PERFORMANCE_TESTS} ${COMMON_SOURCES} ) target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) -file(GLOB TOURNAMENT_TESTS "tournament/*.cpp") -add_executable( tournament_test ${TOURNAMENT_TESTS} ${COMMON_SOURCES} ) -target_link_libraries( tournament_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) - file(GLOB BENCH_MARKS "benchmarks/*.cpp") add_executable( chain_bench ${BENCH_MARKS} ${COMMON_SOURCES} ) target_link_libraries( chain_bench graphene_chain graphene_app graphene_account_history graphene_time graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) @@ -33,4 +29,12 @@ file(GLOB INTENSE_SOURCES "intense/*.cpp") add_executable( intense_test ${INTENSE_SOURCES} ${COMMON_SOURCES} ) target_link_libraries( intense_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) +file(GLOB TOURNAMENT_TESTS "tournament/*.cpp") +add_executable( tournament_test ${TOURNAMENT_TESTS} ${COMMON_SOURCES} ) +target_link_libraries( tournament_test graphene_chain graphene_app graphene_account_history graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) + +file(GLOB RANDOM_SOURCES "random/*.cpp") +add_executable( random_test ${RANDOM_SOURCES} ${COMMON_SOURCES} ) +target_link_libraries( random_test graphene_chain graphene_app graphene_egenesis_none fc ${PLATFORM_SPECIFIC_LIBS} ) + add_subdirectory( generate_empty_blocks ) diff --git a/tests/tournament/tournament_tests.cpp b/tests/tournament/tournament_tests.cpp index 63f17999..22da9a70 100644 --- a/tests/tournament/tournament_tests.cpp +++ b/tests/tournament/tournament_tests.cpp @@ -25,7 +25,6 @@ #include #include - #include #include #include @@ -289,13 +288,17 @@ public: tx.validate(); tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3)); df.sign(tx, sig_priv_key); - PUSH_TX(db, tx); + if (game_obj.get_state() == game_state::expecting_commit_moves) // checking again + PUSH_TX(db, tx); } // spaghetti programming // walking through all tournaments, matches and games and throwing random moves - void play_games() + // optionaly skip generting randomly selected moves + void play_games(unsigned skip_some_commits = 0, unsigned skip_some_reveals = 0) { + //try + //{ graphene::chain::database& db = df.db; const chain_parameters& params = db.get_global_properties().parameters; @@ -310,20 +313,25 @@ public: for(const auto& game_id: match.games ) { const game_object& game = game_id(db); + const rock_paper_scissors_game_details& rps_details = game.game_details.get(); if (game.get_state() == game_state::expecting_commit_moves) { for(const auto& player_id: game.players) { - if (players_keys.find(player_id) != players_keys.end()) + if ( players_keys.find(player_id) != players_keys.end()) { - rps_throw(game_id, player_id, (rock_paper_scissors_gesture) (std::rand() % game_options.number_of_gestures), players_keys[player_id]); + if (!skip_some_commits || player_id.instance.value % skip_some_commits != game_id.instance.value % skip_some_commits) + { + auto iter = std::find(game.players.begin(), game.players.end(), player_id); + unsigned player_index = std::distance(game.players.begin(), iter); + if (!rps_details.commit_moves.at(player_index)) + rps_throw(game_id, player_id, (rock_paper_scissors_gesture) (std::rand() % game_options.number_of_gestures), players_keys[player_id]); + } } } } else if (game.get_state() == game_state::expecting_reveal_moves) { - const rock_paper_scissors_game_details& rps_details = game.game_details.get(); - for (unsigned i = 0; i < 2; ++i) { if (rps_details.commit_moves.at(i) && @@ -333,27 +341,32 @@ public: if (players_keys.find(player_id) != players_keys.end()) { { + auto iter = committed_game_moves.find(*rps_details.commit_moves.at(i)); if (iter != committed_game_moves.end()) { - const rock_paper_scissors_throw_reveal& reveal = iter->second; - - game_move_operation move_operation; - move_operation.game_id = game.id; - move_operation.player_account_id = player_id; - move_operation.move = reveal; - - signed_transaction tx; - tx.operations = {move_operation}; - for( auto& op : tx.operations ) + if (!skip_some_reveals || player_id.instance.value % skip_some_reveals != game_id.instance.value % skip_some_reveals) { - asset f = db.current_fee_schedule().set_fee(op); - players_fees[player_id][f.asset_id] -= f.amount; + const rock_paper_scissors_throw_reveal& reveal = iter->second; + + game_move_operation move_operation; + move_operation.game_id = game.id; + move_operation.player_account_id = player_id; + move_operation.move = reveal; + + signed_transaction tx; + tx.operations = {move_operation}; + for( auto& op : tx.operations ) + { + asset f = db.current_fee_schedule().set_fee(op); + players_fees[player_id][f.asset_id] -= f.amount; + } + tx.validate(); + tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3)); + df.sign(tx, players_keys[player_id]); + if (game.get_state() == game_state::expecting_reveal_moves) // check again + PUSH_TX(db, tx); } - tx.validate(); - tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3)); - df.sign(tx, players_keys[player_id]); - PUSH_TX(db, tx); } } } @@ -363,6 +376,12 @@ public: } } } + //} + //catch (fc::exception& e) + //{ + // edump((e.to_detail_string())); + // throw; + //} } private: @@ -447,7 +466,7 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture ) asset buy_in = asset(12000); tournament_id_type tournament_id; - BOOST_TEST_MESSAGE( "Preparing a tournament" ); + BOOST_TEST_MESSAGE( "Preparing a tournament, insurance disabled" ); tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, TEST1_NR_OF_PLAYERS_NUMBER); BOOST_REQUIRE(tournament_id == tournament_id_type()); @@ -458,9 +477,10 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture ) #endif ++tournaments_to_complete; - BOOST_TEST_MESSAGE( "Preparing another one" ); + BOOST_TEST_MESSAGE( "Preparing another one, insurance enabled" ); buy_in = asset(13000); - tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, TEST2_NR_OF_PLAYERS_NUMBER); + tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, TEST2_NR_OF_PLAYERS_NUMBER, + 3, 1, 3, 3600, 3, 3, true); BOOST_REQUIRE(tournament_id == tournament_id_type(1)); tournament_helper.join_tournament(tournament_id, alice_id, alice_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("alice"))), buy_in); tournament_helper.join_tournament(tournament_id, bob_id, bob_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("bob"))), buy_in); @@ -745,7 +765,7 @@ BOOST_FIXTURE_TEST_CASE( assets, database_fixture ) while(tournaments_to_complete > 0) { generate_block(); - tournament_helper.play_games(); + tournament_helper.play_games(3, 4); for(const auto& tournament_id: tournaments) { const tournament_object& tournament = tournament_id(db);