Merge branch 'rock-paper-scissors' of http://syncad.storm.pl:56780/blocktrades/graphene into rock-paper-scissors
This commit is contained in:
commit
c60e88d054
19 changed files with 407 additions and 37 deletions
|
|
@ -218,6 +218,11 @@ struct get_impacted_account_visitor
|
||||||
_impacted.insert( op.payer_account_id );
|
_impacted.insert( op.payer_account_id );
|
||||||
_impacted.insert( op.player_account_id );
|
_impacted.insert( op.player_account_id );
|
||||||
}
|
}
|
||||||
|
void operator()( const tournament_leave_operation& op )
|
||||||
|
{
|
||||||
|
_impacted.erase( op.payer_account_id );
|
||||||
|
_impacted.erase( op.player_account_id );
|
||||||
|
}
|
||||||
void operator()( const game_move_operation& op )
|
void operator()( const game_move_operation& op )
|
||||||
{
|
{
|
||||||
_impacted.insert( op.player_account_id );
|
_impacted.insert( op.player_account_id );
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ void database::initialize_evaluators()
|
||||||
register_evaluator<tournament_create_evaluator>();
|
register_evaluator<tournament_create_evaluator>();
|
||||||
register_evaluator<tournament_join_evaluator>();
|
register_evaluator<tournament_join_evaluator>();
|
||||||
register_evaluator<game_move_evaluator>();
|
register_evaluator<game_move_evaluator>();
|
||||||
|
register_evaluator<tournament_leave_evaluator>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::initialize_indexes()
|
void database::initialize_indexes()
|
||||||
|
|
|
||||||
|
|
@ -186,3 +186,4 @@
|
||||||
#define TOURNAMENT_MINIMAL_RAKE_FEE_PERCENTAGE (1*GRAPHENE_1_PERCENT)
|
#define TOURNAMENT_MINIMAL_RAKE_FEE_PERCENTAGE (1*GRAPHENE_1_PERCENT)
|
||||||
#define TOURNAMENT_MAXIMAL_RAKE_FEE_PERCENTAGE (20*GRAPHENE_1_PERCENT)
|
#define TOURNAMENT_MAXIMAL_RAKE_FEE_PERCENTAGE (20*GRAPHENE_1_PERCENT)
|
||||||
#define TOURNAMENT_MAXIMAL_REGISTRATION_DEADLINE (60*60*24*30) // seconds, 30 days
|
#define TOURNAMENT_MAXIMAL_REGISTRATION_DEADLINE (60*60*24*30) // seconds, 30 days
|
||||||
|
#define TOURNAMENT_MAX_NUMBER_OF_WINS 100
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,8 @@ namespace graphene { namespace chain {
|
||||||
game_move_operation,
|
game_move_operation,
|
||||||
asset_update_dividend_operation,
|
asset_update_dividend_operation,
|
||||||
asset_dividend_distribution_operation, // VIRTUAL
|
asset_dividend_distribution_operation, // VIRTUAL
|
||||||
tournament_payout_operation // VIRTUAL
|
tournament_payout_operation, // VIRTUAL
|
||||||
|
tournament_leave_operation
|
||||||
> operation;
|
> operation;
|
||||||
|
|
||||||
/// @} // operations group
|
/// @} // operations group
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,30 @@ namespace graphene { namespace chain {
|
||||||
void validate()const;
|
void validate()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct tournament_leave_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type {
|
||||||
|
share_type fee = GRAPHENE_BLOCKCHAIN_PRECISION;
|
||||||
|
};
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
|
||||||
|
/// The account that is paying the fee
|
||||||
|
account_id_type payer_account_id;
|
||||||
|
|
||||||
|
/// The account that would play in the tournament, would receive any winnings.
|
||||||
|
account_id_type player_account_id;
|
||||||
|
|
||||||
|
/// The tournament `player_account_id` is leaving
|
||||||
|
tournament_id_type tournament_id;
|
||||||
|
|
||||||
|
extensions_type extensions;
|
||||||
|
account_id_type fee_payer()const { return payer_account_id; }
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const;
|
||||||
|
void validate()const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef fc::static_variant<rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal> game_specific_moves;
|
typedef fc::static_variant<rock_paper_scissors_throw_commit, rock_paper_scissors_throw_reveal> game_specific_moves;
|
||||||
|
|
||||||
struct game_move_operation : public base_operation
|
struct game_move_operation : public base_operation
|
||||||
|
|
@ -227,6 +251,12 @@ FC_REFLECT( graphene::chain::tournament_join_operation,
|
||||||
(tournament_id)
|
(tournament_id)
|
||||||
(buy_in)
|
(buy_in)
|
||||||
(extensions))
|
(extensions))
|
||||||
|
FC_REFLECT( graphene::chain::tournament_leave_operation,
|
||||||
|
(fee)
|
||||||
|
(payer_account_id)
|
||||||
|
(player_account_id)
|
||||||
|
(tournament_id)
|
||||||
|
(extensions))
|
||||||
FC_REFLECT( graphene::chain::game_move_operation,
|
FC_REFLECT( graphene::chain::game_move_operation,
|
||||||
(fee)
|
(fee)
|
||||||
(game_id)
|
(game_id)
|
||||||
|
|
@ -243,6 +273,7 @@ FC_REFLECT( graphene::chain::tournament_payout_operation,
|
||||||
|
|
||||||
FC_REFLECT( graphene::chain::tournament_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT( graphene::chain::tournament_create_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::tournament_join_operation::fee_parameters_type, (fee) )
|
FC_REFLECT( graphene::chain::tournament_join_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT( graphene::chain::tournament_leave_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::game_move_operation::fee_parameters_type, (fee) )
|
FC_REFLECT( graphene::chain::game_move_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT( graphene::chain::tournament_payout_operation::fee_parameters_type, )
|
FC_REFLECT( graphene::chain::tournament_payout_operation::fee_parameters_type, )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,18 @@ namespace graphene { namespace chain {
|
||||||
void_result do_apply( const tournament_join_operation& o );
|
void_result do_apply( const tournament_join_operation& o );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class tournament_leave_evaluator : public evaluator<tournament_leave_evaluator>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const tournament_object* _tournament_obj = nullptr;
|
||||||
|
const tournament_details_object* _tournament_details_obj = nullptr;
|
||||||
|
public:
|
||||||
|
typedef tournament_leave_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate( const tournament_leave_operation& o );
|
||||||
|
void_result do_apply( const tournament_leave_operation& o );
|
||||||
|
};
|
||||||
|
|
||||||
class game_move_evaluator : public evaluator<game_move_evaluator>
|
class game_move_evaluator : public evaluator<game_move_evaluator>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ namespace graphene { namespace chain {
|
||||||
/// List of payers who have contributed to the prize pool
|
/// List of payers who have contributed to the prize pool
|
||||||
flat_map<account_id_type, share_type> payers;
|
flat_map<account_id_type, share_type> payers;
|
||||||
|
|
||||||
|
/// List of player payer pairs needed by torunament leave operation
|
||||||
|
flat_map<account_id_type, account_id_type> players_payers;
|
||||||
|
|
||||||
/// List of all matches in this tournament. When the tournament starts, all matches
|
/// List of all matches in this tournament. When the tournament starts, all matches
|
||||||
/// are created. Matches in the first round will have players, matches in later
|
/// are created. Matches in the first round will have players, matches in later
|
||||||
/// rounds will not be populated.
|
/// rounds will not be populated.
|
||||||
|
|
@ -114,6 +117,7 @@ namespace graphene { namespace chain {
|
||||||
/// called by database maintenance code when registration for this contest has expired
|
/// called by database maintenance code when registration for this contest has expired
|
||||||
void on_registration_deadline_passed(database& db);
|
void on_registration_deadline_passed(database& db);
|
||||||
void on_player_registered(database& db, account_id_type payer_id, account_id_type player_id);
|
void on_player_registered(database& db, account_id_type payer_id, account_id_type player_id);
|
||||||
|
void on_player_unregistered(database& db, account_id_type payer_id, account_id_type player_id);
|
||||||
void on_start_time_arrived(database& db);
|
void on_start_time_arrived(database& db);
|
||||||
void on_match_completed(database& db, const match_object& match);
|
void on_match_completed(database& db, const match_object& match);
|
||||||
|
|
||||||
|
|
@ -232,6 +236,7 @@ FC_REFLECT_DERIVED(graphene::chain::tournament_details_object, (graphene::db::ob
|
||||||
(tournament_id)
|
(tournament_id)
|
||||||
(registered_players)
|
(registered_players)
|
||||||
(payers)
|
(payers)
|
||||||
|
(players_payers)
|
||||||
(matches))
|
(matches))
|
||||||
//FC_REFLECT_TYPENAME(graphene::chain::tournament_object) // manually serialized
|
//FC_REFLECT_TYPENAME(graphene::chain::tournament_object) // manually serialized
|
||||||
FC_REFLECT(graphene::chain::tournament_object, (creator))
|
FC_REFLECT(graphene::chain::tournament_object, (creator))
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ void_result limit_order_create_evaluator::do_evaluate(const limit_order_create_o
|
||||||
if( _sell_asset->options.blacklist_markets.size() )
|
if( _sell_asset->options.blacklist_markets.size() )
|
||||||
FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) == _sell_asset->options.blacklist_markets.end() );
|
FC_ASSERT( _sell_asset->options.blacklist_markets.find(_receive_asset->id) == _sell_asset->options.blacklist_markets.end() );
|
||||||
|
|
||||||
|
// $$$ I. DEX Task The Peerplays DEX should only allow UIA and sidechain assets to be paired (traded) with the core token (PPY)
|
||||||
|
FC_ASSERT(_receive_asset->id == asset_id_type() || _sell_asset->id == asset_id_type(),
|
||||||
|
"No asset in the trade is CORE.");
|
||||||
|
|
||||||
|
|
||||||
FC_ASSERT( is_authorized_asset( d, *_seller, *_sell_asset ) );
|
FC_ASSERT( is_authorized_asset( d, *_seller, *_sell_asset ) );
|
||||||
FC_ASSERT( is_authorized_asset( d, *_seller, *_receive_asset ) );
|
FC_ASSERT( is_authorized_asset( d, *_seller, *_receive_asset ) );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ namespace graphene { namespace chain {
|
||||||
void on_entry(const initiate_match& event, match_state_machine_& fsm)
|
void on_entry(const initiate_match& event, match_state_machine_& fsm)
|
||||||
{
|
{
|
||||||
match_object& match = *fsm.match_obj;
|
match_object& match = *fsm.match_obj;
|
||||||
|
|
||||||
fc_ilog(fc::logger::get("tournament"),
|
fc_ilog(fc::logger::get("tournament"),
|
||||||
"Match ${id} is now in progress",
|
"Match ${id} is now in progress",
|
||||||
("id", match.id));
|
("id", match.id));
|
||||||
|
|
@ -89,7 +88,9 @@ namespace graphene { namespace chain {
|
||||||
{
|
{
|
||||||
void on_entry(const game_complete& event, match_state_machine_& fsm)
|
void on_entry(const game_complete& event, match_state_machine_& fsm)
|
||||||
{
|
{
|
||||||
|
|
||||||
match_object& match = *fsm.match_obj;
|
match_object& match = *fsm.match_obj;
|
||||||
|
//wdump((match));
|
||||||
fc_ilog(fc::logger::get("tournament"),
|
fc_ilog(fc::logger::get("tournament"),
|
||||||
"Match ${id} is complete",
|
"Match ${id} is complete",
|
||||||
("id", match.id));
|
("id", match.id));
|
||||||
|
|
@ -124,16 +125,19 @@ namespace graphene { namespace chain {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
match.match_winners.insert(match.players[event.db.get_random_bits(match.players.size())]);
|
// III. Rock Paper Scissors Game Need to review how Ties are dealt with.
|
||||||
|
short i = match.number_of_ties == match.games.size() ? 0 : event.db.get_random_bits(match.players.size()) ;
|
||||||
|
match.match_winners.insert(match.players[i]);
|
||||||
|
++match.number_of_wins[i];
|
||||||
|
if (match.number_of_ties == match.games.size())
|
||||||
|
match.game_winners[match.game_winners.size()-1].insert(match.players[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
match.end_time = event.db.head_block_time();
|
match.end_time = event.db.head_block_time();
|
||||||
const tournament_object& tournament_obj = match.tournament_id(event.db);
|
const tournament_object& tournament_obj = match.tournament_id(event.db);
|
||||||
event.db.modify(tournament_obj, [&](tournament_object& tournament) {
|
event.db.modify(tournament_obj, [&](tournament_object& tournament) {
|
||||||
tournament.on_match_completed(event.db, match);
|
tournament.on_match_completed(event.db, match);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
void on_entry(const initiate_match& event, match_state_machine_& fsm)
|
void on_entry(const initiate_match& event, match_state_machine_& fsm)
|
||||||
{
|
{
|
||||||
|
|
@ -238,7 +242,8 @@ namespace graphene { namespace chain {
|
||||||
};
|
};
|
||||||
|
|
||||||
match_object::match_object() :
|
match_object::match_object() :
|
||||||
my(new impl(this))
|
number_of_ties(0),
|
||||||
|
my(new impl(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,17 @@ void tournament_join_operation::validate()const
|
||||||
FC_ASSERT( fee.amount >= 0 );
|
FC_ASSERT( fee.amount >= 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
share_type tournament_leave_operation::calculate_fee(const fee_parameters_type& k)const
|
||||||
|
{
|
||||||
|
return k.fee;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tournament_leave_operation::validate()const
|
||||||
|
{
|
||||||
|
// todo FC_ASSERT( fee.amount >= 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
share_type game_move_operation::calculate_fee(const fee_parameters_type& k)const
|
share_type game_move_operation::calculate_fee(const fee_parameters_type& k)const
|
||||||
{
|
{
|
||||||
return k.fee;
|
return k.fee;
|
||||||
|
|
@ -61,5 +72,4 @@ void game_move_operation::validate()const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ namespace graphene { namespace chain {
|
||||||
FC_THROW("Must specify either a fixed start time or a delay");
|
FC_THROW("Must specify either a fixed start time or a delay");
|
||||||
|
|
||||||
// TODO: make this committee-set
|
// TODO: make this committee-set
|
||||||
const uint32_t maximum_tournament_number_of_wins = 100;
|
const uint32_t maximum_tournament_number_of_wins = TOURNAMENT_MAX_NUMBER_OF_WINS;
|
||||||
FC_ASSERT(op.options.number_of_wins > 0);
|
FC_ASSERT(op.options.number_of_wins > 0);
|
||||||
FC_ASSERT(op.options.number_of_wins <= maximum_tournament_number_of_wins,
|
FC_ASSERT(op.options.number_of_wins <= maximum_tournament_number_of_wins,
|
||||||
"Matches may not require more than ${number_of_wins} wins",
|
"Matches may not require more than ${number_of_wins} wins",
|
||||||
|
|
@ -180,6 +180,36 @@ namespace graphene { namespace chain {
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
void_result tournament_leave_evaluator::do_evaluate( const tournament_leave_operation& op )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
const database& d = db();
|
||||||
|
_tournament_obj = &op.tournament_id(d);
|
||||||
|
fc_ilog(fc::logger::get("tournament"), "details_id = ${id}",("id", _tournament_obj->tournament_details_id));
|
||||||
|
|
||||||
|
_tournament_details_obj = &_tournament_obj->tournament_details_id(d);
|
||||||
|
FC_ASSERT(_tournament_details_obj->registered_players.find(op.player_account_id) != _tournament_details_obj->registered_players.end(),
|
||||||
|
"Player is not registered for this tournament");
|
||||||
|
//FC_ASSERT(_tournament_details_obj->payers.find(op.payer_account_id) != _tournament_details_obj->payers.end(),
|
||||||
|
// "Payer is not registered for this tournament");
|
||||||
|
|
||||||
|
FC_ASSERT(_tournament_obj->get_state() == tournament_state::accepting_registrations ||
|
||||||
|
_tournament_obj->get_state() == tournament_state::awaiting_start);
|
||||||
|
FC_ASSERT(d.head_block_time() <= _tournament_obj->options.registration_deadline,
|
||||||
|
"Registration deadline has already passed");
|
||||||
|
return void_result();
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
void_result tournament_leave_evaluator::do_apply( const tournament_leave_operation& op )
|
||||||
|
{ try {
|
||||||
|
#if 1
|
||||||
|
db().modify(*_tournament_obj, [&](tournament_object& tournament_obj){
|
||||||
|
tournament_obj.on_player_unregistered(db(), op.payer_account_id, op.player_account_id);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
return void_result();
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
void_result game_move_evaluator::do_evaluate( const game_move_operation& o )
|
void_result game_move_evaluator::do_evaluate( const game_move_operation& o )
|
||||||
{ try {
|
{ try {
|
||||||
const database& d = db();
|
const database& d = db();
|
||||||
|
|
@ -188,6 +218,7 @@ namespace graphene { namespace chain {
|
||||||
return void_result();
|
return void_result();
|
||||||
} FC_CAPTURE_AND_RETHROW( (o) ) }
|
} FC_CAPTURE_AND_RETHROW( (o) ) }
|
||||||
|
|
||||||
|
|
||||||
void_result game_move_evaluator::do_apply( const game_move_operation& o )
|
void_result game_move_evaluator::do_apply( const game_move_operation& o )
|
||||||
{ try {
|
{ try {
|
||||||
db().modify(*_game_obj, [&](game_object& game_obj){
|
db().modify(*_game_obj, [&](game_object& game_obj){
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,16 @@ namespace graphene { namespace chain {
|
||||||
db(db), payer_id(payer_id), player_id(player_id)
|
db(db), payer_id(payer_id), player_id(player_id)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
struct registration_deadline_passed
|
struct player_unregistered
|
||||||
|
{
|
||||||
|
database& db;
|
||||||
|
account_id_type payer_id;
|
||||||
|
account_id_type player_id;
|
||||||
|
player_unregistered(database& db, account_id_type payer_id, account_id_type player_id) :
|
||||||
|
db(db), payer_id(payer_id), player_id(player_id)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
struct registration_deadline_passed
|
||||||
{
|
{
|
||||||
database& db;
|
database& db;
|
||||||
registration_deadline_passed(database& db) : db(db) {};
|
registration_deadline_passed(database& db) : db(db) {};
|
||||||
|
|
@ -234,7 +243,7 @@ namespace graphene { namespace chain {
|
||||||
|
|
||||||
event.db.modify(next_round_match, [&](match_object& next_match_obj) {
|
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)
|
if (winner_index_in_next_match == 0)
|
||||||
next_match_obj.players.insert(next_match_obj.players.begin(), *event.match.match_winners.begin());
|
next_match_obj.players.insert(next_match_obj.players.begin(), *event.match.match_winners.begin());
|
||||||
|
|
@ -382,19 +391,42 @@ namespace graphene { namespace chain {
|
||||||
event.db.modify(tournament_details_obj, [&](tournament_details_object& tournament_details_obj){
|
event.db.modify(tournament_details_obj, [&](tournament_details_object& tournament_details_obj){
|
||||||
tournament_details_obj.payers[event.payer_id] += tournament_obj->options.buy_in.amount;
|
tournament_details_obj.payers[event.payer_id] += tournament_obj->options.buy_in.amount;
|
||||||
tournament_details_obj.registered_players.insert(event.player_id);
|
tournament_details_obj.registered_players.insert(event.player_id);
|
||||||
|
tournament_details_obj.players_payers[event.player_id] = event.payer_id;
|
||||||
});
|
});
|
||||||
++tournament_obj->registered_players;
|
++tournament_obj->registered_players;
|
||||||
tournament_obj->prize_pool += tournament_obj->options.buy_in.amount;
|
tournament_obj->prize_pool += tournament_obj->options.buy_in.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregister_player(const player_unregistered& event)
|
||||||
|
{
|
||||||
|
fc_ilog(fc::logger::get("tournament"),
|
||||||
|
"In unregister_player action, player_id is ${player_id}",
|
||||||
|
("player_id", event.player_id));
|
||||||
|
|
||||||
|
event.db.adjust_balance(event.payer_id, tournament_obj->options.buy_in);
|
||||||
|
const tournament_details_object& tournament_details_obj = tournament_obj->tournament_details_id(event.db);
|
||||||
|
event.db.modify(tournament_details_obj, [&](tournament_details_object& tournament_details_obj){
|
||||||
|
account_id_type payer_id = tournament_details_obj.players_payers[event.player_id];
|
||||||
|
tournament_details_obj.payers[payer_id] -= tournament_obj->options.buy_in.amount;
|
||||||
|
if (tournament_details_obj.payers[payer_id] <= 0)
|
||||||
|
tournament_details_obj.payers.erase(payer_id);
|
||||||
|
tournament_details_obj.registered_players.erase(event.player_id);
|
||||||
|
tournament_details_obj.players_payers.erase(event.player_id);
|
||||||
|
});
|
||||||
|
--tournament_obj->registered_players;
|
||||||
|
tournament_obj->prize_pool -= tournament_obj->options.buy_in.amount;
|
||||||
|
}
|
||||||
|
|
||||||
// Transition table for tournament
|
// Transition table for tournament
|
||||||
struct transition_table : mpl::vector<
|
struct transition_table : mpl::vector<
|
||||||
// Start Event Next Action Guard
|
// Start Event Next Action Guard
|
||||||
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
||||||
a_row < accepting_registrations, player_registered, accepting_registrations, &x::register_player >,
|
a_row < accepting_registrations, player_registered, accepting_registrations, &x::register_player >,
|
||||||
|
a_row < accepting_registrations, player_unregistered, accepting_registrations, &x::unregister_player >,
|
||||||
row < accepting_registrations, player_registered, awaiting_start, &x::register_player, &x::will_be_fully_registered >,
|
row < accepting_registrations, player_registered, awaiting_start, &x::register_player, &x::will_be_fully_registered >,
|
||||||
_row < accepting_registrations, registration_deadline_passed, registration_period_expired >,
|
_row < accepting_registrations, registration_deadline_passed, registration_period_expired >,
|
||||||
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
||||||
|
a_row < awaiting_start, player_unregistered, accepting_registrations, &x::unregister_player >,
|
||||||
_row < awaiting_start, start_time_arrived, in_progress >,
|
_row < awaiting_start, start_time_arrived, in_progress >,
|
||||||
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
// +---------------------------+-----------------------------+----------------------------+---------------------+----------------------+
|
||||||
_row < in_progress, match_completed, in_progress >,
|
_row < in_progress, match_completed, in_progress >,
|
||||||
|
|
@ -519,6 +551,11 @@ namespace graphene { namespace chain {
|
||||||
my->state_machine.process_event(player_registered(db, payer_id, player_id));
|
my->state_machine.process_event(player_registered(db, payer_id, player_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tournament_object::on_player_unregistered(database& db, account_id_type payer_id, account_id_type player_id)
|
||||||
|
{
|
||||||
|
my->state_machine.process_event(player_unregistered(db, payer_id, player_id));
|
||||||
|
}
|
||||||
|
|
||||||
void tournament_object::on_start_time_arrived(database& db)
|
void tournament_object::on_start_time_arrived(database& db)
|
||||||
{
|
{
|
||||||
my->state_machine.process_event(start_time_arrived(db));
|
my->state_machine.process_event(start_time_arrived(db));
|
||||||
|
|
|
||||||
|
|
@ -1490,13 +1490,25 @@ class wallet_api
|
||||||
signed_transaction tournament_create( string creator, tournament_options options, bool broadcast = false );
|
signed_transaction tournament_create( string creator, tournament_options options, bool broadcast = false );
|
||||||
|
|
||||||
/** Join an existing tournament
|
/** Join an existing tournament
|
||||||
* @param paying_account the account that is paying the buy-in and the fee to join the tournament
|
* @param payer_account the account that is paying the buy-in and the fee to join the tournament
|
||||||
* @param playing_account the account that will be playing in the tournament
|
* @param player_account the account that will be playing in the tournament
|
||||||
|
* @param buy_in_amount buy_in to pay
|
||||||
|
* @param buy_in_asset_symbol buy_in asset
|
||||||
* @param tournament_id the tournament the user wishes to join
|
* @param tournament_id the tournament the user wishes to join
|
||||||
|
* @param broadcast true if you wish to broadcast the transaction
|
||||||
* @return the signed version of the transaction
|
* @return the signed version of the transaction
|
||||||
*/
|
*/
|
||||||
signed_transaction tournament_join( string payer_account, string player_account, tournament_id_type tournament_id, string buy_in_amount, string buy_in_asset_symbol, bool broadcast = false );
|
signed_transaction tournament_join( string payer_account, string player_account, tournament_id_type tournament_id, string buy_in_amount, string buy_in_asset_symbol, bool broadcast = false );
|
||||||
|
|
||||||
|
/** Leave an existing tournament
|
||||||
|
* @param payer_account the account that is paying the fee
|
||||||
|
* @param player_account the account that would be playing in the tournament
|
||||||
|
* @param tournament_id the tournament the user wishes to leave
|
||||||
|
* @param broadcast true if you wish to broadcast the transaction
|
||||||
|
* @return the signed version of the transaction
|
||||||
|
*/
|
||||||
|
signed_transaction tournament_leave(string payer_account, string player_account, tournament_id_type tournament_id, bool broadcast = false);
|
||||||
|
|
||||||
/** Get a list of upcoming tournaments
|
/** Get a list of upcoming tournaments
|
||||||
* @param limit the number of tournaments to return
|
* @param limit the number of tournaments to return
|
||||||
*/
|
*/
|
||||||
|
|
@ -1730,6 +1742,7 @@ FC_API( graphene::wallet::wallet_api,
|
||||||
(receive_blind_transfer)
|
(receive_blind_transfer)
|
||||||
(tournament_create)
|
(tournament_create)
|
||||||
(tournament_join)
|
(tournament_join)
|
||||||
|
(tournament_leave)
|
||||||
(rps_throw)
|
(rps_throw)
|
||||||
(get_upcoming_tournaments)
|
(get_upcoming_tournaments)
|
||||||
(get_tournaments)
|
(get_tournaments)
|
||||||
|
|
|
||||||
|
|
@ -2521,14 +2521,28 @@ public:
|
||||||
tournament_object tournament = result.as<tournament_object>();
|
tournament_object tournament = result.as<tournament_object>();
|
||||||
tournament_details_object tournament_details = _remote_db->get_objects({result["tournament_details_id"].as<object_id_type>()})[0].as<tournament_details_object>();
|
tournament_details_object tournament_details = _remote_db->get_objects({result["tournament_details_id"].as<object_id_type>()})[0].as<tournament_details_object>();
|
||||||
tournament_state state = tournament.get_state();
|
tournament_state state = tournament.get_state();
|
||||||
if (state == tournament_state::awaiting_start)
|
if (state == tournament_state::accepting_registrations)
|
||||||
|
{
|
||||||
|
ss << "Tournament is accepting registrations\n";
|
||||||
|
ss << "Players " << tournament.registered_players << "/" << tournament.options.number_of_players << ":\n";
|
||||||
|
for (const account_id_type& player : tournament_details.registered_players)
|
||||||
|
ss << "\t" << get_account(player).name << "\n";
|
||||||
|
}
|
||||||
|
else if (state == tournament_state::registration_period_expired)
|
||||||
|
{
|
||||||
|
ss << "Tournament registration period expired\n";
|
||||||
|
ss << "Players " << tournament.registered_players << "/" << tournament.options.number_of_players << ":\n";
|
||||||
|
for (const account_id_type& player : tournament_details.registered_players)
|
||||||
|
ss << "\t" << get_account(player).name << "\n";
|
||||||
|
}
|
||||||
|
else if (state == tournament_state::awaiting_start)
|
||||||
{
|
{
|
||||||
ss << "Tournament starts at " << tournament.start_time->to_iso_string() << "\n";
|
ss << "Tournament starts at " << tournament.start_time->to_iso_string() << "\n";
|
||||||
ss << "Players:\n";
|
ss << "Players:\n";
|
||||||
for (const account_id_type& player : tournament_details.registered_players)
|
for (const account_id_type& player : tournament_details.registered_players)
|
||||||
ss << "\t" << get_account(player).name << "\n";
|
ss << "\t" << get_account(player).name << "\n";
|
||||||
}
|
}
|
||||||
else if (state == tournament_state::in_progress ||
|
else if (state == tournament_state::in_progress ||
|
||||||
state == tournament_state::concluded)
|
state == tournament_state::concluded)
|
||||||
{
|
{
|
||||||
unsigned num_matches = tournament_details.matches.size();
|
unsigned num_matches = tournament_details.matches.size();
|
||||||
|
|
@ -4834,7 +4848,7 @@ signed_transaction wallet_api::tournament_join( string payer_account,
|
||||||
FC_ASSERT( !is_locked() );
|
FC_ASSERT( !is_locked() );
|
||||||
account_object payer_account_obj = get_account(payer_account);
|
account_object payer_account_obj = get_account(payer_account);
|
||||||
account_object player_account_obj = get_account(player_account);
|
account_object player_account_obj = get_account(player_account);
|
||||||
graphene::chain::tournament_object tournament_obj = my->get_object<graphene::chain::tournament_object>(tournament_id);
|
//graphene::chain::tournament_object tournament_obj = my->get_object<graphene::chain::tournament_object>(tournament_id);
|
||||||
|
|
||||||
fc::optional<asset_object> buy_in_asset_obj = get_asset(buy_in_asset_symbol);
|
fc::optional<asset_object> buy_in_asset_obj = get_asset(buy_in_asset_symbol);
|
||||||
FC_ASSERT(buy_in_asset_obj, "Could not find asset matching ${asset}", ("asset", buy_in_asset_symbol));
|
FC_ASSERT(buy_in_asset_obj, "Could not find asset matching ${asset}", ("asset", buy_in_asset_symbol));
|
||||||
|
|
@ -4853,6 +4867,29 @@ signed_transaction wallet_api::tournament_join( string payer_account,
|
||||||
return my->sign_transaction( tx, broadcast );
|
return my->sign_transaction( tx, broadcast );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::tournament_leave( string payer_account,
|
||||||
|
string player_account,
|
||||||
|
tournament_id_type tournament_id,
|
||||||
|
bool broadcast)
|
||||||
|
{
|
||||||
|
FC_ASSERT( !is_locked() );
|
||||||
|
account_object player_account_obj = get_account(player_account);
|
||||||
|
account_object payer_account_obj = get_account(payer_account);
|
||||||
|
//graphene::chain::tournament_object tournament_obj = my->get_object<graphene::chain::tournament_object>(tournament_id);
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tournament_leave_operation op;
|
||||||
|
op.payer_account_id = payer_account_obj.get_id();
|
||||||
|
op.player_account_id = player_account_obj.get_id();
|
||||||
|
op.tournament_id = tournament_id;
|
||||||
|
|
||||||
|
tx.operations = {op};
|
||||||
|
my->set_operation_fees( tx, my->_remote_db->get_global_properties().parameters.current_fees );
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return my->sign_transaction( tx, broadcast );
|
||||||
|
}
|
||||||
|
|
||||||
vector<tournament_object> wallet_api::get_upcoming_tournaments(uint32_t limit)
|
vector<tournament_object> wallet_api::get_upcoming_tournaments(uint32_t limit)
|
||||||
{
|
{
|
||||||
return my->_remote_db->get_tournaments_in_state(tournament_state::accepting_registrations, limit);
|
return my->_remote_db->get_tournaments_in_state(tournament_state::accepting_registrations, limit);
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ int main(int argc, char** argv) {
|
||||||
auto witness_plug = node->register_plugin<witness_plugin::witness_plugin>();
|
auto witness_plug = node->register_plugin<witness_plugin::witness_plugin>();
|
||||||
auto history_plug = node->register_plugin<account_history::account_history_plugin>();
|
auto history_plug = node->register_plugin<account_history::account_history_plugin>();
|
||||||
auto market_history_plug = node->register_plugin<market_history::market_history_plugin>();
|
auto market_history_plug = node->register_plugin<market_history::market_history_plugin>();
|
||||||
auto generate_genesis_plug = node->register_plugin<generate_genesis_plugin::generate_genesis_plugin>();
|
//auto generate_genesis_plug = node->register_plugin<generate_genesis_plugin::generate_genesis_plugin>();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ database_fixture::database_fixture()
|
||||||
genesis_state.initial_timestamp = time_point_sec( GRAPHENE_TESTING_GENESIS_TIMESTAMP );
|
genesis_state.initial_timestamp = time_point_sec( GRAPHENE_TESTING_GENESIS_TIMESTAMP );
|
||||||
|
|
||||||
genesis_state.initial_active_witnesses = 10;
|
genesis_state.initial_active_witnesses = 10;
|
||||||
for( int i = 0; i < genesis_state.initial_active_witnesses; ++i )
|
for( unsigned i = 0; i < genesis_state.initial_active_witnesses; ++i )
|
||||||
{
|
{
|
||||||
auto name = "init"+fc::to_string(i);
|
auto name = "init"+fc::to_string(i);
|
||||||
genesis_state.initial_accounts.emplace_back(name,
|
genesis_state.initial_accounts.emplace_back(name,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
#!/bin/bash
|
#!/bin/bash -e
|
||||||
|
|
||||||
i=1
|
i=1
|
||||||
while [ 0 ]; do
|
while [ 0 ]; do
|
||||||
|
|
||||||
echo "*** $i `date`"
|
echo "*** $i `date`"
|
||||||
mv random-2 random-2-last
|
if [ -f random-2 ]; then
|
||||||
|
mv random-2 random-2-last
|
||||||
|
fi
|
||||||
./random_test --log_level=message 2> random-2
|
./random_test --log_level=message 2> random-2
|
||||||
echo "*** $i `date`"
|
echo "*** $i `date`"
|
||||||
echo
|
echo
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,34 @@ public:
|
||||||
|
|
||||||
players.insert(player_id);
|
players.insert(player_id);
|
||||||
players_keys[player_id] = sig_priv_key;
|
players_keys[player_id] = sig_priv_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void leave_tournament(const tournament_id_type & tournament_id,
|
||||||
|
const account_id_type& player_id,
|
||||||
|
const account_id_type& payer_id,
|
||||||
|
const fc::ecc::private_key& sig_priv_key
|
||||||
|
)
|
||||||
|
{
|
||||||
|
graphene::chain::database& db = df.db;
|
||||||
|
const chain_parameters& params = db.get_global_properties().parameters;
|
||||||
|
signed_transaction tx;
|
||||||
|
tournament_leave_operation op;
|
||||||
|
|
||||||
|
op.payer_account_id = payer_id;
|
||||||
|
op.player_account_id = player_id;
|
||||||
|
op.tournament_id = tournament_id;
|
||||||
|
tx.operations = {op};
|
||||||
|
for( auto& op : tx.operations )
|
||||||
|
db.current_fee_schedule().set_fee(op);
|
||||||
|
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);
|
||||||
|
|
||||||
|
//players.erase(player_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// stolen from cli_wallet
|
// stolen from cli_wallet
|
||||||
void rps_throw(const game_id_type& game_id,
|
void rps_throw(const game_id_type& game_id,
|
||||||
|
|
@ -288,14 +315,15 @@ public:
|
||||||
tx.validate();
|
tx.validate();
|
||||||
tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3));
|
tx.set_expiration(db.head_block_time() + fc::seconds( params.block_interval * (params.maintenance_skip_slots + 1) * 3));
|
||||||
df.sign(tx, sig_priv_key);
|
df.sign(tx, sig_priv_key);
|
||||||
if (game_obj.get_state() == game_state::expecting_commit_moves) // checking again
|
if (/*match_obj.match_winners.empty() &&*/ game_obj.get_state() == game_state::expecting_commit_moves) // checking again
|
||||||
PUSH_TX(db, tx);
|
PUSH_TX(db, tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// spaghetti programming
|
// spaghetti programming
|
||||||
// walking through all tournaments, matches and games and throwing random moves
|
// walking through all tournaments, matches and games and throwing random moves
|
||||||
// optionaly skip generting randomly selected moves
|
// optionaly skip generting randomly selected moves
|
||||||
void play_games(unsigned skip_some_commits = 0, unsigned skip_some_reveals = 0)
|
// every_move_is >= 0 : every game is tie
|
||||||
|
void play_games(unsigned skip_some_commits = 0, unsigned skip_some_reveals = 0, int every_move_is = -1)
|
||||||
{
|
{
|
||||||
//try
|
//try
|
||||||
//{
|
//{
|
||||||
|
|
@ -325,7 +353,8 @@ public:
|
||||||
auto iter = std::find(game.players.begin(), game.players.end(), player_id);
|
auto iter = std::find(game.players.begin(), game.players.end(), player_id);
|
||||||
unsigned player_index = std::distance(game.players.begin(), iter);
|
unsigned player_index = std::distance(game.players.begin(), iter);
|
||||||
if (!rps_details.commit_moves.at(player_index))
|
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]);
|
rps_throw(game_id, player_id,
|
||||||
|
(rock_paper_scissors_gesture) (every_move_is >= 0 ? every_move_is : (std::rand() % game_options.number_of_gestures)), players_keys[player_id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -414,6 +443,7 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 1
|
||||||
// Test of basic functionality creating two tournamenst, joinig players,
|
// Test of basic functionality creating two tournamenst, joinig players,
|
||||||
// playing tournaments to completion, distributing prize.
|
// playing tournaments to completion, distributing prize.
|
||||||
// Testing of "bye" matches handling can be performed if "bye" matches fix is available.
|
// Testing of "bye" matches handling can be performed if "bye" matches fix is available.
|
||||||
|
|
@ -431,13 +461,14 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
|
||||||
#define TEST2_NR_OF_PLAYERS_NUMBER 4
|
#define TEST2_NR_OF_PLAYERS_NUMBER 4
|
||||||
#endif
|
#endif
|
||||||
BOOST_TEST_MESSAGE("Hello simple tournament test");
|
BOOST_TEST_MESSAGE("Hello simple tournament test");
|
||||||
ACTORS((nathan)(alice)(bob)(carol)(dave)(ed)(frank)(george)(harry)(ike));
|
ACTORS((nathan)(alice)(bob)(carol)(dave)(ed)(frank)(george)(harry)(ike)(romek));
|
||||||
|
|
||||||
tournaments_helper tournament_helper(*this);
|
tournaments_helper tournament_helper(*this);
|
||||||
fc::ecc::private_key nathan_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
|
fc::ecc::private_key nathan_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
|
||||||
|
|
||||||
BOOST_TEST_MESSAGE( "Giving folks some money" );
|
BOOST_TEST_MESSAGE( "Giving folks some money" );
|
||||||
transfer(committee_account, nathan_id, asset(1000000000));
|
transfer(committee_account, nathan_id, asset(1000000000));
|
||||||
|
transfer(committee_account, romek_id, asset(2000000));
|
||||||
transfer(committee_account, alice_id, asset(2000000));
|
transfer(committee_account, alice_id, asset(2000000));
|
||||||
transfer(committee_account, bob_id, asset(3000000));
|
transfer(committee_account, bob_id, asset(3000000));
|
||||||
transfer(committee_account, carol_id, asset(4000000));
|
transfer(committee_account, carol_id, asset(4000000));
|
||||||
|
|
@ -483,8 +514,13 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
|
||||||
3, 1, 3, 3600, 3, 3, true);
|
3, 1, 3, 3600, 3, 3, true);
|
||||||
BOOST_REQUIRE(tournament_id == tournament_id_type(1));
|
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, alice_id, alice_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("alice"))), buy_in);
|
||||||
|
// romek joins but will leave
|
||||||
|
//tournament_helper.leave_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))));
|
||||||
|
tournament_helper.join_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))), buy_in);
|
||||||
tournament_helper.join_tournament(tournament_id, bob_id, bob_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("bob"))), buy_in);
|
tournament_helper.join_tournament(tournament_id, bob_id, bob_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("bob"))), buy_in);
|
||||||
tournament_helper.join_tournament(tournament_id, carol_id, carol_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("carol"))), buy_in);
|
tournament_helper.join_tournament(tournament_id, carol_id, carol_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("carol"))), buy_in);
|
||||||
|
// romek leaves
|
||||||
|
tournament_helper.leave_tournament(tournament_id, romek_id, romek_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("romek"))));
|
||||||
tournament_helper.join_tournament(tournament_id, dave_id, dave_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("dave"))), buy_in);
|
tournament_helper.join_tournament(tournament_id, dave_id, dave_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("dave"))), buy_in);
|
||||||
#if TEST2_NR_OF_PLAYERS_NUMBER > 4
|
#if TEST2_NR_OF_PLAYERS_NUMBER > 4
|
||||||
tournament_helper.join_tournament(tournament_id, ed_id, ed_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("ed"))), buy_in);
|
tournament_helper.join_tournament(tournament_id, ed_id, ed_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("ed"))), buy_in);
|
||||||
|
|
@ -532,12 +568,7 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
// trying to randomize automatic moves ?
|
|
||||||
auto n = std::rand() % 100;
|
|
||||||
for(int i = 0; i < n ; ++i)
|
|
||||||
db.get_random_bits(3);
|
|
||||||
#endif
|
|
||||||
abc("@ tournament awaiting start");
|
abc("@ tournament awaiting start");
|
||||||
BOOST_TEST_MESSAGE( "Generating blocks, waiting for tournaments' completion");
|
BOOST_TEST_MESSAGE( "Generating blocks, waiting for tournaments' completion");
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
@ -594,6 +625,122 @@ BOOST_FIXTURE_TEST_CASE( simple, database_fixture )
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// Test of handling ties, creating two tournamenst, joinig players,
|
||||||
|
// All generated moves are identical.
|
||||||
|
BOOST_FIXTURE_TEST_CASE( ties, database_fixture )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
#ifdef BYE_MATCHES_FIXED
|
||||||
|
#define TEST1_NR_OF_PLAYERS_NUMBER 3
|
||||||
|
#define TEST2_NR_OF_PLAYERS_NUMBER 5
|
||||||
|
#else
|
||||||
|
#define TEST1_NR_OF_PLAYERS_NUMBER 2
|
||||||
|
#define TEST2_NR_OF_PLAYERS_NUMBER 4
|
||||||
|
#endif
|
||||||
|
BOOST_TEST_MESSAGE("Hello ties tournament test");
|
||||||
|
ACTORS((nathan)(alice)(bob)(carol)(dave)(ed)(frank)(george)(harry)(ike));
|
||||||
|
|
||||||
|
tournaments_helper tournament_helper(*this);
|
||||||
|
fc::ecc::private_key nathan_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "Giving folks some money" );
|
||||||
|
transfer(committee_account, nathan_id, asset(1000000000));
|
||||||
|
transfer(committee_account, alice_id, asset(2000000));
|
||||||
|
transfer(committee_account, bob_id, asset(3000000));
|
||||||
|
transfer(committee_account, carol_id, asset(4000000));
|
||||||
|
transfer(committee_account, dave_id, asset(5000000));
|
||||||
|
transfer(committee_account, ed_id, asset(6000000));
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "Preparing nathan" );
|
||||||
|
upgrade_to_lifetime_member(nathan);
|
||||||
|
BOOST_CHECK(nathan.is_lifetime_member());
|
||||||
|
|
||||||
|
uint16_t tournaments_to_complete = 0;
|
||||||
|
asset buy_in = asset(12000);
|
||||||
|
tournament_id_type tournament_id;
|
||||||
|
|
||||||
|
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, 30, 30);
|
||||||
|
BOOST_REQUIRE(tournament_id == tournament_id_type());
|
||||||
|
|
||||||
|
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);
|
||||||
|
#if TEST1_NR_OF_PLAYERS_NUMBER > 2
|
||||||
|
tournament_helper.join_tournament(tournament_id, carol_id, carol_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("carol"))), buy_in);
|
||||||
|
#endif
|
||||||
|
++tournaments_to_complete;
|
||||||
|
|
||||||
|
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,
|
||||||
|
30, 30, 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);
|
||||||
|
tournament_helper.join_tournament(tournament_id, carol_id, carol_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("carol"))), buy_in);
|
||||||
|
tournament_helper.join_tournament(tournament_id, dave_id, dave_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("dave"))), buy_in);
|
||||||
|
#if TEST2_NR_OF_PLAYERS_NUMBER > 4
|
||||||
|
tournament_helper.join_tournament(tournament_id, ed_id, ed_id, fc::ecc::private_key::regenerate(fc::sha256::hash(string("ed"))), buy_in);
|
||||||
|
#endif
|
||||||
|
++tournaments_to_complete;
|
||||||
|
|
||||||
|
|
||||||
|
std::set<tournament_id_type> tournaments = tournament_helper.list_tournaments();
|
||||||
|
std::map<account_id_type, std::map<asset_id_type, share_type>> players_balances = tournament_helper.list_players_balances();
|
||||||
|
uint16_t rake_fee_percentage = db.get_global_properties().parameters.rake_fee_percentage;
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE( "Generating blocks, waiting for tournaments' completion");
|
||||||
|
while(tournaments_to_complete > 0)
|
||||||
|
{
|
||||||
|
generate_block();
|
||||||
|
//tournament_helper.play_games(3, 4, 1);
|
||||||
|
tournament_helper.play_games(0, 0, 1);
|
||||||
|
for(const auto& tournament_id: tournaments)
|
||||||
|
{
|
||||||
|
const tournament_object& tournament = tournament_id(db);
|
||||||
|
if (tournament.get_state() == tournament_state::concluded) {
|
||||||
|
const tournament_details_object& tournament_details = tournament.tournament_details_id(db);
|
||||||
|
const match_object& final_match = (tournament_details.matches[tournament_details.matches.size() - 1])(db);
|
||||||
|
|
||||||
|
assert(final_match.match_winners.size() == 1);
|
||||||
|
const account_id_type& winner_id = *final_match.match_winners.begin();
|
||||||
|
BOOST_TEST_MESSAGE( "The winner of " + std::string(object_id_type(tournament_id)) + " is " + winner_id(db).name + " " + std::string(object_id_type(winner_id)));
|
||||||
|
share_type rake_amount = (fc::uint128_t(tournament.prize_pool.value) * rake_fee_percentage / GRAPHENE_1_PERCENT / 100).to_uint64();
|
||||||
|
optional<account_id_type> dividend_account = tournament_helper.get_asset_dividend_account(tournament.options.buy_in.asset_id);
|
||||||
|
if (dividend_account.valid())
|
||||||
|
players_balances[*dividend_account][tournament.options.buy_in.asset_id] += rake_amount; players_balances[winner_id][tournament.options.buy_in.asset_id] += tournament.prize_pool - rake_amount;
|
||||||
|
|
||||||
|
tournaments.erase(tournament_id);
|
||||||
|
--tournaments_to_complete;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking if prizes were distributed correctly
|
||||||
|
BOOST_CHECK(tournaments.size() == 0);
|
||||||
|
std::map<account_id_type, std::map<asset_id_type, share_type>> last_players_balances = tournament_helper.list_players_balances();
|
||||||
|
for (auto a: last_players_balances)
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE( "Checking " + a.first(db).name + "'s balance " + std::to_string((uint64_t)(a.second[asset_id_type()].value)) );
|
||||||
|
BOOST_CHECK(a.second[asset_id_type()] == players_balances[a.first][asset_id_type()]);
|
||||||
|
}
|
||||||
|
BOOST_TEST_MESSAGE("Bye ties tournament test\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (fc::exception& e)
|
||||||
|
{
|
||||||
|
edump((e.to_detail_string()));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test of canceled tournament
|
// Test of canceled tournament
|
||||||
// Checking buyin refund.
|
// Checking buyin refund.
|
||||||
|
|
@ -957,8 +1104,8 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#define MIN_TOURNAMENTS_NUMBER 1
|
#define MIN_TOURNAMENTS_NUMBER 7
|
||||||
#define MAX_TOURNAMENTS_NUMBER 10
|
#define MAX_TOURNAMENTS_NUMBER 13
|
||||||
|
|
||||||
#define MIN_PLAYERS_NUMBER 2
|
#define MIN_PLAYERS_NUMBER 2
|
||||||
#define MAX_PLAYERS_NUMBER 64
|
#define MAX_PLAYERS_NUMBER 64
|
||||||
|
|
@ -976,7 +1123,7 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
|
||||||
|
|
||||||
// creating a pool of actors
|
// creating a pool of actors
|
||||||
std::vector<std::tuple<std::string, account_id_type, fc::ecc::private_key>> actors;
|
std::vector<std::tuple<std::string, account_id_type, fc::ecc::private_key>> actors;
|
||||||
for(unsigned i = 0; i < 2 * MAX_PLAYERS_NUMBER; ++i)
|
for(unsigned i = 0; i < 3 * MAX_PLAYERS_NUMBER; ++i)
|
||||||
{
|
{
|
||||||
std::string name = "account" + std::to_string(i);
|
std::string name = "account" + std::to_string(i);
|
||||||
auto priv_key = generate_private_key(name);
|
auto priv_key = generate_private_key(name);
|
||||||
|
|
@ -997,14 +1144,34 @@ BOOST_FIXTURE_TEST_CASE( massive, database_fixture )
|
||||||
asset buy_in = asset(1000 * number_of_players + 100 * i);
|
asset buy_in = asset(1000 * number_of_players + 100 * i);
|
||||||
tournament_id_type tournament_id;
|
tournament_id_type tournament_id;
|
||||||
tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, number_of_players, 30, 30, number_of_wins);
|
tournament_id = tournament_helper.create_tournament (nathan_id, nathan_priv_key, buy_in, number_of_players, 30, 30, number_of_wins);
|
||||||
|
const tournament_object& tournament = tournament_id(db);
|
||||||
|
|
||||||
for (unsigned j = 0; j < actors.size() && number_of_players > 0; ++j)
|
for (unsigned j = 0; j < actors.size()-1 && number_of_players > 0; ++j)
|
||||||
{
|
{
|
||||||
if (number_of_players < actors.size() - j && std::rand() % 2 == 0) continue;
|
if (number_of_players < actors.size() - j && std::rand() % 2 == 0) continue;
|
||||||
auto a = actors[j];
|
auto a = actors[j];
|
||||||
--number_of_players;
|
|
||||||
tournament_helper.join_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a), buy_in);
|
tournament_helper.join_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a), buy_in);
|
||||||
|
if (j == i)
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is leaving tournament " + std::to_string(i) +
|
||||||
|
", when tournament state is " + std::to_string((int)tournament.get_state()));
|
||||||
|
tournament_helper.leave_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
--number_of_players;
|
||||||
|
if (!number_of_players)
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is leaving tournament " + std::to_string(i) +
|
||||||
|
", when tournament state is " + std::to_string((int)tournament.get_state()));
|
||||||
|
tournament_helper.leave_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a));
|
||||||
|
++j;
|
||||||
|
a = actors[j];
|
||||||
|
BOOST_TEST_MESSAGE("Player " + std::get<0>(a) + " is joinig tournament " + std::to_string(i) +
|
||||||
|
", when tournament state is " + std::to_string((int)tournament.get_state()));
|
||||||
|
tournament_helper.join_tournament(tournament_id, std::get<1>(a), std::get<1>(a), std::get<2>(a), buy_in);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
BOOST_TEST_MESSAGE("Tournament " + std::to_string(i) + " is in state " + std::to_string((int)tournament.get_state()));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t tournaments_to_complete = number_of_tournaments;
|
uint16_t tournaments_to_complete = number_of_tournaments;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
i=1
|
i=1
|
||||||
|
file='tournament-2'
|
||||||
|
file2=$file
|
||||||
while [ 0 ]; do
|
while [ 0 ]; do
|
||||||
|
|
||||||
echo "*** $i `date`"
|
echo "*** $i `date`"
|
||||||
mv tournament-2 tournament-2-last
|
if [ "$1" = "-c" ]; then
|
||||||
./tournament_test --log_level=message 2> tournament-2
|
file2=$file-`date +%Y-%m-%d:%H:%M:%S`
|
||||||
|
|
||||||
|
elif [ -f $file2 ]; then
|
||||||
|
mv $file2 $file2-last
|
||||||
|
fi
|
||||||
|
./tournament_test --log_level=message 2> $file2
|
||||||
echo
|
echo
|
||||||
if [ "$1" = "-c" ]; then
|
if [ "$1" = "-c" ]; then
|
||||||
sleep 2
|
sleep 2
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue