首页 > 代码库 > Elo rating system 模拟
Elo rating system 模拟
1 package org.cc.foo_008; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Random; 6 7 public class Main_006 { 8 9 public static void main(String[] args) { 10 11 EloRatingSystemDemo e=new EloRatingSystemDemo(); 12 13 e.show(); 14 15 // User u=e.gamer.get(new User().level).get(0); 16 // 17 // for(int i=0;i<999;i++){ 18 // e.play(u); 19 // } 20 // 21 // e.show(); 22 // 23 // System.out.println(u.rating); 24 25 //大部分情况下总能选出一个或少数几个等级比较高的(或比较低的...) 是这个算法比较神奇还是我的程序有问题呢... 26 for(int i=0;i<99999;i++){ 27 User u=e.randGetUser(); 28 e.play(u); 29 } 30 31 e.show(); 32 33 } 34 35 } 36 37 class EloRatingSystemDemo { 38 39 public List<List<User>> gamer=new ArrayList<>(); 40 //k值越大,升级就越快,绝大部分都处于越高位置 41 public double k=100; 42 43 public EloRatingSystemDemo() { 44 //十个级别 45 for(int i=0;i<10;i++){ 46 gamer.add(new ArrayList<>()); 47 } 48 49 //十个玩家 50 for(int i=0;i<1000;i++){ 51 User u=new User(); 52 gamer.get(u.level).add(u); 53 } 54 } 55 56 //为传入的玩家找到一个对手并开玩一局 57 public void play(User user){ 58 User river=user; 59 while(river==user){ 60 river=findRival(user); 61 } 62 fightAndRating(user,river); 63 } 64 65 //战斗并且评分(Elo Rating System) 66 public void fightAndRating(User u1,User u2){ 67 68 //暂时移除 69 gamer.get(u1.level).remove(u1); 70 gamer.get(u2.level).remove(u2); 71 72 //期望得分 73 double ea=1.0/(1+Math.pow(10,(u1.rating-u2.rating)/400.0)); 74 double eb=1.0/(1+Math.pow(10,(u2.rating-u1.rating)/400.0)); 75 76 //发生战斗...结果未知 77 int t=new Random().nextInt(3); 78 79 double t2=0; 80 if(t==0){ 81 //A赢 82 t2=u1.rating+k*(1-ea); 83 u1.rating=t2>0?t2:0; 84 t2=u2.rating+k*(0.5-eb); 85 u2.rating=t2>0?t2:0; 86 }else if(t==1){ 87 //B赢 88 t2=u1.rating+k*(0.5-ea); 89 u1.rating=t2>0?t2:0; 90 t2=u2.rating+k*(1-eb); 91 u2.rating=t2>0?t2:0; 92 }else if(t==2){ 93 //战平 94 t2=u1.rating+k*(0-ea);; 95 u1.rating=t2>0?t2:0; 96 t2=u2.rating+k*(0-eb); 97 u2.rating=t2>0?t2:0; 98 } 99 100 //放入101 int level=(int) (u1.rating/500);102 level=level<10?level:9;103 u1.level=level;104 gamer.get(u1.level).add(u1);105 106 level=(int) (u2.rating/500);107 level=level<10?level:9;108 u2.level=level;109 gamer.get(u2.level).add(u2);110 111 }112 113 //找到一个级别相当(左右偏移,实力最接近)的对手114 public User findRival(User user){115 //如果当前级别只有自己一个人的话就偏移,否则的话说明可以找到同级别的玩家116 int shift=gamer.get(user.level).size()==1?1:0;117 while(true){118 119 boolean exit=true;120 121 //优先匹配弱一些的对手122 if(user.level-shift>=0){123 User u=findRival0(user.level-shift);124 if(u!=null) return u;125 exit=false;126 }127 if(user.level+shift<10){128 User u=findRival0(user.level+shift);129 if(u!=null) return u;130 exit=false;131 }132 133 if(exit) return null;134 135 shift++;136 }137 }138 139 //500分为一个级别,找在某个级别的对手140 private User findRival0(int level){141 //检测这个级别是否有人142 List<User> list=gamer.get(level);143 if(list.isEmpty()) return null;144 //随机选取一个对手145 return list.get(new Random().nextInt(list.size()));146 }147 148 //随机获得一个用户149 public User randGetUser(){150 while(true){151 List<User> list=gamer.get(new Random().nextInt(gamer.size()));152 if(!list.isEmpty()) return list.get(new Random().nextInt(list.size()));153 }154 }155 156 //打印所有玩家的信息:157 public void show(){158 for(int i=0;i<gamer.size();i++){159 List<User> list=gamer.get(i);160 System.out.printf("Level %d: ",i+1);161 for(int j=0;j<list.size();j++){162 System.out.printf("%.2f ",list.get(j).rating);163 }164 System.out.println();165 }166 System.out.println();167 }168 169 }170 171 //代表一个玩家,初始分数为1500172 class User {173 double rating=1500;174 int level=(int) (rating/500);175 }
Elo rating system 模拟
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。