2 * Quoridor server and related libraries
3 * Copyright (C) 2009-2010 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. Look for COPYING file in the top folder.
16 * If not, see http://www.gnu.org/licenses/.
19 package cz.xelfi.quoridor.statistics;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Collections;
25 import java.util.ArrayList;
26 import javax.xml.bind.annotation.XmlElement;
27 import javax.xml.bind.annotation.XmlAttribute;
28 import javax.xml.bind.annotation.XmlElementWrapper;
29 import javax.xml.bind.annotation.XmlRootElement;
30 import javax.xml.bind.annotation.XmlAccessType;
31 import javax.xml.bind.annotation.XmlAccessorType;
37 @XmlAccessorType(XmlAccessType.FIELD)
38 public class EloList {
39 static int INITIAL_ELO = 1250;
40 static int MAX_ELO_DIFF = 400;
41 static int KVAL_START = 25;
42 static int KVAL_FOLLOW = 10;
43 static int KVAL_LIMIT = 30;
45 Map<String, Double> players;
46 Map<String, Integer> playerGames;
52 players = new HashMap<String, Double>();
53 playerGames = new HashMap<String, Integer>();
57 public EloList(EloList src){
58 this.players = new HashMap<String, Double>(src.players);
59 this.playerGames = new HashMap<String, Integer>(src.playerGames);
63 public void setEndDate(long endDate){
64 this.published = endDate;
67 public long getEndDate(){
68 return this.published;
71 @XmlElementWrapper(name="elolist")
72 @XmlElement(name="item")
73 public List<EloEntry> getFinalList(){
74 List<EloEntry> finalList = new ArrayList<EloEntry>();
75 for (Map.Entry<String, Double> player : players.entrySet()){
76 finalList.add(new EloEntry(player.getKey(), player.getValue(), playerGames.get(player.getKey())));
78 Collections.sort(finalList, EloEntry.BEST_FIRST);
82 public EloList putResult(String winner, String looser){
83 double wElo = getElo(winner);
84 double lElo = getElo(looser);
86 double eloDiff = wElo - lElo;
87 if(eloDiff < - MAX_ELO_DIFF)
88 eloDiff = - MAX_ELO_DIFF;
89 if(eloDiff > MAX_ELO_DIFF)
90 eloDiff = MAX_ELO_DIFF;
92 double wDiff = Math.round(100 * getKVal(winner) * (1 - (1 / (1 + Math.pow(10, -eloDiff / MAX_ELO_DIFF)))));
94 double lDiff = Math.round(100 * getKVal(looser) * (0 - (1 / (1 + Math.pow(10, eloDiff / MAX_ELO_DIFF)))));
97 players.put(winner, wElo + wDiff);
98 players.put(looser, lElo + lDiff);
102 public double getElo(String player){
103 Double elo = players.get(player);
104 return (elo == null) ? INITIAL_ELO : elo;
107 private int getKVal(String player){
108 Integer games = playerGames.get(player);
109 int g = (games == null) ? 0 : games;
110 // Side effect, method should not be called more times for the same game/player
111 playerGames.put(player, g + 1);
112 return g < KVAL_LIMIT ? KVAL_START : KVAL_FOLLOW;