fxing #11 Fix operation of "insurance" parameter

implementing	#12 Add tournament rules to prevent a game from lasting too long due to ties
This commit is contained in:
Roman Olearski 2016-11-29 17:38:37 +01:00
parent b9508c6da8
commit e16b9d0610
3 changed files with 59 additions and 19 deletions

View file

@ -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<rock_paper_scissors_game_details>::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<rock_paper_scissors_game_options>();
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");
}
}

View file

@ -94,22 +94,40 @@ namespace graphene { namespace chain {
"Match ${id} is complete",
("id", match.id));
optional<account_id_type> last_game_winner;
std::map<account_id_type, unsigned> scores_by_player;
for (const flat_set<account_id_type>& 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<account_id_type> 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,

View file

@ -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)