Fix random choice of several equal votes in handleAllVotes
This commit is contained in:
parent
979077abab
commit
4ee7c51131
@ -4308,7 +4308,7 @@ bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string top_track = m_default_vote->m_track_name;
|
std::string top_track = m_default_vote->m_track_name;
|
||||||
int top_laps = m_default_vote->m_num_laps;
|
unsigned top_laps = m_default_vote->m_num_laps;
|
||||||
bool top_reverse = m_default_vote->m_reverse;
|
bool top_reverse = m_default_vote->m_reverse;
|
||||||
|
|
||||||
std::map<std::string, unsigned> tracks;
|
std::map<std::string, unsigned> tracks;
|
||||||
@ -4319,7 +4319,6 @@ bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
|
|||||||
float tracks_rate = 0.0f;
|
float tracks_rate = 0.0f;
|
||||||
float laps_rate = 0.0f;
|
float laps_rate = 0.0f;
|
||||||
float reverses_rate = 0.0f;
|
float reverses_rate = 0.0f;
|
||||||
RandomGenerator rg;
|
|
||||||
|
|
||||||
for (auto& p : m_peers_votes)
|
for (auto& p : m_peers_votes)
|
||||||
{
|
{
|
||||||
@ -4340,57 +4339,9 @@ bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
|
|||||||
reverse_vote->second++;
|
reverse_vote->second++;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned vote = 0;
|
findMajorityValue<std::string>(tracks, cur_players, &top_track, &tracks_rate);
|
||||||
auto track_vote = tracks.begin();
|
findMajorityValue<unsigned>(laps, cur_players, &top_laps, &laps_rate);
|
||||||
// rg.get(2) == 0 will allow not always the "less" in map get picked
|
findMajorityValue<bool>(reverses, cur_players, &top_reverse, &reverses_rate);
|
||||||
for (auto c_vote = tracks.begin(); c_vote != tracks.end(); c_vote++)
|
|
||||||
{
|
|
||||||
if (c_vote->second > vote ||
|
|
||||||
(c_vote->second >= vote && rg.get(2) == 0))
|
|
||||||
{
|
|
||||||
vote = c_vote->second;
|
|
||||||
track_vote = c_vote;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (track_vote != tracks.end())
|
|
||||||
{
|
|
||||||
top_track = track_vote->first;
|
|
||||||
tracks_rate = float(track_vote->second) / cur_players;
|
|
||||||
}
|
|
||||||
|
|
||||||
vote = 0;
|
|
||||||
auto lap_vote = laps.begin();
|
|
||||||
for (auto c_vote = laps.begin(); c_vote != laps.end(); c_vote++)
|
|
||||||
{
|
|
||||||
if (c_vote->second > vote ||
|
|
||||||
(c_vote->second >= vote && rg.get(2) == 0))
|
|
||||||
{
|
|
||||||
vote = c_vote->second;
|
|
||||||
lap_vote = c_vote;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lap_vote != laps.end())
|
|
||||||
{
|
|
||||||
top_laps = lap_vote->first;
|
|
||||||
laps_rate = float(lap_vote->second) / cur_players;
|
|
||||||
}
|
|
||||||
|
|
||||||
vote = 0;
|
|
||||||
auto reverse_vote = reverses.begin();
|
|
||||||
for (auto c_vote = reverses.begin(); c_vote != reverses.end(); c_vote++)
|
|
||||||
{
|
|
||||||
if (c_vote->second > vote ||
|
|
||||||
(c_vote->second >= vote && rg.get(2) == 0))
|
|
||||||
{
|
|
||||||
vote = c_vote->second;
|
|
||||||
reverse_vote = c_vote;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reverse_vote != reverses.end())
|
|
||||||
{
|
|
||||||
top_reverse = reverse_vote->first;
|
|
||||||
reverses_rate = float(reverse_vote->second) / cur_players;
|
|
||||||
}
|
|
||||||
|
|
||||||
// End early if there is majority agreement which is all entries rate > 0.5
|
// End early if there is majority agreement which is all entries rate > 0.5
|
||||||
it = m_peers_votes.begin();
|
it = m_peers_votes.begin();
|
||||||
@ -4424,10 +4375,10 @@ bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
|
|||||||
while (it != m_peers_votes.end())
|
while (it != m_peers_votes.end())
|
||||||
{
|
{
|
||||||
if (it->second.m_track_name == top_track &&
|
if (it->second.m_track_name == top_track &&
|
||||||
std::abs((int)it->second.m_num_laps - top_laps) < diff)
|
std::abs((int)it->second.m_num_laps - (int)top_laps) < diff)
|
||||||
{
|
{
|
||||||
closest_lap = it;
|
closest_lap = it;
|
||||||
diff = std::abs((int)it->second.m_num_laps - top_laps);
|
diff = std::abs((int)it->second.m_num_laps - (int)top_laps);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
@ -4439,6 +4390,42 @@ bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
|
|||||||
return false;
|
return false;
|
||||||
} // handleAllVotes
|
} // handleAllVotes
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template<typename T>
|
||||||
|
void ServerLobby::findMajorityValue(const std::map<T, unsigned>& choices, unsigned cur_players,
|
||||||
|
T* best_choice, float* rate)
|
||||||
|
{
|
||||||
|
RandomGenerator rg;
|
||||||
|
unsigned max_votes = 0;
|
||||||
|
auto best_iter = choices.begin();
|
||||||
|
unsigned best_iters_count = 1;
|
||||||
|
// Among choices with max votes, we need to pick one uniformly,
|
||||||
|
// thus we have to keep track of their number
|
||||||
|
for (auto iter = choices.begin(); iter != choices.end(); iter++)
|
||||||
|
{
|
||||||
|
if (iter->second > max_votes)
|
||||||
|
{
|
||||||
|
max_votes = iter->second;
|
||||||
|
best_iter = iter;
|
||||||
|
best_iters_count = 1;
|
||||||
|
}
|
||||||
|
else if (iter->second == max_votes)
|
||||||
|
{
|
||||||
|
best_iters_count++;
|
||||||
|
if (rg.get(best_iters_count) == 0)
|
||||||
|
{
|
||||||
|
max_votes = iter->second;
|
||||||
|
best_iter = iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_iter != choices.end())
|
||||||
|
{
|
||||||
|
*best_choice = best_iter->first;
|
||||||
|
*rate = float(best_iter->second) / cur_players;
|
||||||
|
}
|
||||||
|
} // findMajorityValue
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void ServerLobby::getHitCaptureLimit()
|
void ServerLobby::getHitCaptureLimit()
|
||||||
{
|
{
|
||||||
|
@ -330,6 +330,9 @@ private:
|
|||||||
const irr::core::stringw& online_name,
|
const irr::core::stringw& online_name,
|
||||||
const std::string& country_code);
|
const std::string& country_code);
|
||||||
bool handleAllVotes(PeerVote* winner, uint32_t* winner_peer_id);
|
bool handleAllVotes(PeerVote* winner, uint32_t* winner_peer_id);
|
||||||
|
template<typename T>
|
||||||
|
void findMajorityValue(const std::map<T, unsigned>& choices, unsigned cur_players,
|
||||||
|
T* best_choice, float* rate);
|
||||||
void getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p);
|
void getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p);
|
||||||
void submitRankingsToAddons();
|
void submitRankingsToAddons();
|
||||||
void computeNewRankings();
|
void computeNewRankings();
|
||||||
|
Loading…
Reference in New Issue
Block a user