New Player Definitions Self Ranking Suggestion
#121
Posted 2006-March-03, 12:45
#122
Posted 2006-March-03, 13:54
No permission to use this code or the ideas embodied herein unless specifically granted by the author.
------------------------------------------------------------------------
The main function of interest is "ComputeReputations." Ratings are on a
scale of 0 to 10 and ratings weight maxes out after 20 boards but as you
can see this is a configurable parameter.
--------------------------------------------------------------------
#define MIN_RATING 0
#define MAX_RATING 10
#define MIN_BOARDS 1
#define MAX_BOARDS 20
using namespace std;
class Evaluation {
protected:
unsigned int m_num_boards;
unsigned int m_num_days_since_epoch;
unsigned int m_skill;
unsigned int m_niceness;
public:
Evaluation(void) {}
Evaluation(unsigned int num_boards,unsigned int days_since_epoch) :
m_num_boards(num_boards), m_num_days_since_epoch(days_since_epoch), m_sk
ill(UINT_MAX), m_niceness(UINT_MAX) {}
void AddBoards(unsigned int num_boards,unsigned int days_since_epoch) {
// prevent wrap-around
if(m_num_boards + num_boards > m_num_boards) m_num_boards += num_boards;
m_num_days_since_epoch = days_since_epoch;
}
void NewEvaluation(unsigned int skill,unsigned int niceness);
unsigned int get_num_boards(void) const { return m_num_boards; }
unsigned int get_days_since_epoch(void) const { return m_num_days_since_epoc
h; }
unsigned int get_skill(void) const { return m_skill; }
unsigned int get_niceness(void) const { return m_niceness; }
};
class Reputation {
protected:
map<string,Evaluation> m_evals;
double time_weight(unsigned int x) const;
public:
void AddBoards(const string &username,unsigned int num_boards,unsigned int d
ays_since_epoch);
// 0 = success
// 1 = parameter out of range
// 2 = no boards played
int NewEvaluation(const string &username,unsigned int skill,unsigned int nic
eness);
void ComputeReputations(unsigned int days_since_epoch,float &skill_reputatio
n,float &niceness_reputation) const;
};
void Reputation::AddBoards(const string &username,unsigned int num_boards,unsign
ed int days_since_epoch) {
map<string,Evaluation>::iterator eval_iter = m_evals.find(username);
if(eval_iter == m_evals.end()) {
m_evals.insert(pair<string,Evaluation>(username,Evaluation(num_boards,da
ys_since_epoch)));
} else {
eval_iter->second.AddBoards(num_boards,days_since_epoch);
}
}
void Evaluation::NewEvaluation(unsigned int skill,unsigned int niceness) {
m_skill = skill;
m_niceness = niceness;
}
int Reputation::NewEvaluation(const string &username,unsigned int skill,unsigned
int niceness) {
if(skill < MIN_RATING || skill > MAX_RATING || niceness < MIN_RATING || nice
ness > MAX_RATING) return 1;
map<string,Evaluation>::iterator eval_iter = m_evals.find(username);
if(eval_iter == m_evals.end()) {
return 2;
} else {
eval_iter->second.NewEvaluation(skill,niceness);
}
return 0;
}
// This is something else I haven't already mentioned.
// Ratings degrade in weight over time. If you played with someone
// a year ago then your rating counts less than someone who played
// with them 2 days ago. There is a lot of time for improvement over
// a year but not 2 days. The following piecewise formula is complex
// but basically it is relatively flat for up to 80 days and then drops
// pretty linearly for another 80 days and then has a relatively long
// flat tail.
double Reputation::time_weight(unsigned int x) const {
double val;
if(x<120) {
val = 1.5 - 0.5 * exp(x*x/20775.0);
}
else {
val = 0.5 * exp((x-120)/-173.0);
}
return val;
}
void Reputation::ComputeReputations(unsigned int days_since_epoch,float &skill_r
eputation,float &niceness_reputation) const {
map<string,Evaluation>::const_iterator eval_iter;
double sum_skill = 0.0;
double sum_niceness = 0.0;
double sum_weight = 0.0;
cout << "ComputeReputations" << endl;
for(eval_iter = m_evals.begin();
eval_iter != m_evals.end();
++eval_iter) {
unsigned int num_boards = eval_iter->second.get_num_boards();
num_boards = num_boards > MAX_BOARDS ? MAX_BOARDS : num_boards;
cout << "ComputeReputations " << num_boards << endl;
if(num_boards >= MIN_BOARDS) {
double weight = time_weight(days_since_epoch - eval_iter->second.get
_days_since_epoch()) * (num_boards / MAX_BOARDS);
sum_skill += weight * eval_iter->second.get_skill();
sum_niceness += weight * eval_iter->second.get_niceness();
sum_weight += weight;
}
}
if(sum_weight == 0.0) {
skill_reputation = -1.0;
niceness_reputation = -1.0;
} else {
skill_reputation = sum_skill / sum_weight;
niceness_reputation = sum_niceness / sum_weight;
}
}
#123
Posted 2006-March-03, 15:47
m_num_boards to the other style numBoards
I find it more readable. What is the m_ for, is that your cenvention for unsigned int?
// This is something else I haven't already mentioned.
// Ratings degrade in weight over time. If you played with someone
// a year ago then your rating counts less than someone who played
// with them 2 days ago. There is a lot of time for improvement over
// a year but not 2 days. The following piecewise formula is complex
// but basically it is relatively flat for up to 80 days and then drops
// pretty linearly for another 80 days and then has a relatively long
// flat tail.
I like this idea.
Lets add some more complexity!
If someone gives out lots of negative ratings, then their weighting should probably be reduced. That way on crab doesn't ding scores of others.
#124
Posted 2006-March-03, 15:54
Quote
Does this mean i can browse it with an eye towards implementing a variant in C if i like it and it isnt too hard ?
#125
Posted 2006-March-03, 16:49
To Uday, you can create a C version and tinker with the idea. My only request is that nothing go into active use unless I give additional permission.
The idea of lowering the weight of people's ratings who themselves are poorly rated is an appealing one but in my experience, such modifications can potentially lead to instability. I'd have to do some studies to find out what effect such a decreased weight would have.
#126
Posted 2006-March-04, 19:39
DrTodd13, on Mar 3 2006, 08:54 PM, said:
No permission to use this code or the ideas embodied herein unless specifically granted by the author.
No offense Todd, but I don't think it's legally possible to restrain anybody from using ideas you have published unless you have a patent on these ideas. Furthermore, software ideas are not patentable everywhere (e.g. not in Europe, fortunately).
--Sigi
#127
Posted 2006-March-07, 03:06
DrTodd13, on Mar 3 2006, 12:30 PM, said:
Hi Todd
I've been debating the skill part,or at least think I have,mostly
I don't play with pickup partners much,but to answer your question,
yes that's my efficient system
-----------------
I'm still trying to get my head around the skill system of yours.
Will a vote have less weight if the player voting has lower skill level?
#128
Posted 2006-March-13, 03:53
DrTodd13, on Mar 3 2006, 07:54 PM, said:
No permission to use this code or the ideas embodied herein unless specifically granted by the author.
------------------------------------------------------------------------
The main function of interest is "ComputeReputations." Ratings are on a
scale of 0 to 10 and ratings weight maxes out after 20 boards but as you
can see this is a configurable parameter.
--------------------------------------------------------------------
#define MIN_RATING 0
#define MAX_RATING 10
#define MIN_BOARDS 1
#define MAX_BOARDS 20
using namespace std;
class Evaluation {
protected:
unsigned int m_num_boards;
unsigned int m_num_days_since_epoch;
unsigned int m_skill;
unsigned int m_niceness;
public:
Evaluation(void) {}
Evaluation(unsigned int num_boards,unsigned int days_since_epoch) :
m_num_boards(num_boards), m_num_days_since_epoch(days_since_epoch), m_sk
ill(UINT_MAX), m_niceness(UINT_MAX) {}
void AddBoards(unsigned int num_boards,unsigned int days_since_epoch) {
// prevent wrap-around
if(m_num_boards + num_boards > m_num_boards) m_num_boards += num_boards;
m_num_days_since_epoch = days_since_epoch;
}
void NewEvaluation(unsigned int skill,unsigned int niceness);
unsigned int get_num_boards(void) const { return m_num_boards; }
unsigned int get_days_since_epoch(void) const { return m_num_days_since_epoc
h; }
unsigned int get_skill(void) const { return m_skill; }
unsigned int get_niceness(void) const { return m_niceness; }
};
class Reputation {
protected:
map<string,Evaluation> m_evals;
double time_weight(unsigned int x) const;
public:
void AddBoards(const string &username,unsigned int num_boards,unsigned int d
ays_since_epoch);
// 0 = success
// 1 = parameter out of range
// 2 = no boards played
int NewEvaluation(const string &username,unsigned int skill,unsigned int nic
eness);
void ComputeReputations(unsigned int days_since_epoch,float &skill_reputatio
n,float &niceness_reputation) const;
};
void Reputation::AddBoards(const string &username,unsigned int num_boards,unsign
ed int days_since_epoch) {
map<string,Evaluation>::iterator eval_iter = m_evals.find(username);
if(eval_iter == m_evals.end()) {
m_evals.insert(pair<string,Evaluation>(username,Evaluation(num_boards,da
ys_since_epoch)));
} else {
eval_iter->second.AddBoards(num_boards,days_since_epoch);
}
}
void Evaluation::NewEvaluation(unsigned int skill,unsigned int niceness) {
m_skill = skill;
m_niceness = niceness;
}
int Reputation::NewEvaluation(const string &username,unsigned int skill,unsigned
int niceness) {
if(skill < MIN_RATING || skill > MAX_RATING || niceness < MIN_RATING || nice
ness > MAX_RATING) return 1;
map<string,Evaluation>::iterator eval_iter = m_evals.find(username);
if(eval_iter == m_evals.end()) {
return 2;
} else {
eval_iter->second.NewEvaluation(skill,niceness);
}
return 0;
}
// This is something else I haven't already mentioned.
// Ratings degrade in weight over time. If you played with someone
// a year ago then your rating counts less than someone who played
// with them 2 days ago. There is a lot of time for improvement over
// a year but not 2 days. The following piecewise formula is complex
// but basically it is relatively flat for up to 80 days and then drops
// pretty linearly for another 80 days and then has a relatively long
// flat tail.
double Reputation::time_weight(unsigned int x) const {
double val;
if(x<120) {
val = 1.5 - 0.5 * exp(x*x/20775.0);
}
else {
val = 0.5 * exp((x-120)/-173.0);
}
return val;
}
void Reputation::ComputeReputations(unsigned int days_since_epoch,float &skill_r
eputation,float &niceness_reputation) const {
map<string,Evaluation>::const_iterator eval_iter;
double sum_skill = 0.0;
double sum_niceness = 0.0;
double sum_weight = 0.0;
cout << "ComputeReputations" << endl;
for(eval_iter = m_evals.begin();
eval_iter != m_evals.end();
++eval_iter) {
unsigned int num_boards = eval_iter->second.get_num_boards();
num_boards = num_boards > MAX_BOARDS ? MAX_BOARDS : num_boards;
cout << "ComputeReputations " << num_boards << endl;
if(num_boards >= MIN_BOARDS) {
double weight = time_weight(days_since_epoch - eval_iter->second.get
_days_since_epoch()) * (num_boards / MAX_BOARDS);
sum_skill += weight * eval_iter->second.get_skill();
sum_niceness += weight * eval_iter->second.get_niceness();
sum_weight += weight;
}
}
if(sum_weight == 0.0) {
skill_reputation = -1.0;
niceness_reputation = -1.0;
} else {
skill_reputation = sum_skill / sum_weight;
niceness_reputation = sum_niceness / sum_weight;
}
}
1. Use enums or const ints inside a namespace, not #defines.
2. Don't put using namespace std in a header file. (Although you've put all the implementation into the one file and I see no file-scope guards).
3. Member variables should be private, not protected. (As you don't have virtual destructors you're not going to derive from these classes anyway).
4. I hate K&R bracing style.
5. cout - is this a console app?
6. Ever heard of std::for_each ?
#129
Posted 2006-March-13, 09:08
EarlPurple, on Mar 13 2006, 10:53 AM, said:
Blasphemy. What do you use (please don't say GNU style)?
Quote
Yes.
--Sigi
#130
Posted 2006-March-13, 10:51
The only exception where I use K&R is opening a namespace, and that's because I generally don't indent either.
#131
Posted 2006-March-14, 21:29
#132
Posted 2006-March-16, 20:44
EarlPurple, on Mar 13 2006, 10:53 AM, said:
After wondering for a few days why you would want to use for_each() in this case, I can only say that I find no reason to do so. It would only make the code less readable and maintainable.
See also: http://www.awprofessional.com/articles/art...345948&seqNum=3
--Sigi
#133
Posted 2006-March-17, 00:57
#134
Posted 2006-April-04, 20:01
Some info here http://en.wikipedia....o_rating_system
There are more variables to consider but I would have thought some such system could be built particularly for an online environment where all the comparison data is readily available.
#135
Posted 2006-April-05, 09:50
Steve Picketts Bridgebrowser gives ratings for players on BBO also its just not public. It interesting when you see peoples ratings and from what i have seen they tend to be right on from what i have seen
#136
Posted 2006-April-10, 03:26
This happens with ELo in chess (I had been better, but bad luck, bla bla bla) and to the ok-bridge system. (I played too many pickup parts/late at night/with too good/too bad opponents, Too good/too bad parts..)
I liked the system, because it was- besides all flaws- better then anything else.
Roland
Sanity Check: Failure (Fluffy)
More system is not the answer...
#137
Posted 2006-April-12, 22:25
Obviously this is open to abuse, but I think most people would welcome the opportunity to enter something original and descriptive (and maybe amusing) for their skill level, rather than a pre-determined set of responses.
#138
Posted 2006-April-15, 06:39
Codo, on Apr 10 2006, 04:26 AM, said:
This happens with ELo in chess (I had been better, but bad luck, bla bla bla)
Beg to differ.There is no luck in chess.ELO rating gives an accurate description of an active players skill level.Moreover in chess if anyone claims he/she is better then all you have to do is to play a few games with each other.
In bridge even 100 deals will not prove anything if the lesser player doesn't keep an open mind.
Last but not the least the ' unit' to be examined in bridge should be a pair and not a player.Wonder if Meck or Well would have an expert performance if I am the partner.
Do unto others as you would have others do unto you.
"Mediocrity knows nothing higher than itself, but talent instantly recognizes genius".
#139
Posted 2006-April-15, 10:17
Those titles are awarded based on achieving a minimum result in several tournaments. The minimum result needed is calculated based on the strength of the opposition as determined by the ratings of the opponents.
#140
Posted 2006-April-15, 12:08
Compare this with rating in e.g. the NHL.
I wonder how many goals and assist points a goalie usually gets, i bet almost everybody in the defence and the offence has a better rating.

Help
