No more transpiledCode

This commit is contained in:
Nick Winter 2016-05-05 13:22:30 -07:00
parent 93f940e196
commit e4c904463c
12 changed files with 38 additions and 74 deletions

View file

@ -90,7 +90,7 @@ module.exports = class God extends CocoClass
return if hadPreloader return if hadPreloader
@angelsShare.workQueue = [] @angelsShare.workQueue = []
work = work =
userCodeMap: userCodeMap userCodeMap: userCodeMap
level: @level level: @level
levelSessionIDs: @levelSessionIDs levelSessionIDs: @levelSessionIDs
@ -106,13 +106,14 @@ module.exports = class God extends CocoClass
@angelsShare.workQueue.push work @angelsShare.workQueue.push work
angel.workIfIdle() for angel in @angelsShare.angels angel.workIfIdle() for angel in @angelsShare.angels
work work
getUserCodeMap: (spells) -> getUserCodeMap: (spells) ->
userCodeMap = {} userCodeMap = {}
for spellKey, spell of spells for spellKey, spell of spells
for thangID, spellThang of spell.thangs for thangID, spellThang of spell.thangs
continue if spellThang.thang?.programmableMethods[spell.name].cloneOf continue if spellThang.thang?.programmableMethods[spell.name].cloneOf
(userCodeMap[thangID] ?= {})[spell.name] = spellThang.aether.serialize() (userCodeMap[thangID] ?= {})[spell.name] = spellThang.aether.serialize()
console.log 'got UCM', userCodeMap
userCodeMap userCodeMap

View file

@ -115,6 +115,7 @@ module.exports = class LevelLoader extends CocoClass
if @sessionID if @sessionID
url = "/db/level.session/#{@sessionID}" url = "/db/level.session/#{@sessionID}"
url += "?interpret=true" if @spectateMode or utils.getQueryVariable 'esper'
else else
url = "/db/level/#{@levelID}/session" url = "/db/level/#{@levelID}/session"
url += "?team=#{@team}" if @team url += "?team=#{@team}" if @team
@ -126,7 +127,7 @@ module.exports = class LevelLoader extends CocoClass
@session = @sessionResource.model @session = @sessionResource.model
if @opponentSessionID if @opponentSessionID
opponentURL = "/db/level.session/#{@opponentSessionID}" opponentURL = "/db/level.session/#{@opponentSessionID}"
opponentURL += "?interpret=true" if utils.getQueryVariable 'esper' opponentURL += "?interpret=true" if @spectateMode or utils.getQueryVariable 'esper'
opponentSession = new LevelSession().setURL opponentURL opponentSession = new LevelSession().setURL opponentURL
opponentSession.project = session.project if @headless opponentSession.project = session.project if @headless
@opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session', {cache: false}) @opponentSessionResource = @supermodel.loadModel(opponentSession, 'opponent_session', {cache: false})

View file

@ -29,7 +29,7 @@ module.exports.createAetherOptions = (options) ->
#functionParameters: # TODOOOOO #functionParameters: # TODOOOOO
executionLimit: 3 * 1000 * 1000 executionLimit: 3 * 1000 * 1000
language: options.codeLanguage language: options.codeLanguage
useInterpreter: !!utils.getQueryVariable('esper') useInterpreter: options.useInterpreter ? !!utils.getQueryVariable('esper')
parameters = functionParameters[options.functionName] parameters = functionParameters[options.functionName]
unless parameters unless parameters
console.warn "Unknown method #{options.functionName}: please add function parameters to lib/aether_utils.coffee." console.warn "Unknown method #{options.functionName}: please add function parameters to lib/aether_utils.coffee."

View file

@ -5,7 +5,7 @@ GoalManager = require 'lib/world/GoalManager'
God = require 'lib/God' God = require 'lib/God'
{createAetherOptions} = require 'lib/aether_utils' {createAetherOptions} = require 'lib/aether_utils'
SIMULATOR_VERSION = 3 SIMULATOR_VERSION = 4
simulatorInfo = {} simulatorInfo = {}
if $.browser if $.browser
@ -435,23 +435,20 @@ module.exports = class Simulator extends CocoClass
generatedSpellKey = [slugifiedThangID,methodName].join '/' generatedSpellKey = [slugifiedThangID,methodName].join '/'
source = @currentUserCodeMap[generatedSpellKey] ? '' source = @currentUserCodeMap[generatedSpellKey] ? ''
aether = @spells[spellKey].thangs[thang.id].aether aether = @spells[spellKey].thangs[thang.id].aether
unless _.contains(@task.spellKeysToTranspile, generatedSpellKey) #unless _.contains(@task.spellKeysToTranspile, generatedSpellKey)
aether.pure = source try
else aether.transpile source
try catch e
aether.transpile source console.log "Couldn't transpile #{spellKey}:\n#{source}\n", e
catch e aether.transpile ''
console.log "Couldn't transpile #{spellKey}:\n#{source}\n", e
aether.transpile ''
createAether: (methodName, method, useProtectAPI, codeLanguage) -> createAether: (methodName, method, useProtectAPI, codeLanguage) ->
aetherOptions = createAetherOptions functionName: methodName, codeLanguage: codeLanguage, skipProtectAPI: not useProtectAPI aetherOptions = createAetherOptions functionName: methodName, codeLanguage: codeLanguage, skipProtectAPI: not useProtectAPI, useInterpreter: true
return new Aether aetherOptions return new Aether aetherOptions
class SimulationTask class SimulationTask
constructor: (@rawData) -> constructor: (@rawData) ->
@spellKeyToTeamMap = {} @spellKeyToTeamMap = {}
@spellKeysToTranspile = []
getLevelName: -> getLevelName: ->
levelName = @rawData.sessions?[0]?.levelID levelName = @rawData.sessions?[0]?.levelID
@ -486,45 +483,23 @@ class SimulationTask
setWorld: (@world) -> setWorld: (@world) ->
generateSpellKeyToSourceMap: -> generateSpellKeyToSourceMap: ->
# TODO: we always now only have hero-placeholder/plan vs. hero-placeholder-1/plan on humans vs. ogres, always just have to retranspile for Esper, and never need to transpile for NPCs or other methods, so we can get rid of almost all of this stuff.
playerTeams = _.pluck @rawData.sessions, 'team' playerTeams = _.pluck @rawData.sessions, 'team'
spellKeyToSourceMap = {} spellKeyToSourceMap = {}
for session in @rawData.sessions for session in @rawData.sessions
teamSpells = session.teamSpells[session.team] teamSpells = session.teamSpells[session.team]
allTeams = _.keys session.teamSpells allTeams = _.keys session.teamSpells
nonPlayerTeams = _.difference allTeams, playerTeams
for team in allTeams for team in allTeams
for spell in session.teamSpells[team] for spell in session.teamSpells[team]
@spellKeyToTeamMap[spell] = team @spellKeyToTeamMap[spell] = team
for nonPlayerTeam in nonPlayerTeams
for spell in session.teamSpells[nonPlayerTeam]
spellKeyToSourceMap[spell] ?= @getWorldProgrammableSource(spell, @world)
@spellKeysToTranspile.push spell
teamCode = {} teamCode = {}
for thangName, thangSpells of session.transpiledCode for thangName, thangSpells of session.submittedCode
for spellName, spell of thangSpells for spellName, spell of thangSpells
fullSpellName = [thangName, spellName].join '/' fullSpellName = [thangName, spellName].join '/'
if _.contains(teamSpells, fullSpellName) if _.contains(teamSpells, fullSpellName)
teamCode[fullSpellName]=spell teamCode[fullSpellName] = LZString.decompressFromUTF16 spell
_.merge spellKeyToSourceMap, teamCode _.merge spellKeyToSourceMap, teamCode
spellKeyToSourceMap spellKeyToSourceMap
getWorldProgrammableSource: (desiredSpellKey ,world) ->
programmableThangs = _.filter world.thangs, 'isProgrammable'
@spells ?= {}
@thangSpells ?= {}
for thang in programmableThangs
continue if @thangSpells[thang.id]?
@thangSpells[thang.id] = []
for methodName, method of thang.programmableMethods
pathComponents = [thang.id, methodName]
if method.cloneOf
pathComponents[0] = method.cloneOf # referencing another Thang's method
pathComponents[0] = _.string.slugify pathComponents[0]
spellKey = pathComponents.join '/'
@thangSpells[thang.id].push spellKey
if not method.cloneOf and spellKey is desiredSpellKey
#console.log "Setting #{desiredSpellKey} from world!"
return method.source

View file

@ -135,8 +135,8 @@ module.exports = class SpectateLevelView extends RootView
continue if spellTeam is myTeam or not myTeam continue if spellTeam is myTeam or not myTeam
opponentSpells = opponentSpells.concat spells opponentSpells = opponentSpells.concat spells
opponentCode = @otherSession?.get('transpiledCode') or {} opponentCode = @otherSession?.get('code') or {}
myCode = @session.get('transpiledCode') or {} myCode = @session.get('code') or {}
for spell in opponentSpells for spell in opponentSpells
[thang, spell] = spell.split '/' [thang, spell] = spell.split '/'
c = opponentCode[thang]?[spell] c = opponentCode[thang]?[spell]

View file

@ -63,13 +63,12 @@ module.exports = class LadderSubmissionView extends CocoView
failure = (jqxhr, textStatus, errorThrown) => failure = (jqxhr, textStatus, errorThrown) =>
console.log jqxhr.responseText console.log jqxhr.responseText
@setRankingButtonText 'failed' unless @destroyed @setRankingButtonText 'failed' unless @destroyed
@transpileSession (transpiledCode) => @session.save null, success: =>
ajaxData = ajaxData =
session: @session.id session: @session.id
levelID: @level.id levelID: @level.id
originalLevelID: @level.get('original') originalLevelID: @level.get('original')
levelMajorVersion: @level.get('version').major levelMajorVersion: @level.get('version').major
transpiledCode: transpiledCode
ajaxOptions = ajaxOptions =
type: 'POST' type: 'POST'
data: ajaxData data: ajaxData
@ -81,35 +80,19 @@ module.exports = class LadderSubmissionView extends CocoView
mirrorAjaxData.session = @mirrorSession.id mirrorAjaxData.session = @mirrorSession.id
mirrorCode = @mirrorSession.get('code') mirrorCode = @mirrorSession.get('code')
if @session.get('team') is 'humans' if @session.get('team') is 'humans'
mirrorAjaxData.transpiledCode = 'hero-placeholder-1': transpiledCode['hero-placeholder']
mirrorCode['hero-placeholder-1'] = @session.get('code')['hero-placeholder'] mirrorCode['hero-placeholder-1'] = @session.get('code')['hero-placeholder']
else else
mirrorAjaxData.transpiledCode = 'hero-placeholder': transpiledCode['hero-placeholder-1']
mirrorCode['hero-placeholder'] = @session.get('code')['hero-placeholder-1'] mirrorCode['hero-placeholder'] = @session.get('code')['hero-placeholder-1']
mirrorAjaxOptions = _.clone ajaxOptions mirrorAjaxOptions = _.clone ajaxOptions
mirrorAjaxOptions.data = mirrorAjaxData mirrorAjaxOptions.data = mirrorAjaxData
ajaxOptions.success = => ajaxOptions.success = =>
patch = code: mirrorCode, codeLanguage: @session.get('codeLanguage'), submittedCodeLanguage: @session.get('submittedCodeLanguage') patch = code: mirrorCode, codeLanguage: @session.get('codeLanguage')
tempSession = new LevelSession _id: @mirrorSession.id tempSession = new LevelSession _id: @mirrorSession.id
tempSession.save patch, patch: true, type: 'PUT', success: -> tempSession.save patch, patch: true, type: 'PUT', success: ->
$.ajax '/queue/scoring', mirrorAjaxOptions $.ajax '/queue/scoring', mirrorAjaxOptions
$.ajax '/queue/scoring', ajaxOptions $.ajax '/queue/scoring', ajaxOptions
transpileSession: (callback) ->
submittedCode = @session.get('code')
codeLanguage = @session.get('codeLanguage') or 'javascript'
@session.set('submittedCodeLanguage', codeLanguage)
transpiledCode = {}
for thang, spells of submittedCode
transpiledCode[thang] = {}
for spellID, spell of spells
unless _.contains(@session.get('teamSpells')[@session.get('team')], thang + '/' + spellID) then continue
aetherOptions = createAetherOptions functionName: spellID, codeLanguage: codeLanguage
aether = new Aether aetherOptions
transpiledCode[thang][spellID] = aether.transpile spell
@session.save null, success: -> callback transpiledCode
onHelpSimulate: -> onHelpSimulate: ->
@playSound 'menu-button-click' @playSound 'menu-button-click'
$('a[href="#simulate"]').tab('show') $('a[href="#simulate"]').tab('show')

View file

@ -182,6 +182,7 @@ module.exports = class Spell
skipProtectAPI: skipProtectAPI skipProtectAPI: skipProtectAPI
includeFlow: includeFlow includeFlow: includeFlow
problemContext: problemContext problemContext: problemContext
useInterpreter: if @spectateView then true else undefined
aether = new Aether aetherOptions aether = new Aether aetherOptions
if @worker if @worker
workerMessage = workerMessage =
@ -215,8 +216,7 @@ module.exports = class Spell
shouldUseTranspiledCode: -> shouldUseTranspiledCode: ->
# Determine whether this code has already been transpiled, or whether it's raw source needing transpilation. # Determine whether this code has already been transpiled, or whether it's raw source needing transpilation.
return false if utils.getQueryVariable 'esper' # Don't use transpiled code with interpreter return false if @spectateView or utils.getQueryVariable 'esper' # Don't use transpiled code with interpreter
return true if @spectateView # Use transpiled code for both teams if we're just spectating.
return true if @isEnemySpell() # Use transpiled for enemy spells. return true if @isEnemySpell() # Use transpiled for enemy spells.
# Players without permissions can't view the raw code. # Players without permissions can't view the raw code.
return false if @observing and @levelType in ['hero', 'course'] return false if @observing and @levelType in ['hero', 'course']

View file

@ -9,7 +9,6 @@ module.exports = createNewTask = (req, res) ->
requestSessionID = req.body.session requestSessionID = req.body.session
originalLevelID = req.body.originalLevelID originalLevelID = req.body.originalLevelID
currentLevelID = req.body.levelID currentLevelID = req.body.levelID
transpiledCode = req.body.transpiledCode
requestLevelMajorVersion = parseInt(req.body.levelMajorVersion) requestLevelMajorVersion = parseInt(req.body.levelMajorVersion)
yetiGuru = {} yetiGuru = {}
@ -17,7 +16,7 @@ module.exports = createNewTask = (req, res) ->
validatePermissions.bind(yetiGuru, req, requestSessionID) validatePermissions.bind(yetiGuru, req, requestSessionID)
fetchAndVerifyLevelType.bind(yetiGuru, currentLevelID) fetchAndVerifyLevelType.bind(yetiGuru, currentLevelID)
fetchSessionObjectToSubmit.bind(yetiGuru, requestSessionID) fetchSessionObjectToSubmit.bind(yetiGuru, requestSessionID)
updateSessionToSubmit.bind(yetiGuru, transpiledCode, req.user) updateSessionToSubmit.bind(yetiGuru, req.user)
# Because there's some bug where the chained rankings don't work, and this is super slow, let's just not do this until we fix it. # Because there's some bug where the chained rankings don't work, and this is super slow, let's just not do this until we fix it.
#fetchInitialSessionsToRankAgainst.bind(yetiGuru, requestLevelMajorVersion, originalLevelID) #fetchInitialSessionsToRankAgainst.bind(yetiGuru, requestLevelMajorVersion, originalLevelID)
#generateAndSendTaskPairsToTheQueue #generateAndSendTaskPairsToTheQueue
@ -49,14 +48,14 @@ fetchAndVerifyLevelType = (levelID, cb) ->
cb null cb null
fetchSessionObjectToSubmit = (sessionID, callback) -> fetchSessionObjectToSubmit = (sessionID, callback) ->
LevelSession.findOne({_id: sessionID}).select('team code leagues').exec (err, session) -> LevelSession.findOne({_id: sessionID}).select('team code leagues codeLanguage').exec (err, session) ->
callback err, session?.toObject() callback err, session?.toObject()
updateSessionToSubmit = (transpiledCode, user, sessionToUpdate, callback) -> updateSessionToSubmit = (user, sessionToUpdate, callback) ->
sessionUpdateObject = sessionUpdateObject =
submitted: true submitted: true
submittedCode: sessionToUpdate.code submittedCode: sessionToUpdate.code
transpiledCode: transpiledCode submittedCodeLanguage: sessionToUpdate.codeLanguage or 'python'
submitDate: new Date() submitDate: new Date()
#meanStrength: 25 # Let's try not resetting the score on resubmission #meanStrength: 25 # Let's try not resetting the score on resubmission
standardDeviation: 25 / 3 standardDeviation: 25 / 3

View file

@ -57,10 +57,10 @@ constructTaskObject = (taskMessageBody, message, callback) ->
callback null, taskObject, message callback null, taskObject, message
getSessionInformation = (sessionIDString, callback) -> getSessionInformation = (sessionIDString, callback) ->
selectString = 'submitDate team submittedCode teamSpells levelID creator creatorName transpiledCode submittedCodeLanguage totalScore' selectString = 'submitDate team submittedCode teamSpells levelID creator creatorName submittedCodeLanguage totalScore'
LevelSession.findOne(_id: sessionIDString).select(selectString).lean().exec (err, session) -> LevelSession.findOne(_id: sessionIDString).select(selectString).lean().exec (err, session) ->
if err? then return callback err, {'error': 'There was an error retrieving the session.'} if err? then return callback err, {'error': 'There was an error retrieving the session.'}
callback null, session callback null, scoringUtils.formatSessionInformation session
constructTaskLogObject = (calculatorUserID, taskObject, message, callback) -> constructTaskLogObject = (calculatorUserID, taskObject, message, callback) ->
taskLogObject = new TaskLog taskLogObject = new TaskLog

View file

@ -21,7 +21,7 @@ module.exports = getTwoGames = (req, res) ->
leagueID: req.body.leagueID leagueID: req.body.leagueID
getRandomSessions req.user, options, sendSessionsResponse(res) getRandomSessions req.user, options, sendSessionsResponse(res)
sessionSelectionString = 'team totalScore transpiledCode submittedCodeLanguage teamSpells levelID creatorName creator submitDate leagues' sessionSelectionString = 'team totalScore submittedCode submittedCodeLanguage teamSpells levelID creatorName creator submitDate leagues'
sendSessionsResponse = (res) -> sendSessionsResponse = (res) ->
(err, sessions) -> (err, sessions) ->

View file

@ -89,7 +89,7 @@ logTaskComputation = (callback) ->
callback err callback err
determineIfSessionShouldContinueAndUpdateLog = (cb) -> determineIfSessionShouldContinueAndUpdateLog = (cb) ->
sessionID = @clientResponseObject.originalSessionID sessionID = @clientResponseObject.originalSessionIDx
sessionRank = parseInt @clientResponseObject.originalSessionRank sessionRank = parseInt @clientResponseObject.originalSessionRank
update = '$inc': {} update = '$inc': {}
if sessionRank is 0 if sessionRank is 0

View file

@ -4,6 +4,7 @@ bayes = new (require 'bayesian-battle')()
LevelSession = require '../../models/LevelSession' LevelSession = require '../../models/LevelSession'
User = require '../../models/User' User = require '../../models/User'
perfmon = require '../../commons/perfmon' perfmon = require '../../commons/perfmon'
LZString = require 'lz-string'
SIMULATOR_VERSION = 3 SIMULATOR_VERSION = 3
@ -26,11 +27,15 @@ module.exports.sendResponseObject = (res, object) ->
res.send(object) res.send(object)
res.end() res.end()
module.exports.formatSessionInformation = (session) -> module.exports.formatSessionInformation = (session) ->
heroID = if session.team is 'ogres' then 'hero-placeholder-1' else 'hero-placeholder'
submittedCode = {}
submittedCode[heroID] = plan: LZString.compressToUTF16 session.submittedCode[heroID].plan
_id: session._id
sessionID: session._id sessionID: session._id
team: session.team ? 'No team' team: session.team ? 'No team'
transpiledCode: session.transpiledCode submittedCode: submittedCode
submittedCodeLanguage: session.submittedCodeLanguage submittedCodeLanguage: session.submittedCodeLanguage
teamSpells: session.teamSpells ? {} teamSpells: session.teamSpells ? {}
levelID: session.levelID levelID: session.levelID