mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 09:35:39 -05:00
Add concept map view to artisans.
This commit is contained in:
parent
fd17793819
commit
75e3c54d54
4 changed files with 193 additions and 1 deletions
|
@ -51,6 +51,7 @@ module.exports = class CocoRouter extends Backbone.Router
|
|||
'artisans/level-tasks': go('artisans/LevelTasksView')
|
||||
'artisans/solution-problems': go('artisans/SolutionProblemsView')
|
||||
'artisans/thang-tasks': go('artisans/ThangTasksView')
|
||||
'artisans/level-concepts': go('artisans/LevelConceptMap')
|
||||
|
||||
'beta': go('HomeView')
|
||||
|
||||
|
|
|
@ -10,4 +10,7 @@ block content
|
|||
|Level Tasks
|
||||
div
|
||||
a(href="/artisans/solution-problems")
|
||||
|Solution Problems
|
||||
|Solution Problems
|
||||
div
|
||||
a(href="/artisans/level-concepts")
|
||||
|Level Concept Map
|
20
app/templates/artisans/concept-map-view.jade
Normal file
20
app/templates/artisans/concept-map-view.jade
Normal file
|
@ -0,0 +1,20 @@
|
|||
// DNT
|
||||
extends /templates/base
|
||||
|
||||
block content
|
||||
#solution-problems-view
|
||||
div
|
||||
a(href='/artisans')
|
||||
span.glyphicon.glyphicon-chevron-left
|
||||
span Artisans Home
|
||||
br
|
||||
table.table.table-striped#level-table
|
||||
tr
|
||||
th Level Name
|
||||
th Concepts Detected
|
||||
for level in (view.parsedLevels || [])
|
||||
tr
|
||||
td(style="width:10%")= level.level.get('name')
|
||||
td
|
||||
for tag in (level.tags || [])
|
||||
span.label.label-primary(style='margin-right: 10px; float: left; line-height: 20px; margin-bottom: 10px')= tag
|
168
app/views/artisans/LevelConceptMap.coffee
Normal file
168
app/views/artisans/LevelConceptMap.coffee
Normal file
|
@ -0,0 +1,168 @@
|
|||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/artisans/concept-map-view'
|
||||
|
||||
Level = require 'models/Level'
|
||||
Campaign = require 'models/Campaign'
|
||||
|
||||
CocoCollection = require 'collections/CocoCollection'
|
||||
Campaigns = require 'collections/Campaigns'
|
||||
Levels = require 'collections/Levels'
|
||||
parser = new esper().realm.parser
|
||||
|
||||
module.exports = class LevelConceptMap extends RootView
|
||||
template: template
|
||||
id: 'solution-problems-view'
|
||||
excludedCampaigns = [
|
||||
# Misc. campaigns
|
||||
'picoctf', 'auditions'
|
||||
|
||||
# Campaign-version campaigns
|
||||
#'dungeon', 'forest', 'desert', 'mountain', 'glacier'
|
||||
|
||||
# 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'
|
||||
]
|
||||
|
||||
includedLanguages = [
|
||||
'javascript'
|
||||
]
|
||||
|
||||
excludedLevelSnippets = [
|
||||
'treasure', 'brawl', 'siege'
|
||||
]
|
||||
|
||||
unloadedCampaigns: 0
|
||||
campaignLevels: {}
|
||||
loadedLevels: {}
|
||||
parsedLevels: []
|
||||
problemCount: 0
|
||||
|
||||
initialize: ->
|
||||
@campaigns = new Campaigns([])
|
||||
@listenTo(@campaigns, 'sync', @onCampaignsLoaded)
|
||||
@supermodel.trackRequest(@campaigns.fetch(
|
||||
data:
|
||||
project:'slug'
|
||||
))
|
||||
|
||||
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: ->
|
||||
for levelSlug, level of @loadedLevels
|
||||
unless level?
|
||||
console.error 'Level Slug doesn\'t have associated Level', levelSlug
|
||||
continue
|
||||
|
||||
isBad = false
|
||||
for word in excludedLevelSnippets
|
||||
if levelSlug.indexOf(word) isnt -1
|
||||
isBad = true
|
||||
continue if isBad
|
||||
thangs = level.get 'thangs'
|
||||
component = null
|
||||
thangs = _.filter(thangs, (elem) ->
|
||||
return _.findWhere(elem.components, (elem2) ->
|
||||
if elem2.config?.programmableMethods?
|
||||
component = elem2
|
||||
return true
|
||||
)
|
||||
)
|
||||
|
||||
if thangs.length > 1
|
||||
console.warn 'Level has more than 1 programmableMethod Thangs', levelSlug
|
||||
continue
|
||||
|
||||
unless component?
|
||||
console.error 'Level doesn\'t have programmableMethod Thang', levelSlug
|
||||
continue
|
||||
|
||||
plan = component.config.programmableMethods.plan
|
||||
@parsedLevels.push
|
||||
level: level
|
||||
tags: @tagLevel _.find plan.solutions, (s) -> s.language is 'javascript'
|
||||
|
||||
@renderSelectors '#level-table'
|
||||
|
||||
tagLevel: (src) ->
|
||||
return [] if not src?.source?
|
||||
try
|
||||
ast = parser(src.source)
|
||||
catch e
|
||||
return ['parse error: ' + e.message]
|
||||
|
||||
tags = {}
|
||||
process = (n) ->
|
||||
return unless n?
|
||||
switch n.type
|
||||
when "Program", "BlockStatement"
|
||||
process(n) for n in n.body
|
||||
when "FunctionDeclaration"
|
||||
tags['function-def'] = true
|
||||
if n.params > 0
|
||||
tags['function-params:' + n.params.length] = true
|
||||
process(n.body)
|
||||
when "ExpressionStatement"
|
||||
process(n.expression)
|
||||
when "CallExpression"
|
||||
process(n.callee)
|
||||
when "MemberExpression"
|
||||
if n.object?.name is 'hero'
|
||||
tags["hero." + n.property.name] = true
|
||||
when "WhileStatement"
|
||||
if n.test.type is 'Literal' and n.test.value is true
|
||||
tags['while-true'] = true
|
||||
else
|
||||
tags['while'] = true
|
||||
process(n.test)
|
||||
process(n.body)
|
||||
when "ForStatement"
|
||||
tags['for'] = true
|
||||
process(n.init)
|
||||
process(n.test)
|
||||
process(n.update)
|
||||
process(n.body)
|
||||
when "IfStatement"
|
||||
tags['if'] = true
|
||||
process(n.test)
|
||||
process(n.consequent)
|
||||
process(n.alternate)
|
||||
when "Literal"
|
||||
if n.value is true
|
||||
tags['true'] = true
|
||||
else
|
||||
tags['literal:' + typeof n.value] = true
|
||||
when "BinaryExpression","LogicalExpression"
|
||||
process(n.left)
|
||||
process(n.right)
|
||||
tags[n.operator] = true
|
||||
when "AssignmentExpression"
|
||||
tags['assign:' + n.operator] = true
|
||||
process(n.right)
|
||||
else
|
||||
tags[n.type] = true
|
||||
|
||||
|
||||
|
||||
process ast
|
||||
Object.keys(tags)
|
||||
|
Loading…
Reference in a new issue