2016-04-04 14:03:07 -04:00
|
|
|
RootView = require 'views/core/RootView'
|
2016-05-10 17:34:17 -04:00
|
|
|
template = require 'templates/artisans/solution-problems-view'
|
2016-05-13 18:32:59 -04:00
|
|
|
|
2016-04-04 14:03:07 -04:00
|
|
|
Level = require 'models/Level'
|
|
|
|
Campaign = require 'models/Campaign'
|
2016-05-13 18:32:59 -04:00
|
|
|
|
2016-04-04 14:03:07 -04:00
|
|
|
CocoCollection = require 'collections/CocoCollection'
|
2016-05-13 18:32:59 -04:00
|
|
|
Campaigns = require 'collections/Campaigns'
|
|
|
|
Levels = require 'collections/Levels'
|
2016-04-04 14:03:07 -04:00
|
|
|
|
2016-04-21 12:17:54 -04:00
|
|
|
module.exports = class SolutionProblemsView extends RootView
|
2016-04-04 14:03:07 -04:00
|
|
|
template: template
|
2016-04-21 12:17:54 -04:00
|
|
|
id: 'solution-problems-view'
|
2016-04-07 17:48:40 -04:00
|
|
|
excludedCampaigns = [
|
2016-05-13 18:32:59 -04:00
|
|
|
# Misc. campaigns
|
|
|
|
'picoctf', 'auditions'
|
|
|
|
|
|
|
|
# Campaign-version campaigns
|
2016-05-18 17:53:34 -04:00
|
|
|
#'dungeon', 'forest', 'desert', 'mountain', 'glacier'
|
2016-05-13 18:32:59 -04:00
|
|
|
|
|
|
|
# Test campaigns
|
|
|
|
'dungeon-branching-test', 'forest-branching-test', 'desert-branching-test'
|
|
|
|
|
|
|
|
# Course-version campaigns
|
|
|
|
#'intro', 'course-2', 'course-3', 'course-4', 'course-5', 'course-6'
|
2016-04-20 14:15:26 -04:00
|
|
|
]
|
|
|
|
excludedSimulationLevels = [
|
2016-04-29 18:58:30 -04:00
|
|
|
# Course Arenas
|
2016-05-13 18:32:59 -04:00
|
|
|
'wakka-maul', 'cross-bones'
|
2016-04-07 17:48:40 -04:00
|
|
|
]
|
2016-04-29 18:58:30 -04:00
|
|
|
excludedSolutionLevels = [
|
|
|
|
# Multiplayer Levels
|
2016-05-13 18:32:59 -04:00
|
|
|
'cavern-survival'
|
|
|
|
'dueling-grounds', 'multiplayer-treasure-grove'
|
|
|
|
'harrowland'
|
|
|
|
'zero-sum'
|
|
|
|
'ace-of-coders', 'capture-their-flag'
|
|
|
|
]
|
|
|
|
simulationRequirements = [
|
|
|
|
'seed'
|
|
|
|
'succeeds'
|
|
|
|
'heroConfig'
|
|
|
|
'frameCount'
|
|
|
|
'goals'
|
|
|
|
]
|
|
|
|
includedLanguages = [
|
|
|
|
'python', 'javascript', 'java', 'lua', 'coffeescript'
|
2016-04-29 18:58:30 -04:00
|
|
|
]
|
2016-05-13 18:32:59 -04:00
|
|
|
# TODO: Phase the following out:
|
|
|
|
excludedLanguages = [
|
2016-05-16 14:45:06 -04:00
|
|
|
'java', 'lua', 'coffeescript'
|
2016-05-13 18:32:59 -04:00
|
|
|
]
|
2016-05-16 14:45:06 -04:00
|
|
|
excludedLevelSnippets = [
|
|
|
|
'treasure', 'brawl', 'siege'
|
|
|
|
]
|
|
|
|
|
2016-05-13 18:32:59 -04:00
|
|
|
unloadedCampaigns: 0
|
|
|
|
campaignLevels: {}
|
|
|
|
loadedLevels: {}
|
|
|
|
parsedLevels: []
|
|
|
|
problemCount: 0
|
|
|
|
|
|
|
|
initialize: ->
|
|
|
|
@campaigns = new Campaigns([])
|
2016-04-04 14:03:07 -04:00
|
|
|
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
|
2016-05-13 18:32:59 -04:00
|
|
|
@supermodel.trackRequest(@campaigns.fetch(
|
|
|
|
data:
|
|
|
|
project:'slug'
|
|
|
|
))
|
2016-04-08 18:50:04 -04:00
|
|
|
|
2016-05-13 18:32:59 -04:00
|
|
|
onCampaignsLoaded: (campCollection) ->
|
|
|
|
for campaign in campCollection.models
|
|
|
|
campaignSlug = campaign.get('slug')
|
|
|
|
continue if campaignSlug in excludedCampaigns
|
|
|
|
@unloadedCampaigns++
|
|
|
|
|
|
|
|
@campaignLevels[campaignSlug] = new Levels()
|
|
|
|
@listenTo(@campaignLevels[campaignSlug], 'sync', @onLevelsLoaded)
|
|
|
|
@supermodel.trackRequest(@campaignLevels[campaignSlug].fetchForCampaign(campaignSlug,
|
|
|
|
data:
|
|
|
|
project: 'thangs,name,slug,campaign'
|
|
|
|
))
|
|
|
|
|
|
|
|
onLevelsLoaded: (lvlCollection) ->
|
|
|
|
for level in lvlCollection.models
|
|
|
|
@loadedLevels[level.get('slug')] = level
|
|
|
|
if --@unloadedCampaigns is 0
|
|
|
|
@onAllLevelsLoaded()
|
|
|
|
|
|
|
|
onAllLevelsLoaded: ->
|
2016-04-21 12:17:54 -04:00
|
|
|
for levelSlug, level of @loadedLevels
|
2016-04-07 17:48:40 -04:00
|
|
|
unless level?
|
2016-05-13 18:32:59 -04:00
|
|
|
console.error 'Level Slug doesn\'t have associated Level', levelSlug
|
2016-04-07 17:48:40 -04:00
|
|
|
continue
|
2016-05-13 18:32:59 -04:00
|
|
|
continue if levelSlug in excludedSolutionLevels
|
2016-05-16 14:45:06 -04:00
|
|
|
isBad = false
|
|
|
|
for word in excludedLevelSnippets
|
|
|
|
if levelSlug.indexOf(word) isnt -1
|
|
|
|
isBad = true
|
|
|
|
continue if isBad
|
2016-05-13 18:32:59 -04:00
|
|
|
thangs = level.get 'thangs'
|
2016-04-08 18:50:04 -04:00
|
|
|
component = null
|
2016-04-29 18:58:30 -04:00
|
|
|
thangs = _.filter(thangs, (elem) ->
|
|
|
|
return _.findWhere(elem.components, (elem2) ->
|
|
|
|
if elem2.config?.programmableMethods?
|
2016-05-13 18:32:59 -04:00
|
|
|
component = elem2
|
2016-04-29 18:58:30 -04:00
|
|
|
return true
|
|
|
|
)
|
|
|
|
)
|
2016-05-13 18:32:59 -04:00
|
|
|
|
2016-04-29 18:58:30 -04:00
|
|
|
if thangs.length > 1
|
2016-05-13 18:32:59 -04:00
|
|
|
unless levelSlug in excludedSimulationLevels
|
|
|
|
console.warn 'Level has more than 1 programmableMethod Thangs', levelSlug
|
2016-04-08 18:50:04 -04:00
|
|
|
continue
|
2016-05-13 18:32:59 -04:00
|
|
|
unless component?
|
|
|
|
console.error 'Level doesn\'t have programmableMethod Thang', levelSlug
|
2016-04-08 18:50:04 -04:00
|
|
|
continue
|
|
|
|
|
2016-05-13 18:32:59 -04:00
|
|
|
plan = component.config.programmableMethods.plan
|
|
|
|
solutions = plan.solutions or []
|
2016-04-08 18:50:04 -04:00
|
|
|
problems = []
|
2016-05-13 18:32:59 -04:00
|
|
|
problems = problems.concat(@findMissingSolutions solutions)
|
|
|
|
unless levelSlug in excludedSimulationLevels
|
|
|
|
for solution in solutions
|
|
|
|
problems = problems.concat(@findSimulationProblems solution)
|
|
|
|
problems = problems.concat(@findPass solution)
|
|
|
|
problems = problems.concat(@findIdenticalToSource solution, plan)
|
|
|
|
@problemCount += problems.length
|
|
|
|
@parsedLevels.push
|
2016-04-08 18:50:04 -04:00
|
|
|
level: level
|
|
|
|
problems: problems
|
2016-05-13 18:32:59 -04:00
|
|
|
|
2016-05-18 16:33:02 -04:00
|
|
|
@renderSelectors '#level-table'
|
2016-05-13 18:32:59 -04:00
|
|
|
|
|
|
|
findMissingSolutions: (solutions) ->
|
|
|
|
problems = []
|
|
|
|
for lang in includedLanguages
|
|
|
|
if _.findWhere(solutions, (elem) -> return elem.language is lang)
|
|
|
|
# TODO: Phase the following out:
|
|
|
|
else if lang not in excludedLanguages
|
|
|
|
problems.push
|
|
|
|
type: 'Missing solution language'
|
|
|
|
value: lang
|
|
|
|
problems
|
|
|
|
|
|
|
|
findSimulationProblems: (solution) ->
|
|
|
|
problems = []
|
|
|
|
for req in simulationRequirements
|
|
|
|
unless solution[req]?
|
|
|
|
problems.push
|
|
|
|
type: 'Solution is not simulatable'
|
|
|
|
value: solution.language
|
|
|
|
break
|
|
|
|
problems
|
|
|
|
|
|
|
|
findPass: (solution) ->
|
|
|
|
problems = []
|
|
|
|
if solution.source.search(/pass\n/) isnt -1
|
|
|
|
problems.push
|
|
|
|
type: 'Solution contains pass'
|
|
|
|
value: solution.language
|
|
|
|
problems
|
|
|
|
|
|
|
|
findIdenticalToSource: (solution, plan) ->
|
|
|
|
problems = []
|
|
|
|
source = if solution.lang is 'javascript' then plan.source else plan.languages[solution.language]
|
|
|
|
if solution.source is source
|
|
|
|
problems.push
|
|
|
|
type: 'Solution matches sample code'
|
|
|
|
value: solution.language
|
|
|
|
problems
|