首页 > 代码库 > 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 模拟