File: ScoreUtil.h

package info (click to toggle)
pentobi 29.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,892 kB
  • sloc: cpp: 25,719; javascript: 875; xml: 40; makefile: 13; sh: 6
file content (73 lines) | stat: -rw-r--r-- 2,683 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//-----------------------------------------------------------------------------
/** @file libpentobi_base/ScoreUtil.h
    @author Markus Enzenberger
    @copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------

#ifndef LIBPENTOBI_BASE_SCORE_UTIL_H
#define LIBPENTOBI_BASE_SCORE_UTIL_H

#include <algorithm>
#include <array>
#include "Color.h"
#include "PieceInfo.h"

namespace libpentobi_base {

//-----------------------------------------------------------------------------

/** Convert the result of a multi-player game into a comparable number.
    This generalizes the game result of a two-player game (0,0.5,1 for
    loss/tie/win) for a game with n \> 2 players. The points are sorted in
    ascending order. Each rank r_i (i in 0..n-1) is assigned a value of
    r_i/(n-1). If multiple players have the same points, the result value is
    the average of all ranks with these points. So being the single winner
    still gives the result 1 and being the single loser the result 0. Being the
    single winner is better than sharing the best rank, which is better than
    getting the second rank, etc.
    @return The game result for each player. */
template<typename FLOAT>
void get_multiplayer_result(unsigned nu_players,
                            array<ScoreType, Color::range>& points,
                            array<FLOAT, Color::range>& result,
                            bool break_ties)
{
    array<ScoreType, Color::range> sorted;
    for (Color::IntType i = 0; i < nu_players; ++i)
    {
        if (break_ties)
            // Favor later player. The adjustment must be smaller than the
            // smallest difference in points (0.5 for GembloQ).
            points[i] +=  0.001f * i;
        sorted[i] = points[i];
    }
    // Disable false-positive GCC warning if compiled with -O2
    // (last tested with GCC 13.2.0)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
    sort(sorted.begin(), sorted.begin() + nu_players);
#pragma GCC diagnostic pop
    for (Color::IntType i = 0; i < nu_players; ++i)
    {
        FLOAT sum = 0;
        FLOAT n = 0;
        FLOAT float_j = 0;
        FLOAT factor = 1 / FLOAT(nu_players - 1);
        for (unsigned j = 0; j < nu_players; ++j)
        {
            if (sorted[j] == points[i])
            {
                sum += factor * float_j;
                ++n;
            }
            ++float_j;
        }
        result[i] = sum / n;
    }
}

//-----------------------------------------------------------------------------

} // namespace libpentobi_base

#endif // LIBPENTOBI_BASE_SCORE_UTIL_H