mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-13 22:49:51 -04:00
Keeping old matches, up to 200, and showing them as stale. Added LevelSession.isRanking for better display of when you're still in the initial ranking phase.
This commit is contained in:
parent
852b1c97ac
commit
392534878a
5 changed files with 63 additions and 38 deletions
|
@ -18,5 +18,13 @@
|
|||
white-space: nowrap
|
||||
overflow: hidden
|
||||
|
||||
tr.stale
|
||||
opacity: 0.5
|
||||
|
||||
tr.win .state-cell
|
||||
color: #172
|
||||
tr.loss .state-cell
|
||||
color: #712
|
||||
|
||||
#must-log-in button
|
||||
margin-right: 10px
|
||||
margin-right: 10px
|
||||
|
|
|
@ -17,9 +17,10 @@ div#columns.row
|
|||
button.btn.btn-sm.btn-warning.pull-right.rank-button(data-session-id=team.session.id)
|
||||
span.unavailable.hidden No New Code to Rank
|
||||
span.rank.hidden Rank My Game!
|
||||
span.ranking.hidden Submitting...
|
||||
span.ranked.hidden Submitted for Ranking
|
||||
span.submitting.hidden Submitting...
|
||||
span.submitted.hidden Submitted for Ranking
|
||||
span.failed.hidden Failed to Rank
|
||||
span.ranking.hidden Game Being Ranked
|
||||
|
||||
if team.chartData
|
||||
tr
|
||||
|
@ -32,7 +33,7 @@ div#columns.row
|
|||
th When
|
||||
th
|
||||
for match in team.matches
|
||||
tr
|
||||
tr(class=(match.stale ? "stale " : "") + match.state)
|
||||
td.state-cell
|
||||
if match.state === 'win'
|
||||
span.win Win
|
||||
|
@ -48,7 +49,11 @@ div#columns.row
|
|||
|
||||
if !team.matches.length
|
||||
tr
|
||||
td(colspan=4).alert.alert-warning
|
||||
| No ranked matches for this team!
|
||||
| Play against some competitors and then come back here to get your game ranked.
|
||||
if team.isRanking
|
||||
td(colspan=4).alert.alert-info
|
||||
| Your new code is being simulated by other players for ranking.
|
||||
else
|
||||
td(colspan=4).alert.alert-warning
|
||||
| No ranked matches for this team!
|
||||
| Play against some competitors and then come back here to get your game ranked.
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
ctx.levelID = @level.get('slug') or @level.id
|
||||
ctx.teams = @teams
|
||||
|
||||
convertMatch = (match) =>
|
||||
convertMatch = (match, submitDate) =>
|
||||
opponent = match.opponents[0]
|
||||
state = 'win'
|
||||
state = 'loss' if match.metrics.rank > opponent.metrics.rank
|
||||
|
@ -65,12 +65,14 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
opponentID: opponent.userID
|
||||
when: moment(match.date).fromNow()
|
||||
sessionID: opponent.sessionID
|
||||
stale: match.date < submitDate
|
||||
}
|
||||
|
||||
for team in @teams
|
||||
team.session = (s for s in @sessions.models when s.get('team') is team.id)[0]
|
||||
team.readyToRank = @readyToRank(team.session)
|
||||
team.matches = (convertMatch(match) for match in team.session?.get('matches') or [])
|
||||
team.isRanking = team.session.get('isRanking')
|
||||
team.matches = (convertMatch(match, team.session.get('submitDate')) for match in team.session?.get('matches') or [])
|
||||
team.matches.reverse()
|
||||
team.score = (team.session?.get('totalScore') or 10).toFixed(2)
|
||||
team.wins = _.filter(team.matches, {state: 'win'}).length
|
||||
|
@ -96,7 +98,12 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
button = $(el)
|
||||
sessionID = button.data('session-id')
|
||||
session = _.find @sessions.models, { id: sessionID }
|
||||
@setRankingButtonText button, if @readyToRank(session) then 'rank' else 'unavailable'
|
||||
rankingState = 'unavailable'
|
||||
if @readyToRank session
|
||||
rankingState = 'rank'
|
||||
else if session.get 'isRanking'
|
||||
rankingState = 'ranking'
|
||||
@setRankingButtonText button, rankingState
|
||||
|
||||
readyToRank: (session) ->
|
||||
return false unless session?.get('levelID') # If it hasn't been denormalized, then it's not ready.
|
||||
|
@ -110,8 +117,8 @@ module.exports = class MyMatchesTabView extends CocoView
|
|||
session = _.find @sessions.models, { id: sessionID }
|
||||
return unless @readyToRank(session)
|
||||
|
||||
@setRankingButtonText(button, 'ranking')
|
||||
success = => @setRankingButtonText(button, 'ranked')
|
||||
@setRankingButtonText(button, 'submitting')
|
||||
success = => @setRankingButtonText(button, 'submitted')
|
||||
failure = => @setRankingButtonText(button, 'failed')
|
||||
|
||||
ajaxData = { session: sessionID, levelID: @level.id, originalLevelID: @level.attributes.original, levelMajorVersion: @level.attributes.version.major }
|
||||
|
|
|
@ -140,6 +140,10 @@ _.extend LevelSessionSchema.properties,
|
|||
submittedCode:
|
||||
type: 'object'
|
||||
|
||||
isRanking:
|
||||
type: 'boolean'
|
||||
description: 'Whether this session is still in the first ranking chain after being submitted.'
|
||||
|
||||
unsubscribed:
|
||||
type: 'boolean'
|
||||
description: 'Whether the player has opted out of receiving email updates about ladder rankings for this session.'
|
||||
|
@ -147,6 +151,7 @@ _.extend LevelSessionSchema.properties,
|
|||
numberOfWinsAndTies:
|
||||
type: 'number'
|
||||
default: 0
|
||||
|
||||
numberOfLosses:
|
||||
type: 'number'
|
||||
default: 0
|
||||
|
@ -162,7 +167,6 @@ _.extend LevelSessionSchema.properties,
|
|||
items:
|
||||
type: 'number'
|
||||
|
||||
|
||||
matches:
|
||||
type: 'array'
|
||||
title: 'Matches'
|
||||
|
|
|
@ -52,7 +52,7 @@ module.exports.createNewTask = (req, res) ->
|
|||
requestLevelID = req.body.originalLevelID
|
||||
requestCurrentLevelID = req.body.levelID
|
||||
requestLevelMajorVersion = parseInt(req.body.levelMajorVersion)
|
||||
|
||||
|
||||
validatePermissions req, requestSessionID, (error, permissionsAreValid) ->
|
||||
if err? then return errors.serverError res, "There was an error validating permissions"
|
||||
unless permissionsAreValid then return errors.forbidden res, "You do not have the permissions to submit that game to the leaderboard"
|
||||
|
@ -60,24 +60,24 @@ module.exports.createNewTask = (req, res) ->
|
|||
return errors.badInput res, "The session ID is invalid" unless typeof requestSessionID is "string"
|
||||
Level.findOne({_id: requestCurrentLevelID}).lean().select('type').exec (err, levelWithType) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the level type"
|
||||
|
||||
if not levelWithType.type or levelWithType.type isnt "ladder"
|
||||
|
||||
if not levelWithType.type or levelWithType.type isnt "ladder"
|
||||
console.log "The level type of level with ID #{requestLevelID} is #{levelWithType.type}"
|
||||
return errors.badInput res, "That level isn't a ladder level"
|
||||
|
||||
|
||||
fetchSessionToSubmit requestSessionID, (err, sessionToSubmit) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the given session."
|
||||
|
||||
|
||||
updateSessionToSubmit sessionToSubmit, (err, data) ->
|
||||
if err? then return errors.serverError res, "There was an error updating the session"
|
||||
opposingTeam = calculateOpposingTeam(sessionToSubmit.team)
|
||||
fetchInitialSessionsToRankAgainst opposingTeam,requestLevelID, requestLevelMajorVersion, (err, sessionsToRankAgainst) ->
|
||||
if err? then return errors.serverError res, "There was an error fetching the sessions to rank against"
|
||||
|
||||
|
||||
taskPairs = generateTaskPairs(sessionsToRankAgainst, sessionToSubmit)
|
||||
sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
|
||||
if taskPairError? then return errors.serverError res, "There was an error sending the task pairs to the queue"
|
||||
|
||||
|
||||
sendResponseObject req, res, {"message":"All task pairs were succesfully sent to the queue"}
|
||||
|
||||
module.exports.dispatchTaskToConsumer = (req, res) ->
|
||||
|
@ -118,51 +118,53 @@ module.exports.processTaskResult = (req, res) ->
|
|||
scoringTaskQueue.deleteMessage clientResponseObject.receiptHandle, (err) ->
|
||||
console.log "Deleted message."
|
||||
if err? then return errors.badInput res, "The queue message is already back in the queue, rejecting results."
|
||||
|
||||
|
||||
LevelSession.findOne(_id: clientResponseObject.originalSessionID).lean().exec (err, levelSession) ->
|
||||
if err? then return errors.serverError res, "There was a problem finding the level session:#{err}"
|
||||
|
||||
|
||||
supposedSubmissionDate = new Date(clientResponseObject.sessions[0].submitDate)
|
||||
|
||||
|
||||
if Number(supposedSubmissionDate) isnt Number(levelSession.submitDate)
|
||||
return sendResponseObject req, res, {"message":"The game has been resubmitted. Removing from queue..."}
|
||||
|
||||
|
||||
logTaskComputation clientResponseObject, taskLog, (logErr) ->
|
||||
if logErr? then return errors.serverError res, "There as a problem logging the task computation: #{logErr}"
|
||||
|
||||
|
||||
updateSessions clientResponseObject, (updateError, newScoreArray) ->
|
||||
if updateError? then return errors.serverError res, "There was an error updating the scores.#{updateError}"
|
||||
|
||||
|
||||
newScoresObject = _.indexBy newScoreArray, 'id'
|
||||
|
||||
|
||||
addMatchToSessions clientResponseObject, newScoresObject, (err, data) ->
|
||||
if err? then return errors.serverError res, "There was an error updating the sessions with the match! #{JSON.stringify err}"
|
||||
|
||||
|
||||
originalSessionID = clientResponseObject.originalSessionID
|
||||
originalSessionTeam = clientResponseObject.originalSessionTeam
|
||||
originalSessionRank = parseInt clientResponseObject.originalSessionRank
|
||||
|
||||
|
||||
determineIfSessionShouldContinueAndUpdateLog originalSessionID, originalSessionRank, (err, sessionShouldContinue) ->
|
||||
if err? then return errors.serverError res, "There was an error determining if the session should continue, #{err}"
|
||||
|
||||
|
||||
if sessionShouldContinue
|
||||
opposingTeam = calculateOpposingTeam(originalSessionTeam)
|
||||
opponentID = _.pull(_.keys(newScoresObject), originalSessionID)
|
||||
sessionNewScore = newScoresObject[originalSessionID].totalScore
|
||||
opponentNewScore = newScoresObject[opponentID].totalScore
|
||||
|
||||
|
||||
levelOriginalID = levelSession.level.original
|
||||
levelOriginalMajorVersion = levelSession.level.majorVersion
|
||||
findNearestBetterSessionID levelOriginalID, levelOriginalMajorVersion, originalSessionID, sessionNewScore, opponentNewScore, opponentID ,opposingTeam, (err, opponentSessionID) ->
|
||||
if err? then return errors.serverError res, "There was an error finding the nearest sessionID!"
|
||||
unless opponentSessionID then return sendResponseObject req, res, {"message":"There were no more games to rank(game is at top!"}
|
||||
|
||||
|
||||
addPairwiseTaskToQueue [originalSessionID, opponentSessionID], (err, success) ->
|
||||
if err? then return errors.serverError res, "There was an error sending the pairwise tasks to the queue!"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
|
||||
else
|
||||
console.log "Player lost, achieved rank #{originalSessionRank}"
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
|
||||
LevelSession.update {_id: originalSessionID}, {isRanking: false}, {multi: false}, (err, affected) ->
|
||||
if err? then return errors.serverError res, "There was an error marking the completed session as not being ranked."
|
||||
sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
|
||||
|
||||
|
||||
determineIfSessionShouldContinueAndUpdateLog = (sessionID, sessionRank, cb) ->
|
||||
|
@ -285,7 +287,7 @@ updateMatchesInSession = (matchObject, sessionID, callback) ->
|
|||
currentMatchObject.opponents = opponentsArray
|
||||
|
||||
sessionUpdateObject =
|
||||
$push: {matches: currentMatchObject}
|
||||
$push: {matches: {$each: [currentMatchObject], $slice: -200}}
|
||||
log.info "Updating session #{sessionID}"
|
||||
LevelSession.update {"_id":sessionID}, sessionUpdateObject, callback
|
||||
|
||||
|
@ -304,12 +306,12 @@ updateSessionToSubmit = (sessionToUpdate, callback) ->
|
|||
submitted: true
|
||||
submittedCode: sessionToUpdate.code
|
||||
submitDate: new Date()
|
||||
matches: []
|
||||
meanStrength: 25
|
||||
standardDeviation: 25/3
|
||||
totalScore: 10
|
||||
numberOfWinsAndTies: 0
|
||||
numberOfLosses: 0
|
||||
isRanking: true
|
||||
LevelSession.update {_id: sessionToUpdate._id}, sessionUpdateObject, callback
|
||||
|
||||
fetchInitialSessionsToRankAgainst = (opposingTeam, levelID, levelMajorVersion, callback) ->
|
||||
|
@ -321,7 +323,7 @@ fetchInitialSessionsToRankAgainst = (opposingTeam, levelID, levelMajorVersion, c
|
|||
submittedCode:
|
||||
$exists: true
|
||||
team: opposingTeam
|
||||
|
||||
|
||||
sortParameters =
|
||||
totalScore: 1
|
||||
|
||||
|
@ -449,8 +451,7 @@ updateScoreInSession = (scoreObject,callback) ->
|
|||
meanStrength: scoreObject.meanStrength
|
||||
standardDeviation: scoreObject.standardDeviation
|
||||
totalScore: newTotalScore
|
||||
$push:
|
||||
scoreHistory: scoreHistoryAddition
|
||||
$push: {scoreHistory: {$each: [scoreHistoryAddition], $slice: -1000}}
|
||||
|
||||
LevelSession.update {"_id": scoreObject.id}, updateObject, callback
|
||||
log.info "New total score for session #{scoreObject.id} is #{updateObject.totalScore}"
|
||||
|
|
Loading…
Reference in a new issue