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. iOS开发——常见错误——使用MJRefresh返回上一个界面蹦掉的情况

    最近在使用MJRefresh框架时发现了一个bug 下面是我的源代码 前一个界面 -(void)tableView:(UITableView *)tableView didSelectRowAtInd ...

  2. class training

    实验3-1 分别使用while循环.do while循环.for循环求 (即求1+2+3+ --+100). 参考: 源码 方法一#include<stdio.h> int main(){ ...

  3. 跟着百度学PHP[4]OOP面对对象编程-6-封装性private

    所谓封装顾名思义,如同箱子般给封装起来.结合前面的来说就是对属性或者方法,封装后的方法或属性只能有类内部进行调用.外部调用不了. 封装性的好处: 1.信息隐藏 2.http://www.cnblogs ...

  4. Struts2 Action 动态传参数

    Struts2的两个Action之间传参的问题. 需求功能是这样:Action1 获取数据库配置内容,得到相应Model的 动态URL ,这里的URL 有的是Action有的是JSP页面. 1.使用r ...

  5. Codeforces Gym 101138 G. LCM-er

    Description 在 \([a,b]\) 之间选择 \(n\) 个数 (可以重复) ,使这 \(n\) 个数的最小公倍数能被 \(x\) 整除,对 \(10^9+7\) 取膜. \(1\leqs ...

  6. 线段树区间更新&&求和poj3486

    给出了一个序列,你需要处理如下两种询问. ≤ c ≤ ). "Q a b" 询问[a, b]区间中所有值的和. Input 第一行包含两个整数N, Q. ≤ N,Q ≤ . 第二行 ...

  7. 网页百度地图API相关资料

    百度地图API——网页URI接口.手机网页点击直接导航:js生成一个地图网页 或 直接跳转到百度导航界面 http://developer.baidu.com/map/index.php?title= ...

  8. linux自动定时备份web程序和mysql数据库

    前些天受朋友说linux定时备份不知道怎么搞,叫帮忙处理一下.由于这段时间正闲着,所以也就欣然答应.由于朋友对linux不懂也希望我将操作的过程记录下来,也就是越详细越好.所以写得比较$%^& ...

  9. zju3547

    题意:给出n(1<=n<=10^8),求小于n的,求所有与n互质的数字的四次幂的加和是多少. 分析:容斥原理 首先要知道四次幂求和公式,1^4+2^4+...+n^4=n*(n+1)*(2 ...

  10. linux学习中遇到的各种故障与解决方法

    一.nginx 二.apache 三.mysql 四.tomcat 五.oracle 六.python python安装mysqldb(mysql-devel包)出现错误: error: comman ...