Don't rate guests, and don't include guests in the rating adjustments for persistent players. Generally more robust code.

git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@349 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Par Winzell
2007-07-06 01:07:03 +00:00
parent 3484e8cd1f
commit 48bde23d17
@@ -28,6 +28,7 @@ import java.util.logging.Level;
import com.samskivert.io.PersistenceException; import com.samskivert.io.PersistenceException;
import com.samskivert.util.ArrayUtil;
import com.samskivert.util.HashIntMap; import com.samskivert.util.HashIntMap;
import com.samskivert.util.IntMap; import com.samskivert.util.IntMap;
import com.samskivert.util.Invoker; import com.samskivert.util.Invoker;
@@ -97,15 +98,22 @@ public abstract class RatingManagerDelegate
public boolean invoke () { public boolean invoke () {
int gameId = _gmgr.getGameConfig().getGameId(); int gameId = _gmgr.getGameConfig().getGameId();
// enumerate our players // enumerate our non-guest players
Integer[] players = new Integer[_gmgr.getPlayerCount()]; Integer[] allPlayers = new Integer[_gmgr.getPlayerCount()];
for (int ii = 0; ii < players.length; ii ++) { Integer[] ratedPlayers = new Integer[allPlayers.length];
players[ii] = _gmgr.getPlayerPersistentId(_gmgr.getPlayer(ii)); int jj = 0;
for (int ii = 0; ii < allPlayers.length; ii ++) {
allPlayers[ii] = _gmgr.getPlayerPersistentId(_gmgr.getPlayer(ii));
if (allPlayers[ii] != 0) {
// this is a player with a persistent id, a player we can rate
ratedPlayers[jj ++] = allPlayers[ii];
}
} }
ratedPlayers = ArrayUtil.splice(ratedPlayers, jj);
try { try {
// fetch their previous ratings for this game // fetch the previous ratings of our persistent users, for this game
List<RatingRecord> records = _repo.getRatings(gameId, players); List<RatingRecord> records = _repo.getRatings(gameId, ratedPlayers);
// and make it easy to look them up by their id // and make it easy to look them up by their id
IntMap<RatingRecord> map = new HashIntMap<RatingRecord>(); IntMap<RatingRecord> map = new HashIntMap<RatingRecord>();
@@ -114,12 +122,17 @@ public abstract class RatingManagerDelegate
} }
// now build the array we keep around until the end of the game // now build the array we keep around until the end of the game
_ratings = new Rating[_gmgr.getPlayerCount()]; _ratings = new Rating[allPlayers.length];
for (int ii = 0; ii < _ratings.length; ii ++) { for (int ii = 0; ii < _ratings.length; ii ++) {
RatingRecord record = map.get(players[ii]); if (allPlayers[ii] == 0) {
// for guests we let the slot remain null
continue;
}
RatingRecord record = map.get(allPlayers[ii]);
// if the player had no previous record, initiate them at default values // if the player had no previous record, initiate them at default values
_ratings[ii] = record != null ? _ratings[ii] = record != null ?
new Rating(record.rating, record.experience) : new Rating(); new Rating(allPlayers[ii], record.rating, record.experience) :
new Rating(allPlayers[ii]);
} }
return true; return true;
@@ -153,13 +166,13 @@ public abstract class RatingManagerDelegate
// compute the updated ratings // compute the updated ratings
int[] nratings = new int[_ratings.length]; int[] nratings = new int[_ratings.length];
for (int ii = 0; ii < _ratings.length; ii ++) { for (int ii = 0; ii < _ratings.length; ii ++) {
nratings[ii] = computeRating(ii); nratings[ii] = _ratings[ii] != null ? computeRating(ii) : -1;
} }
// and store them // and store them
boolean modified = false; boolean modified = false;
for (int ii = 0; ii < _ratings.length; ii++) { for (int ii = 0; ii < _ratings.length; ii++) {
// skip this rating if we weren't able to compute a value // skip this rating if it's a guest slot or we weren't able to compute a value
if (nratings[ii] < 0) { if (nratings[ii] < 0) {
continue; continue;
} }
@@ -173,22 +186,18 @@ public abstract class RatingManagerDelegate
return; return;
} }
// else enumerate our players // else persist the result
final int[] players = new int[_gmgr.getPlayerCount()];
for (int ii = 0; ii < players.length; ii ++) {
players[ii] = _gmgr.getPlayerPersistentId(_gmgr.getPlayer(ii));
}
// and finally persist the result
final int gameId = _gmgr.getGameConfig().getGameId(); final int gameId = _gmgr.getGameConfig().getGameId();
CrowdServer.invoker.postUnit(new Invoker.Unit() { CrowdServer.invoker.postUnit(new Invoker.Unit() {
public boolean invoke () { public boolean invoke () {
try { try {
for (int ii = 0; ii < _ratings.length; ii ++) { for (int ii = 0; ii < _ratings.length; ii ++) {
// for each player, update or create the rating record if (_ratings[ii] != null) {
// TODO: reorganize things so this can be a single db request? // for each rated player, update or create the rating record
_repo.setRating(gameId, players[ii], _ratings[ii].rating, // TODO: reorganize things so this can be a single db request?
_ratings[ii].experience); _repo.setRating(gameId, _ratings[ii].playerId,
_ratings[ii].rating, _ratings[ii].experience);
}
} }
return true; return true;
@@ -202,7 +211,9 @@ public abstract class RatingManagerDelegate
public void handleResult () { public void handleResult () {
// let subclasses store away the new ratings if they so desire // let subclasses store away the new ratings if they so desire
for (int ii = 0; ii < _ratings.length; ii ++) { for (int ii = 0; ii < _ratings.length; ii ++) {
updateRatingInMemory(gameId, _gmgr.getPlayerName(ii), _ratings[ii]); if (_ratings[ii] != null) {
updateRatingInMemory(gameId, _gmgr.getPlayerName(ii), _ratings[ii]);
}
} }
} }
}); });
@@ -228,8 +239,8 @@ public abstract class RatingManagerDelegate
int opponents = 0; int opponents = 0;
for (int ii = 0; ii < _ratings.length; ii++) { for (int ii = 0; ii < _ratings.length; ii++) {
// we don't care how we did against ourselves... // we don't care how we did against ourselves, or against guests...
if (pidx == ii) { if (pidx == ii || _ratings[ii] == null) {
continue; continue;
} }
@@ -279,18 +290,21 @@ public abstract class RatingManagerDelegate
*/ */
protected static class Rating protected static class Rating
{ {
/** A player's rating for a game. */ /** The id of the rated player. */
public int playerId;
/** The player's rating for our game. */
public int rating; public int rating;
/** The number of times a player's played a game. */ /** The number of times the player's played our game. */
public int experience; public int experience;
/** /**
* Sets up a new {@link Rating} object with default values. * Sets up a new {@link Rating} object with default values.
*/ */
public Rating () public Rating (int playerId)
{ {
super(); this.playerId = playerId;
this.rating = DEFAULT_RATING; this.rating = DEFAULT_RATING;
this.experience = 0; this.experience = 0;
} }
@@ -298,9 +312,9 @@ public abstract class RatingManagerDelegate
/** /**
* Sets up a new {@link Rating} object with the given values. * Sets up a new {@link Rating} object with the given values.
*/ */
public Rating (int rating, int experience) public Rating (int playerId, int rating, int experience)
{ {
super(); this.playerId = playerId;
this.rating = rating; this.rating = rating;
this.experience = experience; this.experience = experience;
} }