mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-24 11:50:58 -04:00
Fixed #2448 with better random session query distribution.
This commit is contained in:
parent
4669d4cb0a
commit
eb075b99a0
3 changed files with 33 additions and 6 deletions
|
@ -208,6 +208,12 @@ _.extend LevelSessionSchema.properties,
|
|||
type: 'boolean'
|
||||
description: 'Whether this session is still in the first ranking chain after being submitted.'
|
||||
|
||||
randomSimulationIndex:
|
||||
type: 'number'
|
||||
description: 'A random updated every time the game is randomly simulated for a uniform random distribution of simulations (see #2448).'
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
unsubscribed:
|
||||
type: 'boolean'
|
||||
description: 'Whether the player has opted out of receiving email updates about ladder rankings for this session.'
|
||||
|
|
|
@ -24,9 +24,10 @@ LevelSessionSchema.index({team: 1}, {sparse: true})
|
|||
LevelSessionSchema.index({totalScore: 1}, {sparse: true})
|
||||
LevelSessionSchema.index({user: 1, changed: -1}, {name: 'last played index', sparse: true})
|
||||
LevelSessionSchema.index({'level.original': 1, 'state.topScores.type': 1, 'state.topScores.date': -1, 'state.topScores.score': -1}, {name: 'top scores index', sparse: true})
|
||||
LevelSessionSchema.index({submitted: 1, team: 1, level:1, totalScore: -1}, {name: 'rank counting index', sparse:true})
|
||||
LevelSessionSchema.index({levelID: 1, submitted:1, team: 1},{name:'get all scores index',sparse:true})
|
||||
LevelSessionSchema.index({submitted: 1, team: 1, levelID: 1, submitDate: -1}, {name: 'matchmaking index', sparse:true})
|
||||
LevelSessionSchema.index({submitted: 1, team: 1, level:1, totalScore: -1}, {name: 'rank counting index', sparse: true})
|
||||
LevelSessionSchema.index({levelID: 1, submitted:1, team: 1}, {name: 'get all scores index', sparse: true})
|
||||
LevelSessionSchema.index({submitted: 1, team: 1, levelID: 1, submitDate: -1}, {name: 'matchmaking index', sparse: true})
|
||||
LevelSessionSchema.index({submitted: 1, team: 1, levelID: 1, randomSimulationIndex: -1}, {name: 'matchmaking random index', sparse: true})
|
||||
|
||||
LevelSessionSchema.plugin(plugins.PermissionsPlugin)
|
||||
LevelSessionSchema.plugin(AchievablePlugin)
|
||||
|
|
|
@ -107,10 +107,9 @@ findEarliestSubmission = (queryParams, callback) ->
|
|||
result = earliestSubmissionCache[cacheKey] = earliest?.submitDate
|
||||
callback null, result
|
||||
|
||||
findRandomSession = (queryParams, callback) ->
|
||||
findRecentRandomSession = (queryParams, callback) ->
|
||||
# We pick a random submitDate between the first submit date for the level and now, then do a $lt fetch to find a session to simulate.
|
||||
# We bias it towards recently submitted sessions.
|
||||
queryParams.submitted = true
|
||||
findEarliestSubmission queryParams, (err, startDate) ->
|
||||
return callback err, null unless startDate
|
||||
now = new Date()
|
||||
|
@ -122,6 +121,24 @@ findRandomSession = (queryParams, callback) ->
|
|||
return callback err if err
|
||||
callback null, session
|
||||
|
||||
findRandomSession = (queryParams, callback) ->
|
||||
queryParams.submitted = true
|
||||
favorRecent = queryParams.favorRecent
|
||||
delete queryParams.favorRecent
|
||||
if favorRecent
|
||||
return findRecentRandomSession queryParams, callback
|
||||
queryParams.randomSimulationIndex = $lte: Math.random()
|
||||
selection = 'team totalScore transpiledCode submittedCodeLanguage teamSpells levelID creatorName creator submitDate'
|
||||
sort = randomSimulationIndex: -1
|
||||
console.log 'trying to find one with qparams', queryParams
|
||||
LevelSession.findOne(queryParams).sort(sort).select(selection).lean().exec (err, session) ->
|
||||
return callback err if err
|
||||
return callback null, session if session
|
||||
delete queryParams.randomSimulationIndex # Effectively switch to $gt, if our randomSimulationIndex was lower than the lowest one.
|
||||
LevelSession.findOne(queryParams).sort(sort).select(selection).lean().exec (err, session) ->
|
||||
return callback err if err
|
||||
callback null, session
|
||||
|
||||
formatSessionInformation = (session) ->
|
||||
sessionID: session._id
|
||||
team: session.team ? 'No team'
|
||||
|
@ -142,7 +159,8 @@ module.exports.getTwoGames = (req, res) ->
|
|||
ladderGameIDs = ['dueling-grounds', 'cavern-survival', 'multiplayer-treasure-grove', 'harrowland', 'zero-sum']
|
||||
levelID = _.sample ladderGameIDs
|
||||
unless ogresGameID and humansGameID
|
||||
async.map [{levelID: levelID, team: 'humans'}, {levelID: levelID, team: 'ogres'}], findRandomSession, (err, sessions) ->
|
||||
recentHumans = Math.random() < 0.5 # We pick one session favoring recent submissions, then find another one uniformly to play against
|
||||
async.map [{levelID: levelID, team: 'humans', favorRecent: recentHumans}, {levelID: levelID, team: 'ogres', favorRecent: not recentHumans}], findRandomSession, (err, sessions) ->
|
||||
if err then return errors.serverError(res, "Couldn't get two games to simulate for #{levelID}.")
|
||||
unless sessions.length is 2
|
||||
res.send(204, 'No games to score.')
|
||||
|
@ -252,6 +270,7 @@ updateSessionToSubmit = (transpiledCode, sessionToUpdate, callback) ->
|
|||
numberOfWinsAndTies: 0
|
||||
numberOfLosses: 0
|
||||
isRanking: true
|
||||
randomSimulationIndex: Math.random()
|
||||
LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, (err, result) ->
|
||||
callback err, sessionToUpdate
|
||||
|
||||
|
@ -485,6 +504,7 @@ updateScoreInSession = (scoreObject, callback) ->
|
|||
standardDeviation: scoreObject.standardDeviation
|
||||
totalScore: newTotalScore
|
||||
$push: {scoreHistory: {$each: [scoreHistoryAddition], $slice: -1000}}
|
||||
randomSimulationIndex: Math.random()
|
||||
|
||||
LevelSession.update {'_id': scoreObject.id}, updateObject, callback
|
||||
#log.info "New total score for session #{scoreObject.id} is #{updateObject.totalScore}"
|
||||
|
|
Loading…
Add table
Reference in a new issue