Multiplayer Hub Logo  
  Powered by Noble Master Games, http://www.noblemaster.com Multiplayer Dragon
  Forums Twitter Dev. Blog ⊕  
Home > Forums

MultiplayerHub.com
» Forums|New Posts
» Twitter
» Dev. Blog
» About
» Contact Us
Showcase
» Age of Conquest
» Demise of Nations
» Retro Commander

































Multiplayer Forums


Board index » Games » Age of Conquest (AOC) » AOC: Modding Discussions & Workshop


Post new topic Reply to topic  [ 91 posts ]  Go to page 1, 2, 3, 4, 5 ... 7  Next
Author Message
 Post subject: Rating Calcuation
PostPosted: 12 Aug 2006, 15:38 
Game Developer
Game Developer
User avatar

Joined: 17 Apr 2005, 02:34
Posts: 8416
Location: Honolulu
That's for calculating the ranking :kg: .

Code:
/**
* Ranking class.
*
* @author   king (http://www.aevumobscurum.com)
* @since    February 22, 2006
*/
public class Ranking implements Serializable {
 
  /** Minimum number of players for ranking. */
  public static final int MINIMUM_PLAYERS_FOR_RANKING = 5;
 
  /** The rating. */
  private int rating = 900;
  /** The ranking volatility. */
  private int volatility = 400;
  /** The number of games played. */
  private int gamesPlayed = 0;
 
 
  /** The various types rating classifications. */
  public static enum RatingClassification {
    /** Level 0. */
    LEVEL0("0", new Color(0x00818181), 0, 799),
    /** Level 1. */
    LEVEL1("*", new Color(0x0001C351), 800, 1099),
    /** Level 2. */
    LEVEL2("**", new Color(0x00029AEF), 1100, 1399),
    /** Level 3. */
    LEVEL3("***", new Color(0x00F5E800), 1400, 1799),
    /** Level 4. */
    LEVEL4("****", new Color(0x00F7941D), 1800, 2199),
    /** Level 5. */
    LEVEL5("*****", new Color(0x00E22A24), 2200, Integer.MAX_VALUE);
   
    /** The name for the given rating. */
    private final String name;
    /** The color for the given rating. */
    private final Color color;
    /** The minimum number for the rating. */
    private final int minRating;
    /** The maximum number for the rating. */
    private final int maxRating;
   
    /**
     * Constructor for rating enum with value.
     *
     * @param name  The name for the given rating interval.
     * @param color  The color for the given rating.
     * @param minRating  The minimum rating for the given interval.
     * @param maxRating  The maximum rating for the given interval.
     */
    private RatingClassification(String name, Color color, int minRating, int maxRating) {
      this.name = name;
      this.color = color;
      this.minRating = minRating;
      this.maxRating = maxRating;
    }
   
    /**
     * Returns the rating classification for the given rating.
     *
     * @param rating  The rating to find the classification for.
     * @return  The rating classification.
     */
    public static RatingClassification find(int rating) {
      if ((rating >= LEVEL0.minRating) && (rating <= LEVEL0.maxRating)) {
        return LEVEL0;
      }
      else if ((rating >= LEVEL1.minRating) && (rating <= LEVEL1.maxRating)) {
        return LEVEL1;
      }
      else if ((rating >= LEVEL2.minRating) && (rating <= LEVEL2.maxRating)) {
        return LEVEL2;
      }
      else if ((rating >= LEVEL3.minRating) && (rating <= LEVEL3.maxRating)) {
        return LEVEL3;
      }
      else if ((rating >= LEVEL4.minRating) && (rating <= LEVEL4.maxRating)) {
        return LEVEL4;
      }
      else if ((rating >= LEVEL5.minRating) && (rating <= LEVEL5.maxRating)) {
        return LEVEL5;
      }
      else {
        // not found, just return null
        return null;
      }
    }
   
    /**
     * To query the name.
     *
     * @return  The name for the given classification.
     */
    public String getName() {
      return this.name;
    }

    /**
     * Ths color for the given classification.
     *
     * @return  The color for the given classification.
     */
    public Color getColor() {
      return this.color;
    }
   
    /**
     * Returns the minimum rating for this rating.
     *
     * @return  The minimum rating value.
     */
    public int getMinRating() {
      return this.minRating;
    }
   
    /**
     * Returns the maximum rating value.
     *
     * @return  The maximum rating value.
     */
    public int getMaxRating() {
      return this.maxRating;
    }
  };

 
  /**
   * Returns the number of games played.
   *
   * @return  The number of games played.
   */
  public int getGamesPlayed() {
    return gamesPlayed;
  }
 
  /**
   * Sets the number of games played.
   *
   * @param gamesPlayed  The number of games played.
   */
  public void setGamesPlayed(int gamesPlayed) {
    this.gamesPlayed = gamesPlayed;
  }
 
  /**
   * Returns the rating.
   *
   * @return  The rating.
   */
  public int getRating() {
    return rating;
  }
 
  /**
   * Sets a new rating.
   *
   * @param rating  The new rating.
   */
  public void setRating(int rating) {
    this.rating = rating;
  }
 
  /**
   * Returns the rating volatility.
   *
   * @return  The rating volatility.
   */
  public int getVolatility() {
    return volatility;
  }
 
  /**
   * Sets the rating volatility.
   * 
   * @param volatility  The volatility.
   */
  public void setVolatility(int volatility) {
    this.volatility = volatility;
  }
 
  /**
   * Returns the average rating for all the given rankings.
   *
   * @param rankings  The rankings to calculate the average rating for.
   * @return  The average rating.
   */
  public static double getAverageRating(List<Ranking> rankings) {
    double averageRating = 0;
    for (Ranking ranking: rankings) {
      averageRating += ranking.getRating();
    }
    averageRating /= rankings.size();
    return averageRating;
  }
 
  /**
   * Returns the competition factor for the given rankings.
   *
   * @param rankings  The rankings to calculate the competition factor for.
   * @return  The competition factor.
   */
  public static double getCompetitionFactor(List<Ranking> rankings) {
    double volatilitySum2 = 0;
    for (Ranking ranking: rankings) {
      volatilitySum2 += ranking.getVolatility() * ranking.getVolatility();
    }
   
    double averageRating = getAverageRating(rankings);
    double ratingSum2 = 0;
    for (Ranking ranking: rankings) {
      ratingSum2 += (ranking.getRating() - averageRating) * (ranking.getRating() - averageRating);
    }
   
    int size = rankings.size();
    return Math.sqrt((volatilitySum2 / size) + (ratingSum2 / (size - 1)));
  }
 
  /**
   * Returns the win probability of this ranking compared to the inputted ranking.
   *
   * @param ranking  The other ranking to calculate the win probability for.
   * @return  The win probability for this ranking.
   */
  public double getWinProbability(Ranking ranking) {
    double a = ranking.getRating() - rating;
    double b = ranking.getVolatility() * ranking.getVolatility() + volatility * volatility;
    double erfValue = erf(a / Math.sqrt(2 * b));
    return 0.5 * (erfValue + 1.0);
  }
 
  /**
   * Returns the win probability compared to everybody.
   *
   * @param rankings  The others to compare this ranking to.
   * @return  The win probability.
   */
  public double getWinProbability(List<Ranking> rankings) {
    if (rankings.size() > 1) {
      double probability = 0;
      for (Ranking ranking: rankings) {
        if (this != ranking) {
          probability += ranking.getWinProbability(this);
        }
      }
      return probability / (rankings.size() * (rankings.size() - 1) / ((double)2));
    }
    else {
      return 1.0;
    }
  }
 
  /**
   * Returns this ranking's expected rank compared to other rankings.
   *
   * @param rankings  The other ranking to compare this ranking to.
   * @return  The expected rank compared to other rankings.
   */
  public double getExpectedRank(List<Ranking> rankings) {
    double expectedRankSum = 0;
    for (Ranking ranking: rankings) {
      expectedRankSum += getWinProbability(ranking);
    }
    return expectedRankSum + 0.5;
  }
 
  /**
   * Returns the expected performance compared to other rankings.
   *
   * @param rankings  The other rankings to compare this ranking to.
   * @return  The expected performance of this ranking.
   */
  public double getExpectedPerformance(List<Ranking> rankings) {
    return -gaussianPercentage((getExpectedRank(rankings) - 0.5) / rankings.size());   
  }
 
  /**
   * Returns the actual performance of this ranking.
   *
   * @param actualRank  The actual rank. Rank is the actual rank of the ranking in the
   *              competition based on score (1 for first place, NumPlayers forlast). If the
   *              player tied with another player, the rank is the average of the positions
   *              covered by the tied players.
   * @param numPlayers  The number of players.
   * @return  The actual performance of this ranking.
   */
  public double getActualPerformance(double actualRank, int numPlayers) {
    return -gaussianPercentage((actualRank - 0.5) / numPlayers);   
  }
 
  /**
   * Returns the performed as rating.
   *
   * @param actualRank  The actual rank. Rank is the actual rank of the ranking in the
   *              competition based on score (1 for first place, NumPlayers forlast). If the
   *              player tied with another player, the rank is the average of the positions
   *              covered by the tied players.
   * @param rankings  The other player's rankings.
   * @return  The performed as rating.
   */
  public double getPerformedAsRating(double actualRank, List<Ranking> rankings) {
    return rating + getCompetitionFactor(rankings)
                  * (getActualPerformance(actualRank, rankings.size()) - getExpectedPerformance(rankings));
  }
 
  /**
   * Returns the weight of a competition for the player.
   *
   * @return  The weight of the competition for the player.
   */
  public double getWeight() {
    return (1d / (1d - (0.58 / (gamesPlayed + 1d) + 0.18))) - 1d;
  }
 
  /**
   * Returns the cap for this player.
   *
   * @return  The cap for this player.
   */
  public double getCap() {
    return 180d + (1500d / (1d + gamesPlayed));
  }
 
 
  /**
   * Returns the new ranking for this ranking.
   *
   * @param actualRank  The actual rank. Rank is the actual rank of the player in the
   *              competition based on score (1 for first place, NumPlayers forlast). If the
   *              player tied with another player, the rank is the average of the positions
   *              covered by the tied players.
   * @param rankings  The other player's rankings.
   * @return  The new ranking
   */
  public Ranking getNewRanking(double actualRank, List<Ranking> rankings) {
    Ranking newRanking = new Ranking();
   
    // increase games played
    newRanking.setGamesPlayed(gamesPlayed + 1);
   
    // calculate ranking and volatility
    double weight = getWeight();
    double cap = getCap();
    double perfAs = getPerformedAsRating(actualRank, rankings);
   
    double newRating = (rating + weight * perfAs) / (1 + weight);
    if ((newRating - rating) > cap) {
      newRating = rating + cap;
    }
    else if ((newRating - rating) < -cap) {
      newRating = rating - cap;
    }
    newRanking.setRating((int)Math.round(newRating));
   
    double a = ((newRating - rating) * (newRating - rating)) / weight;
    double b = volatility * volatility / (weight + 1);
    double newVolatility = Math.sqrt(a + b);
    newRanking.setVolatility((int)Math.round(newVolatility));
   
    return newRanking;
  }
 
  /**
   * Returns the new rankings for the inputted data.
   *
   * @param actualRanks  The actual ranks. Rank is the actual rank of the player in the
   *              competition based on score (1 for first place, NumPlayers forlast). If the
   *              player tied with another player, the rank is the average of the positions
   *              covered by the tied players.
   * @param rankings  The actual rankings.
   * @return  The new rankings in the same order as the inputted rankings.
   */
  public static List<Ranking> getNewRankings(List<Double> actualRanks, List<Ranking> rankings) {
    List<Ranking> newRankings = new ArrayList<Ranking>();
    for (int i = 0; i < actualRanks.size(); i++) {
      double actualRank = actualRanks.get(i);
      Ranking ranking = rankings.get(i);
      Ranking newRanking = ranking.getNewRanking(actualRank, rankings);
      newRankings.add(newRanking);
    }
    return newRankings;
  }
 
  /**
   * Error function.
   *
   * @param x  Input value.
   * @return  Error funtion output
   */
  private double erf(double x) {
    return 2.0 * pn(x * Math.sqrt(2)) - 1;
  }
 
  /**
   * Percentage point of the standard normal distribution. Inverse of the distribution
   * function.
   *
   * @param p  The input value.
   * @return  Inverse of the normal distribution.
   */
  private double gaussianPercentage(double p) {
    return pninv(p);
  }

  /**
   * Inverse Standard normal distribution.
   * Approximate using secant method.
   *
   * @param x  The input value.
   * @return  The output value.
   */
  private double pninv(double x) {
      if (x==0.5) {
        return 0;
      }
      if (x<=0) {
        return Double.NEGATIVE_INFINITY;
      }
      if (x>=1) {
        return Double.POSITIVE_INFINITY;
      }
      if (x<0.5) {
        return -pninv(1 - x);
      }
      return secant(x, 1, 1.1);     
  }

  /**
   * Secant method.
   *
   * @param a  Parameter a.
   * @param x0  Parameter x0.
   * @param x1  Parameter x1.
   * @return  The result.
   */
  private double secant(double a, double x0, double x1) {
    double xi = x0, xii = x1, x;
    double yi = pn(x0)-a, yii = pn(x1)-a, y;

    do {
      x = xii - yii * (xii - xi) / (yii - yi);
      y = pn(x)-a;

      xi = xii; xii = x;
      yi = yii; yii = y;
    }
    while (Math.abs(y) > 1e-14);

    return x;
  }
 
  /**
   * Compute Standard Normal Distribution.
   * Source: Abramovitz & Stegun, 26.2.11, pg. 932
   *
   * @param x  The value to calculate normal distribution for.
   * @return  The normal distribution.
   */
  private double pn(double x) {
    final double epsilon = 1e-30;
    if (x == 0) {
      return 0.5;
    }
    if (x < 0) {
      return 1 - pn(-x);
    }
    if (x > 12) {
      return 1;
    }

    double fac = x;
    double tot = fac;
    int n = 1;

    while (Math.abs(fac) > epsilon) {
       fac = fac * x * x / (2.0 * n + 1);
       tot += fac;
       n  = n+1;
    }
     
    return 0.5 + zn(x) * tot;
  }

  /**
   * Compute density of standard normal distribution.
   *
   * @param x  The value to calculate the density for.
   * @return The density.
   */
  private double zn(double x) {
    final double sqrt2pi = Math.sqrt(2*Math.PI);
    return 1.0 / (sqrt2pi * Math.exp(x * x / 2));
  }
}

_________________
play: Age of Conquest IV


Top
 Profile  
 
 Post subject:
PostPosted: 13 Aug 2006, 00:14 
Knight
Knight
User avatar

Joined: 14 Jun 2006, 23:37
Posts: 2315
Location: Mostlikely at the bar
Yeah I get it

not
:???:


Top
 Profile  
 
 Post subject:
PostPosted: 13 Aug 2006, 00:16 
Game Developer
Game Developer
User avatar

Joined: 17 Apr 2005, 02:34
Posts: 8416
Location: Honolulu
yeah!!! first post in the geek section :kg:

*stig gets "geek" award 2006 - thanks for posting*

_________________
play: Age of Conquest IV


Top
 Profile  
 
 Post subject:
PostPosted: 13 Aug 2006, 00:18 
Knight
Knight
User avatar

Joined: 14 Jun 2006, 23:37
Posts: 2315
Location: Mostlikely at the bar
Aschi wrote:
*stig gets "geek" award 2006 - thanks for posting*

first time a geek award goes to someone who doesn't even know how to put his computer back together after cleaning, HURRAY


Top
 Profile  
 
 Post subject:
PostPosted: 14 Aug 2006, 03:45 
Knight
Knight
User avatar

Joined: 28 May 2006, 02:55
Posts: 3071
Location: Wigan, UK
you clean your computer!!! :irre:

or is it me :irre:

_________________
ImageShow me force and reep what you sowImage
Image


Top
 Profile  
 
 Post subject:
PostPosted: 14 Aug 2006, 05:19 
Knight
Knight
User avatar

Joined: 14 Jun 2006, 23:37
Posts: 2315
Location: Mostlikely at the bar
dusty m8, so I took the panels of and the dust out, but when I rebuild it again I put on the panels the wrong way


Top
 Profile  
 
 Post subject:
PostPosted: 14 Aug 2006, 12:27 
Knight
Knight
User avatar

Joined: 28 May 2006, 02:55
Posts: 3071
Location: Wigan, UK
Doh!

_________________
ImageShow me force and reep what you sowImage
Image


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 00:35 
Knight
Knight
User avatar

Joined: 28 May 2006, 02:55
Posts: 3071
Location: Wigan, UK
just out of curiosity, soon (well within the next year) there will be two or more peeps with ratings over 2200, the max number, who'll be in the number one position the last one to win., one with most completed games (yes it plays well for me if i can get that far) or the first one there?

_________________
ImageShow me force and reep what you sowImage
Image


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 01:04 
Game Developer
Game Developer
User avatar

Joined: 17 Apr 2005, 02:34
Posts: 8416
Location: Honolulu
2200+

The ratings will go OVER 2200 ...

All the ratings together will form a sort of bell curve with some players over 2200. 2300, 2400 is definitly in the reach!

_________________
play: Age of Conquest IV


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 01:53 
Knight
Knight
User avatar

Joined: 14 Jun 2006, 23:37
Posts: 2315
Location: Mostlikely at the bar
I think there will be some limit, you simply can't go over 2200 I think.
UNLESS, you get back up by loads of players. Say Bio and I help Mab to win every game, but no-one will do that


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 02:18 
Knight
Knight
User avatar

Joined: 28 May 2006, 02:55
Posts: 3071
Location: Wigan, UK
way i read it looked like it was capped no proberlem if it continues onward

_________________
ImageShow me force and reep what you sowImage
Image


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 07:53 
Merchant
Merchant
User avatar

Joined: 15 Aug 2006, 10:17
Posts: 421
Location: Spain
Yeah, you seems to be very skilled at Java!
I like Java. Now I am learning JSP.


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 10:02 
Game Developer
Game Developer
User avatar

Joined: 17 Apr 2005, 02:34
Posts: 8416
Location: Honolulu
It definitly will go over 2200. In maybe couple of years, some players might even reach 2800 ...

However, the higher your score, the more time it takes to get it!

_________________
play: Age of Conquest IV


Top
 Profile  
 
 Post subject:
PostPosted: 18 Aug 2006, 10:17 
Mercenary
Mercenary
User avatar

Joined: 02 Jul 2006, 11:45
Posts: 565
Location: Brasil
you can just create new colors and rew ranks


Top
 Profile  
 
 Post subject:
PostPosted: 19 Oct 2006, 12:59 
Game Developer
Game Developer
User avatar

Joined: 17 Apr 2005, 02:34
Posts: 8416
Location: Honolulu
Wow, this thread has been read about 500 times!

_________________
play: Age of Conquest IV


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 91 posts ]  Go to page 1, 2, 3, 4, 5 ... 7  Next


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Green Smilies by http://www.greensmilies.com/

Home  |  Forums  |  Twitter  |  Dev. Blog  |  About  |  Contact