package org.cc.foo_008;

 import java.util.ArrayList;
import java.util.List;
import java.util.Random; public class Main_006 { public static void main(String[] args) { EloRatingSystemDemo e=new EloRatingSystemDemo(); e.show(); // User u=e.gamer.get(new User().level).get(0);
//
// for(int i=0;i<999;i++){
// e.play(u);
// }
//
// e.show();
//
// System.out.println(u.rating); //大部分情况下总能选出一个或少数几个等级比较高的(或比较低的...) 是这个算法比较神奇还是我的程序有问题呢...
for(int i=0;i<99999;i++){
User u=e.randGetUser();
e.play(u);
} e.show(); } } class EloRatingSystemDemo { public List<List<User>> gamer=new ArrayList<>();
//k值越大,升级就越快,绝大部分都处于越高位置
public double k=100; public EloRatingSystemDemo() {
//十个级别
for(int i=0;i<10;i++){
gamer.add(new ArrayList<>());
} //十个玩家
for(int i=0;i<1000;i++){
User u=new User();
gamer.get(u.level).add(u);
}
} //为传入的玩家找到一个对手并开玩一局
public void play(User user){
User river=user;
while(river==user){
river=findRival(user);
}
fightAndRating(user,river);
} //战斗并且评分(Elo Rating System)
public void fightAndRating(User u1,User u2){ //暂时移除
gamer.get(u1.level).remove(u1);
gamer.get(u2.level).remove(u2); //期望得分
double ea=1.0/(1+Math.pow(10,(u1.rating-u2.rating)/400.0));
double eb=1.0/(1+Math.pow(10,(u2.rating-u1.rating)/400.0)); //发生战斗...结果未知
int t=new Random().nextInt(3); double t2=0;
if(t==0){
//A赢
t2=u1.rating+k*(1-ea);
u1.rating=t2>0?t2:0;
t2=u2.rating+k*(0.5-eb);
u2.rating=t2>0?t2:0;
}else if(t==1){
//B赢
t2=u1.rating+k*(0.5-ea);
u1.rating=t2>0?t2:0;
t2=u2.rating+k*(1-eb);
u2.rating=t2>0?t2:0;
}else if(t==2){
//战平
t2=u1.rating+k*(0-ea);;
u1.rating=t2>0?t2:0;
t2=u2.rating+k*(0-eb);
u2.rating=t2>0?t2:0;
} //放入
int level=(int) (u1.rating/500);
level=level<10?level:9;
u1.level=level;
gamer.get(u1.level).add(u1); level=(int) (u2.rating/500);
level=level<10?level:9;
u2.level=level;
gamer.get(u2.level).add(u2); } //找到一个级别相当(左右偏移,实力最接近)的对手
public User findRival(User user){
//如果当前级别只有自己一个人的话就偏移,否则的话说明可以找到同级别的玩家
int shift=gamer.get(user.level).size()==1?1:0;
while(true){ boolean exit=true; //优先匹配弱一些的对手
if(user.level-shift>=0){
User u=findRival0(user.level-shift);
if(u!=null) return u;
exit=false;
}
if(user.level+shift<10){
User u=findRival0(user.level+shift);
if(u!=null) return u;
exit=false;
} if(exit) return null; shift++;
}
} //500分为一个级别,找在某个级别的对手
private User findRival0(int level){
//检测这个级别是否有人
List<User> list=gamer.get(level);
if(list.isEmpty()) return null;
//随机选取一个对手
return list.get(new Random().nextInt(list.size()));
} //随机获得一个用户
public User randGetUser(){
while(true){
List<User> list=gamer.get(new Random().nextInt(gamer.size()));
if(!list.isEmpty()) return list.get(new Random().nextInt(list.size()));
}
} //打印所有玩家的信息:
public void show(){
for(int i=0;i<gamer.size();i++){
List<User> list=gamer.get(i);
System.out.printf("Level %d: ",i+1);
for(int j=0;j<list.size();j++){
System.out.printf("%.2f ",list.get(j).rating);
}
System.out.println();
}
System.out.println();
} } //代表一个玩家,初始分数为1500
class User {
double rating=1500;
int level=(int) (rating/500);
}

Elo rating system 模拟的更多相关文章

  1. 从Elo Rating System谈到层次分析法

    1. Elo Rating System Elo Rating System对于很多人来说比较陌生,根据wikipedia上的解释:Elo评分系统是一种用于计算对抗比赛(例如象棋对弈)中对手双方技能水 ...

  2. Elo rating system(Elo 打分体系)

    A.B 两个待比较.评价的对象,分别打分为 RA,RB,则各自获胜的期望值为: ⎧⎩⎨⎪⎪⎪⎪⎪⎪EA=11+10(RB−RA)/400.EB=11+10(RA−RB)/400. 不妨令 QA=10R ...

  3. Codeforces Rating System

    来翻译一下官方文档,但是建议看英文原文,本文可能会出现一些错误,虽然不是为了方便自己查阅用的. 首先,对于人 \(i\),定义 \(r_i\) 是他的 rating,对于人 \(i,j\),定义 \( ...

  4. Atcoder Rating System

    来翻译一下官方文档,但是建议看英文原文,本文可能会出现一些错误,只是为了方便自己查阅用的. 对于你的每一场rated比赛,会有一个Performance值\(X_i\),你的rating是\(X_i- ...

  5. elo system

    今天了解了一下游戏中的PVP模块的实现,大多数的游戏都使用到了ELO算法,刚开始的时候并不清楚这个算法是做什么的,对此开始大量查找有关于ELO算法的资源,功夫不负有心人,总算找到一些有用的资源了. 先 ...

  6. HPU暑期集训积分赛2

    A. 再战斐波那契 单点时限: 1.0 sec 内存限制: 512 MB 小z 学会了斐波那契和 gcd 后,老师又给他出了个难题,求第N个和第M个斐波那契数的最大公约数,这可难倒了小z ,不过在小z ...

  7. Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) A B C D 水 模拟 二分 贪心

    A. Is it rated? time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  8. ural 2020 Traffic Jam in Flower Town(模拟)

    2020. Traffic Jam in Flower Town Time limit: 1.0 secondMemory limit: 64 MB Having returned from Sun ...

  9. ural 2015 Zhenya moves from the dormitory(模拟)

    2015. Zhenya moves from the dormitory Time limit: 1.0 secondMemory limit: 64 MB After moving from hi ...

随机推荐

  1. python 编码 UnicodeDecodeError

    将一个py脚本从Centos转到win运行,出错如下: UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: il ...

  2. 自定义Listview

    public class MyListView extends ListView { public MyListView(Context context) { super(context); } pu ...

  3. Android--UI之AutoCompleteTextView

    前言 之前讲过EditText,有兴趣的朋友可以看一下.这篇博客主要说明的是自动完成文本框,它实际上也是一个文本编辑框,可以理解为对EditText功能的扩展,它对输入的内容可以进行提示并且自动完成. ...

  4. hdu4747——Mex

    1.题目大意:对一个序列的每一个区间求Mex,最后所有的mex相加(mex就是SG的那个),力求nlogn... 2.分析:最近开始刷线段树了,还是有很多不会啊 首先把1-1 1-2 1-- 1-n这 ...

  5. .net获取周几(中文)

    DateTime.Now.ToString("yyyy年MM月dd日 星期ddd hh时mm分ss秒", new System.Globalization.CultureInfo( ...

  6. putty如何使用

    使用putty连接管理centos 1 双击putty.exe2 和linux命令行一样了 使用psftp上传和下载 cd d:/psftppsftp open 10.0.0.9 输入用户密码root ...

  7. hdu1455 dfs+剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. An exception occurred during a WebClient request

    System.Net.WebException was caught HResult=-2146233079 Message=An exception occurred during a WebCli ...

  9. 套接字IO超时设置和使用select实现超时管理

    在涉及套接字IO超时的设置上有一下3种方法: 1.调用alarm,它在指定的时期满时产生SIGALRM信号.这个方法涉及信号的处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm ...

  10. html常用标签的使用方法

    1  html标题 <h1> to <h6> <!DOCTYPE html> <html lang="en"> <head&g ...