Giter Site home page Giter Site logo

jskills's People

Contributors

moserware avatar nsp avatar pmg1991 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jskills's Issues

Keep track of players after using rating calculator

Hey @nsp,
Today I was using the TwoTeamRatingCalculator class to calculate ratings for a team game, the problem is, once I do TwoTeamRatingCalculator.calculateNewRatings(), it returns a Map<IPlayer,Rating>. When it does that, I can't keep track of which player in that map corresponds to which player in the game. I used Player.getID() to keep track of my players before, but since the IPlayer interface does not have IDs, I lose track of who is who. Is there currently a way to find out?

Thanks,
Jake.

De-C#-ify the API

These are all minor nit-picks, nobody will hate you if you disregard this issue :-)

While it is a convention to prefix the names of Interfaces with an "I" in C#, it is the convention in Java not to do this.

Similarly, the convention in Java is for all methods to begin with a lower-case letter (and then use camel-case subsequent to that, eg. TrueSkillFactorGraph.BuildGraph() should be TrueSkillFactorGraph.buildGraph().

($10) Some calculations produce NaN

Bountysource

This works fine:

  @Test
  public void testOk() {
    GameInfo gameInfo = new GameInfo(1500, 500, 240, 10, 0.1);
    Collection<ITeam> ts = Arrays.asList(
      new Team().addPlayer(new jskills.Player<>(1), new Rating(3453, 74)),
      new Team().addPlayer(new jskills.Player<>(2), new Rating(38, 181))
    );
    Map<IPlayer, Rating> newRatings = TrueSkillCalculator.calculateNewRatings(gameInfo, new ArrayList<>(ts), 1, 2);

    newRatings.forEach((iPlayer, rating) -> System.out.println(rating));
  }

Output:

Mean(μ)=3453.000000, Std-Dev(σ)=74.672619
Mean(μ)=38.000000, Std-Dev(σ)=181.276033

While this produces NaN (note that only player 2's deviation has been changed)

  @Test
  public void testNaN() {
    GameInfo gameInfo = new GameInfo(1500, 500, 240, 10, 0.1);
    Collection<ITeam> ts = Arrays.asList(
      new Team().addPlayer(new jskills.Player<>(1), new Rating(3453, 74)),
      new Team().addPlayer(new jskills.Player<>(2), new Rating(38, 180))
    );
    Map<IPlayer, Rating> newRatings = TrueSkillCalculator.calculateNewRatings(gameInfo, new ArrayList<>(ts), 1, 2);

    newRatings.forEach((iPlayer, rating) -> System.out.println(rating));
  }

Output:

Mean(μ)=NaN, Std-Dev(σ)=74.672619
Mean(μ)=38.000000, Std-Dev(σ)=180.277564

Suggested change to high-level API

I thought about how I would like this to work when I first approached JSkills, and here was what I came up with. I'll just walk through a few example usages. Its entirely possible that there are use-cases I'm unaware of that this won't support (my personal needs from JSkills were very rudimentary).

One significant difference is that we use the same TrueskillGame class for all types of games, regardless of the number of players, or whether there are teams. Two player example (note, I propose renaming GameInfo to GameConfig, and TrueskillCalc to TrueskillGame):

TrueskillGame trueskillGame = new TrueskillGame();

Or, to use non-default gameConfig:

TrueskillGame trueskillGame = new TrueskillGame(GameConfig gameConfig);

For extra brownie points, we may also want to consider supporting this "Builder" pattern for the TrueskillGame, see http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html

Ok, so here is how we do a simple two-player game (Rating is as before - a simple class with two public double non-final fields, mean, and standardDeviation):

Rating playerRating1 = trueskillGame.newDefaultRating();

or

Rating playerRating2 = new Rating(mean, stdDev);

player1 wins, player2 comes second

trueskillGame.updateRatings(playerRating1, 1, playerRating2, 2);

Note, there are multiple overloaded implementations of TrueskillGame.updateRatings(). In this case, we use updateRatings(Player a, int aResult, Player b, bResult) - and this contains code specific to a one-on-one game (like TwoPlayerTrueSkillCalculator)

Note also that the Ratings are updated in-place. This is more efficient and probably in-keeping with the most common use-cases. Rating should implement a clone() method, so that they can be copied before giving them to updateRatings() if the caller needs to keep the original around.

Two teams with 2 players in the first team, and 3 players in the second

Team implements the List<Rating> interface

Team team1 = Team.create(playerRating1, playerRating2);
Team team2 = Team.create(playerRating3, playerRating4, playerRating5);

trueskillGame.updateRatings(team1, 1, team2, 2);

What about multiple players? We use a Map

Here, player1 wins, and player2 and player3 tie for second place ("Maps" is a utility class provided by Google's guava-libraries).

Map<Rating, Integer> gameResults = Maps.newHashMap();
Rating playerRating1 = ...
gameResults.put(playerRating1, 1);
Rating playerRating2 = ...
gameResults.put(playerRating2, 2);
Rating playerRating3 = ...
gameResults.put(playerRating3, 2);

trueskillGame.updateRatings(gameResults);

HOWEVER, we can't use another overloaded implementation of our updateRatings() to do the same with teams because of a limitation of Java's generics, so we do this:

Map<Team, Integer> gameResults = Maps.newHashMap();
// ...Create the teams and add them to gameResults..

Now update the ratings with these results:

trueskillGame.updateTeamRatings(gameResults);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.