Difference between revisions of "User:Nfwu/ELO Sim"
Jump to navigation
Jump to search
m (New page: Used RR@H server code as reference. No licence - use and abuse. Running the code as-is outputs ratings of bots A, B and C for this scenario:<br> A vs B = 25/75<br> A vs C = 75/25<br> B vs...) |
m (Nav + Category) |
||
Line 1: | Line 1: | ||
+ | {{User:Nfwu/Nav}} | ||
+ | |||
Used RR@H server code as reference. No licence - use and abuse. | Used RR@H server code as reference. No licence - use and abuse. | ||
Line 166: | Line 168: | ||
} | } | ||
</pre> | </pre> | ||
+ | |||
+ | [[Category:Source Code]] |
Revision as of 09:28, 6 September 2008
Used RR@H server code as reference. No licence - use and abuse.
Running the code as-is outputs ratings of bots A, B and C for this scenario:
A vs B = 25/75
A vs C = 75/25
B vs C = 25/75
Code:
package roborumble; import java.util.*; // There are faster ways of doing this, // but I wanted to replicate the RR@H server as close as possible. // // So, here's an inefficent ELO simulator. class EnemyStat { double wins; int benemy; //Looks like "Number of Battles agains this enemy" } class RobotStats { RobotStats(String n){ this(n, 1600); } RobotStats(String n, double r){ scoremap = new HashMap<String, EnemyStat>(); post = false; name = n; battles = 0; rating = r; } String name; int battles; double rating; boolean post; HashMap<String, EnemyStat> scoremap; } public class Test { private static final double min_score = 0.0; private static final double max_score = 1.0; private static final double rating_change = 3.0; static RobotStats[] stats; public static void main(String[] args){ //stats = new RobotStats[4]; stats = new RobotStats[3]; stats[0] = new RobotStats("BotA 1.0"); stats[1] = new RobotStats("BotB 1.0"); stats[2] = new RobotStats("BotC 1.0"); //POST EXPERIMENT //stats[3] = new RobotStats("Post", 2000); //stats[3].post = true; //A/B=25/75, A/C=75/25, BC=25/75 int rand; for (int i=0;i<1000;i++){ rand = (int)(Math.random() * 6.0); if (rand == 1){ //battleResults(0, 24.5+Math.random(), 1, 74.5+Math.random()); battleResults(0, 25, 1, 75); } else if (rand == 2){ //battleResults(1, 74.5+Math.random(), 0, 24.5+Math.random()); battleResults(1, 75, 0, 25); } else if (rand == 3){ //battleResults(0, 74.5+Math.random(), 2, 24.5+Math.random()); battleResults(0, 75, 2, 25); } else if (rand == 4){ //battleResults(2, 24.5+Math.random(), 0, 74.5+Math.random()); battleResults(2, 25, 0, 75); } else if (rand == 5){ //battleResults(1, 49.5+Math.random(), 2, 49.5+Math.random()); battleResults(1, 25, 2, 75); } else { //battleResults(2, 49.5+Math.random(), 1, 49.5+Math.random()); battleResults(2, 75, 1, 25); } //battleResults((int)(Math.random()*3), 50, 3, 50); //FROM POST EXPERIMENT } for (int i=0;i<stats.length;i++){ System.out.println(stats[i].name+" - Battles "+stats[i].battles+" - Rating "+stats[i].rating); } } static void battleResults(int fid, double fscore, int sid, double sscore){ //Get stuff for first double real1 = fscore / (fscore + sscore); if (real1 == 1.0 || real1 == 0.0) return; //RR@H server does this EnemyStat es1 = null; es1 = stats[fid].scoremap.get(stats[sid].name); //First's enemy data of second double wins1 = real1; if (es1 != null) wins1 = es1.wins; int benemy1 = 0; if (es1 != null) benemy1 = es1.benemy; //Get stuff for second double real2 = 1.0 - real1; EnemyStat es2 = null; es2 = stats[sid].scoremap.get(stats[sid].name); //Second's enemy data of first double wins2 = real1; if (es2 != null) wins2 = es2.wins; int benemy2 = 0; if (es2 != null) benemy2 = es2.benemy; //Calculate EnemyStat differences wins1 = 0.7 * wins1 + 0.3 * real1; wins2 = 0.7 * wins2 + 0.3 * real2; benemy1++; benemy2++; //Store the EnemyStats away if (es1 == null) { es1 = new EnemyStat(); } es1.wins = wins1; es1.benemy = benemy1; stats[fid].scoremap.put(stats[sid].name, es1); //First's enemy data of second if (es2 == null) { es2 = new EnemyStat(); } es2.wins = wins2; es2.benemy = benemy2; stats[sid].scoremap.put(stats[fid].name, es2); //Second's enemy data of first //Calculate rating change, anchored to all the other bots. double change1 = 0; double change2 = 0; for (int i=0;i<stats.length;i++) { //selectedrating = stats[i].rating; //Do stuff for first if (fid != i){ double expected = 1.0 / (1+Math.pow(20,(stats[i].rating-stats[fid].rating)/800)); expected = Math.max(Math.min(expected,max_score),min_score); if (stats[fid].scoremap.get(stats[i].name) != null){ double selectedwins = stats[fid].scoremap.get(stats[i].name).wins; selectedwins = Math.max(Math.min(selectedwins,max_score),min_score); change1 += rating_change * (selectedwins - expected); } } //Do stuff for second if (sid != i){ double expected = 1.0 / (1+Math.pow(20,(stats[i].rating-stats[sid].rating)/800)); expected = Math.max(Math.min(expected,max_score),min_score); if (stats[sid].scoremap.get(stats[i].name) != null){ double selectedwins = stats[sid].scoremap.get(stats[i].name).wins; selectedwins = Math.max(Math.min(selectedwins,max_score),min_score); change2 += rating_change * (selectedwins - expected); } } } if (!stats[fid].post) stats[fid].rating += change1; if (!stats[sid].post) stats[sid].rating += change2; stats[fid].battles++; stats[sid].battles++; } }