rapid-router 5.4.1__py2.py3-none-any.whl → 7.6.8__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- example_project/rapid_router_test_settings.py +164 -0
- example_project/settings.py +152 -0
- example_project/urls.py +15 -0
- example_project/{example_project/wsgi.py → wsgi.py} +2 -1
- game/__init__.py +1 -1
- game/admin.py +43 -4
- game/app_settings.py +3 -7
- game/character.py +26 -18
- game/decor.py +172 -97
- game/end_to_end_tests/base_game_test.py +44 -33
- game/end_to_end_tests/editor_page.py +17 -2
- game/end_to_end_tests/game_page.py +127 -45
- game/end_to_end_tests/selenium_test_case.py +1 -20
- game/end_to_end_tests/test_cow_crashes.py +3 -5
- game/end_to_end_tests/test_language_dropdown.py +14 -0
- game/end_to_end_tests/test_level_editor.py +290 -0
- game/end_to_end_tests/test_level_failures.py +1 -1
- game/end_to_end_tests/test_level_selection.py +79 -0
- game/end_to_end_tests/test_play_through.py +240 -102
- game/end_to_end_tests/test_python_levels.py +44 -13
- game/end_to_end_tests/test_saving_workspace.py +22 -0
- game/forms.py +9 -2
- game/level_management.py +38 -29
- game/messages.py +1218 -203
- game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
- game/migrations/0026_levels_pt2.py +13 -2
- game/migrations/0032_cannot_turn_left_level.py +13 -2
- game/migrations/0033_recursion_level.py +13 -2
- game/migrations/0034_joes_level.py +13 -2
- game/migrations/0035_disable_route_score_level_70.py +0 -2
- game/migrations/0036_level_score_73.py +0 -2
- game/migrations/0037_level_score_79.py +0 -2
- game/migrations/0038_level_score_40.py +0 -1
- game/migrations/0042_level_score_73.py +0 -2
- game/migrations/0048_add_cow_field_and_blocks.py +0 -2
- game/migrations/0049_level_score_34.py +0 -2
- game/migrations/0050_level_score_40.py +0 -2
- game/migrations/0051_level_score_49.py +0 -1
- game/migrations/0076_level_locked_for_class.py +19 -0
- game/migrations/0077_alter_level_next_level.py +52 -0
- game/migrations/0078_add_block_types.py +23 -0
- game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
- game/migrations/0080_level_disable_algorithm_score.py +18 -0
- game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
- game/migrations/0082_level_43_solution.py +16 -0
- game/migrations/0083_add_cows_to_existing_levels.py +195 -0
- game/migrations/0084_alter_block_block_type.py +18 -0
- game/migrations/0085_add_new_blocks.py +53 -0
- game/migrations/0086_loop_levels.py +482 -0
- game/migrations/0087_workspace_python_view_enabled.py +18 -0
- game/migrations/0088_rename_episodes.py +35 -0
- game/migrations/0089_episodes_in_development.py +30 -0
- game/migrations/0090_add_missing_model_solutions.py +144 -0
- game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
- game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
- game/migrations/0093_alter_level_character_name.py +18 -0
- game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
- game/migrations/0095_level_commands.py +18 -0
- game/migrations/0096_alter_level_commands.py +18 -0
- game/migrations/0097_add_python_den_levels.py +1515 -0
- game/migrations/0098_add_episode_link_fields.py +44 -0
- game/migrations/0099_python_episodes_links.py +103 -0
- game/migrations/0100_reorder_python_levels.py +179 -0
- game/migrations/0101_rename_episodes.py +45 -0
- game/migrations/0102_reoder_episodes_13_14.py +136 -0
- game/migrations/0103_level_1015_solution.py +26 -0
- game/migrations/0104_remove_level_direct_drive.py +17 -0
- game/migrations/0105_delete_invalid_attempts.py +18 -0
- game/migrations/0106_fields_to_snake_case.py +48 -0
- game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
- game/migrations/0108_episode_indy_worksheet_link.py +18 -0
- game/migrations/0109_create_episodes_23_and_24.py +99 -0
- game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
- game/migrations/0111_create_worksheets.py +149 -0
- game/migrations/0112_worksheet_locked_classes.py +21 -0
- game/migrations/0113_level_needs_approval.py +18 -0
- game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
- game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
- game/migrations/0116_update_worksheet_video_links.py +68 -0
- game/migrations/0117_update_solutions_to_if_else.py +61 -0
- game/models.py +157 -16
- game/permissions.py +34 -19
- game/python_den_urls.py +26 -0
- game/random_road.py +43 -127
- game/serializers.py +12 -17
- game/static/django_reverse_js/js/reverse.js +171 -0
- game/static/game/css/LilitaOne-Regular.ttf +0 -0
- game/static/game/css/backgrounds.css +14 -10
- game/static/game/css/dataTables.custom.css +4 -2
- game/static/game/css/dataTables.jqueryui.css +561 -320
- game/static/game/css/editor.css +47 -0
- game/static/game/css/game.css +43 -49
- game/static/game/css/game_screen.css +116 -53
- game/static/game/css/jquery.dataTables.css +455 -251
- game/static/game/css/level_editor.css +10 -1
- game/static/game/css/level_selection.css +32 -3
- game/static/game/css/level_share.css +6 -5
- game/static/game/css/skulpt/codemirror.css +1 -0
- game/static/game/image/Python_Den_hero_student.png +0 -0
- game/static/game/image/Python_levels_page.svg +1954 -0
- game/static/game/image/characters/front_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/image/decor/city/solar_panel.svg +1200 -0
- game/static/game/image/decor/farm/solar_panel.svg +86 -0
- game/static/game/image/decor/grass/solar_panel.svg +86 -0
- game/static/game/image/decor/snow/barn.svg +1788 -0
- game/static/game/image/decor/snow/cfc.svg +1050 -147
- game/static/game/image/decor/snow/crops.svg +7370 -0
- game/static/game/image/decor/snow/hospital.svg +1220 -0
- game/static/game/image/decor/snow/house1.svg +971 -0
- game/static/game/image/decor/snow/house2.svg +1574 -0
- game/static/game/image/decor/snow/school.svg +1071 -0
- game/static/game/image/decor/snow/shop.svg +3211 -0
- game/static/game/image/decor/snow/solar_panel.svg +173 -0
- game/static/game/image/electric_van.svg +448 -0
- game/static/game/image/icons/add_house.svg +26 -0
- game/static/game/image/icons/delete_house.svg +26 -0
- game/static/game/image/icons/description.svg +1 -0
- game/static/game/image/icons/hint.svg +1 -0
- game/static/game/image/icons/if_else.svg +3 -0
- game/static/game/image/icons/python.svg +1 -1
- game/static/game/image/if_else_example.png +0 -0
- game/static/game/image/pigeon.svg +684 -0
- game/static/game/image/python_den_header.svg +19 -0
- game/static/game/js/animation.js +84 -28
- game/static/game/js/blockly/msg/js/bg.js +52 -1
- game/static/game/js/blockly/msg/js/ca.js +52 -1
- game/static/game/js/blockly/msg/js/en-gb.js +52 -1
- game/static/game/js/blockly/msg/js/en.js +52 -1
- game/static/game/js/blockly/msg/js/es.js +52 -1
- game/static/game/js/blockly/msg/js/fr.js +52 -1
- game/static/game/js/blockly/msg/js/hi.js +52 -1
- game/static/game/js/blockly/msg/js/it.js +52 -1
- game/static/game/js/blockly/msg/js/pl.js +52 -1
- game/static/game/js/blockly/msg/js/pt-br.js +52 -1
- game/static/game/js/blockly/msg/js/ru.js +52 -1
- game/static/game/js/blockly/msg/js/ur.js +52 -1
- game/static/game/js/blocklyCompiler.js +550 -392
- game/static/game/js/blocklyControl.js +335 -302
- game/static/game/js/blocklyCustomBlocks.js +691 -458
- game/static/game/js/blocklyCustomisations.js +3 -1
- game/static/game/js/button.js +12 -0
- game/static/game/js/cow.js +15 -130
- game/static/game/js/drawing.js +313 -201
- game/static/game/js/editor.js +23 -0
- game/static/game/js/game.js +148 -139
- game/static/game/js/jquery.dataTables.min.js +3 -159
- game/static/game/js/level_editor.js +823 -448
- game/static/game/js/level_moderation.js +33 -2
- game/static/game/js/level_selection.js +62 -25
- game/static/game/js/loadLanguages.js +21 -0
- game/static/game/js/map.js +106 -36
- game/static/game/js/model.js +55 -107
- game/static/game/js/pathFinder.js +73 -72
- game/static/game/js/program.js +184 -193
- game/static/game/js/pythonControl.js +14 -1
- game/static/game/js/scoreboard.js +0 -37
- game/static/game/js/scoreboardSharedLevels.js +48 -0
- game/static/game/js/sharing.js +22 -10
- game/static/game/js/skulpt/codemirror.js +5 -4
- game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
- game/static/game/js/sound.js +52 -5
- game/static/game/js/van.js +0 -7
- game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
- game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
- game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
- game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
- game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
- game/static/game/raphael_image/decor/snow/house1.svg +971 -0
- game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
- game/static/game/raphael_image/decor/snow/school.svg +1071 -0
- game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
- game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
- game/static/game/raphael_image/pigeon.svg +685 -0
- game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
- game/static/game/sass/game.scss +22 -6
- game/static/game/sound/clown_horn.mp3 +0 -0
- game/static/game/sound/clown_horn.ogg +0 -0
- game/static/game/sound/electric_van_starting.mp3 +0 -0
- game/static/game/sound/electric_van_starting.ogg +0 -0
- game/static/game/sound/pigeon.mp3 +0 -0
- game/static/game/sound/pigeon.ogg +0 -0
- game/static/game/sound/sleigh_bells.mp3 +0 -0
- game/static/game/sound/sleigh_bells.ogg +0 -0
- game/static/game/sound/sleigh_crash.mp3 +0 -0
- game/static/game/sound/sleigh_crash.ogg +0 -0
- game/templates/game/base.html +35 -15
- game/templates/game/basenonav.html +23 -17
- game/templates/game/game.html +236 -111
- game/templates/game/level_editor.html +353 -275
- game/templates/game/level_moderation.html +19 -6
- game/templates/game/level_selection.html +75 -62
- game/templates/game/python_den_level_selection.html +291 -0
- game/templates/game/python_den_worksheet.html +101 -0
- game/templates/game/scoreboard.html +88 -65
- game/tests/test_level_editor.py +210 -35
- game/tests/test_level_moderation.py +6 -20
- game/tests/test_level_selection.py +332 -11
- game/tests/test_python_den_worksheet.py +85 -0
- game/tests/test_scoreboard.py +258 -66
- game/tests/utils/level.py +43 -3
- game/tests/utils/teacher.py +2 -2
- game/theme.py +21 -21
- game/urls.py +125 -78
- game/views/language_code_conversions.py +90 -0
- game/views/level.py +201 -63
- game/views/level_editor.py +109 -48
- game/views/level_moderation.py +29 -6
- game/views/level_selection.py +179 -56
- game/views/level_solutions.py +600 -106
- game/views/scoreboard.py +181 -66
- game/views/worksheet.py +25 -0
- rapid_router-7.6.8.dist-info/METADATA +174 -0
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
- rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
- example_project/example_project/__init__.py +0 -1
- example_project/example_project/settings.py +0 -54
- example_project/example_project/urls.py +0 -16
- example_project/manage.py +0 -10
- game/autoconfig.py +0 -59
- game/csp_config.py +0 -23
- game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
- game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
- game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
- game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
- game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
- game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
- game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
- game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
- game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
- game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/django.po +0 -405
- game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/django.po +0 -405
- game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/django.po +0 -405
- game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
- game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/django.po +0 -405
- game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
- game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
- game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
- game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
- game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/django.po +0 -405
- game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
- game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/django.po +0 -405
- game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
- game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
- game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/django.po +0 -405
- game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
- game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
- game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
- game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
- game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
- game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
- game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
- game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
- game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
- game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
- game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
- game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
- game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
- game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
- game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
- game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
- game/static/game/image/actions/go.svg +0 -18
- game/static/game/image/icons/destination.svg +0 -9
- game/static/game/js/pqselect.min.js +0 -9
- game/static/game/js/widget-scroller.js +0 -906
- rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
- rapid_router-5.4.1.dist-info/METADATA +0 -24
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
|
@@ -8,36 +8,45 @@ ocargo.PathFinder = function(model) {
|
|
|
8
8
|
this.destinations = model.map.destinations;
|
|
9
9
|
|
|
10
10
|
this.pathScoreDisabled = DISABLE_ROUTE_SCORE;
|
|
11
|
+
this.algorithmScoreDisabled = DISABLE_ALGORITHM_SCORE;
|
|
11
12
|
this.modelSolution = MODEL_SOLUTION;
|
|
12
13
|
|
|
14
|
+
const tooSimpleToGetAlgorithmScore = (LEVEL_ID < 13);
|
|
15
|
+
|
|
13
16
|
if (!this.pathScoreDisabled) {
|
|
14
|
-
|
|
17
|
+
if (tooSimpleToGetAlgorithmScore) {
|
|
18
|
+
this.maxScoreForPathLength = 20;
|
|
19
|
+
} else {
|
|
20
|
+
this.maxScoreForPathLength = 10;
|
|
21
|
+
}
|
|
15
22
|
} else {
|
|
16
23
|
this.maxScoreForPathLength = 0;
|
|
17
24
|
}
|
|
18
25
|
|
|
19
|
-
this.maxScoreForNumberOfInstructions =
|
|
26
|
+
this.maxScoreForNumberOfInstructions = 0;
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
if (!this.algorithmScoreDisabled) {
|
|
29
|
+
this.maxScoreForNumberOfInstructions = 10;
|
|
30
|
+
}
|
|
22
31
|
|
|
32
|
+
this.maxScore = this.maxScoreForPathLength + this.maxScoreForNumberOfInstructions;
|
|
23
33
|
this.optimalPath = getOptimalPath(this.nodes, this.destinations);
|
|
24
34
|
};
|
|
25
35
|
|
|
26
36
|
ocargo.PathFinder.prototype.getScore = function() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
let routeCoins = {};
|
|
38
|
+
let instrCoins = {};
|
|
39
|
+
let performance= "";
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
if(!this.pathScoreDisabled){
|
|
41
|
+
let pathLengthScore = 0;
|
|
42
|
+
if (!this.pathScoreDisabled) {
|
|
33
43
|
pathLengthScore = Math.max(0, this.getTravelledPathScore());
|
|
34
44
|
routeCoins = this.getNumCoins(pathLengthScore, this.maxScoreForPathLength);
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
let totalScore = pathLengthScore;
|
|
38
48
|
|
|
39
|
-
if (this.
|
|
40
|
-
// Then we're on a default level
|
|
49
|
+
if (!this.algorithmScoreDisabled) {
|
|
41
50
|
var initInstrScore = this.getScoreForNumberOfInstructions();
|
|
42
51
|
var instrScore = Math.max(0, initInstrScore);
|
|
43
52
|
|
|
@@ -52,7 +61,6 @@ ocargo.PathFinder.prototype.getScore = function() {
|
|
|
52
61
|
instrCoins = this.getNumCoins(instrScore, this.maxScoreForNumberOfInstructions);
|
|
53
62
|
}
|
|
54
63
|
|
|
55
|
-
|
|
56
64
|
if (pathLengthScore < this.maxScoreForPathLength) {
|
|
57
65
|
performance = "pathLonger";
|
|
58
66
|
}
|
|
@@ -62,11 +70,11 @@ ocargo.PathFinder.prototype.getScore = function() {
|
|
|
62
70
|
else if (initInstrScore < this.maxScoreForNumberOfInstructions) {
|
|
63
71
|
performance = "algorithmLonger";
|
|
64
72
|
}
|
|
65
|
-
else
|
|
73
|
+
else if (totalScore === this.maxScore) {
|
|
66
74
|
performance = "scorePerfect";
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
const endLevelMsg = function(performance) {
|
|
70
78
|
switch (performance){
|
|
71
79
|
case 'pathLonger':
|
|
72
80
|
return gettext('Try finding a shorter route to the destination.');
|
|
@@ -88,6 +96,7 @@ ocargo.PathFinder.prototype.getScore = function() {
|
|
|
88
96
|
performance: performance,
|
|
89
97
|
pathLengthScore: pathLengthScore,
|
|
90
98
|
pathScoreDisabled: this.pathScoreDisabled,
|
|
99
|
+
algorithmScoreDisabled: this.algorithmScoreDisabled,
|
|
91
100
|
maxScoreForPathLength: this.maxScoreForPathLength,
|
|
92
101
|
instrScore: instrScore,
|
|
93
102
|
maxScoreForNumberOfInstructions: this.maxScoreForNumberOfInstructions,
|
|
@@ -100,17 +109,17 @@ ocargo.PathFinder.prototype.getNumCoins = function(score, maxScore) {
|
|
|
100
109
|
};
|
|
101
110
|
|
|
102
111
|
ocargo.PathFinder.prototype.getTravelledPathScore = function() {
|
|
103
|
-
|
|
104
|
-
|
|
112
|
+
const travelled = this.van.getDistanceTravelled();
|
|
113
|
+
const START_AND_END_BLOCKS = 2;
|
|
114
|
+
return this.maxScoreForPathLength - (travelled + START_AND_END_BLOCKS - this.optimalPath.length);
|
|
105
115
|
};
|
|
106
116
|
|
|
107
117
|
ocargo.PathFinder.prototype.getScoreForNumberOfInstructions = function() {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
var currDifference = blocksUsed - this.modelSolution[i];
|
|
118
|
+
const blocksUsed = ocargo.utils.isIOSMode() ? ocargo.game.mobileBlocks : ocargo.blocklyControl.activeBlocksCount();
|
|
119
|
+
let algorithmScore = 0;
|
|
120
|
+
let difference = this.maxScoreForNumberOfInstructions;
|
|
121
|
+
for (let i = 0; i < this.modelSolution.length; i++) {
|
|
122
|
+
let currDifference = blocksUsed - this.modelSolution[i];
|
|
114
123
|
if (Math.abs(currDifference) < difference) {
|
|
115
124
|
difference = Math.abs(currDifference);
|
|
116
125
|
algorithmScore = this.maxScoreForNumberOfInstructions - currDifference;
|
|
@@ -120,13 +129,11 @@ ocargo.PathFinder.prototype.getScoreForNumberOfInstructions = function() {
|
|
|
120
129
|
};
|
|
121
130
|
|
|
122
131
|
ocargo.PathFinder.prototype.getLength = function(stack) {
|
|
123
|
-
|
|
124
|
-
var total = 0;
|
|
125
|
-
var i;
|
|
132
|
+
let total = 0;
|
|
126
133
|
if (!stack) {
|
|
127
134
|
return total;
|
|
128
135
|
}
|
|
129
|
-
for (i = 0; i < stack.length; i++) {
|
|
136
|
+
for (let i = 0; i < stack.length; i++) {
|
|
130
137
|
if (stack[i].command === "While") {
|
|
131
138
|
total += this.getLength(stack[i].block);
|
|
132
139
|
}
|
|
@@ -139,16 +146,14 @@ ocargo.PathFinder.prototype.getLength = function(stack) {
|
|
|
139
146
|
return total;
|
|
140
147
|
};
|
|
141
148
|
|
|
142
|
-
|
|
143
|
-
|
|
144
149
|
function getOptimalPath(nodes, destinations) {
|
|
145
150
|
// Brute force Travelling Salesman implementation, using A* to determine the connection lengths
|
|
146
151
|
// If the map size increases or lots of destinations are required, it may need to be rethought
|
|
147
|
-
|
|
152
|
+
let hash = {};
|
|
148
153
|
function getPathBetweenNodes(node1, node2) {
|
|
149
|
-
|
|
154
|
+
const key = '(' + node1.coordinate.x + ',' + node1.coordinate.y + '),(' + node2.coordinate.x +
|
|
150
155
|
',' + node2.coordinate.y + ')';
|
|
151
|
-
|
|
156
|
+
let solution;
|
|
152
157
|
if (key in hash) {
|
|
153
158
|
solution = hash[key];
|
|
154
159
|
}
|
|
@@ -160,13 +165,13 @@ function getOptimalPath(nodes, destinations) {
|
|
|
160
165
|
}
|
|
161
166
|
|
|
162
167
|
function getPermutationPath(start, permutation) {
|
|
163
|
-
|
|
164
|
-
for (
|
|
168
|
+
let fragPath = [getPathBetweenNodes(start, permutation[0], nodes)];
|
|
169
|
+
for (let i = 1; i < permutation.length; i++) {
|
|
165
170
|
fragPath.push(getPathBetweenNodes(permutation[i-1], permutation[i], nodes));
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
|
|
169
|
-
for (
|
|
173
|
+
let fullPath = [start];
|
|
174
|
+
for (let i = 0; i < fragPath.length; i++) {
|
|
170
175
|
if (!fragPath[i]) {
|
|
171
176
|
return null;
|
|
172
177
|
}
|
|
@@ -177,12 +182,12 @@ function getOptimalPath(nodes, destinations) {
|
|
|
177
182
|
return fullPath;
|
|
178
183
|
}
|
|
179
184
|
|
|
180
|
-
|
|
185
|
+
let permutations = [];
|
|
181
186
|
function permute(array, data) {
|
|
182
|
-
|
|
183
|
-
|
|
187
|
+
let current;
|
|
188
|
+
let currentPermutation = data || [];
|
|
184
189
|
|
|
185
|
-
for (
|
|
190
|
+
for (let i = 0; i < array.length; i++) {
|
|
186
191
|
// Take node out
|
|
187
192
|
current = array.splice(i, 1)[0];
|
|
188
193
|
// Then the current permutation is complete so add it
|
|
@@ -196,26 +201,25 @@ function getOptimalPath(nodes, destinations) {
|
|
|
196
201
|
}
|
|
197
202
|
}
|
|
198
203
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
let start = nodes[0];
|
|
205
|
+
let bestScore = Number.POSITIVE_INFINITY;
|
|
206
|
+
let bestPermutationPath = null;
|
|
207
|
+
let destinationNodes = [];
|
|
203
208
|
|
|
204
|
-
for (
|
|
209
|
+
for (let i = 0; i < destinations.length; i++) {
|
|
205
210
|
destinationNodes.push(destinations[i].node);
|
|
206
211
|
}
|
|
207
212
|
permute(destinationNodes);
|
|
208
213
|
|
|
209
|
-
for (
|
|
210
|
-
|
|
211
|
-
|
|
214
|
+
for (let i = 0; i < permutations.length; i++) {
|
|
215
|
+
let permutation = permutations[i];
|
|
216
|
+
const permutationPath = getPermutationPath(start, permutation, nodes);
|
|
212
217
|
|
|
213
218
|
if (permutationPath && permutationPath.length < bestScore) {
|
|
214
219
|
bestScore = permutationPath.length;
|
|
215
220
|
bestPermutationPath = permutationPath;
|
|
216
221
|
}
|
|
217
222
|
}
|
|
218
|
-
|
|
219
223
|
return bestPermutationPath;
|
|
220
224
|
}
|
|
221
225
|
|
|
@@ -226,21 +230,19 @@ function QueueLink(node, score) {
|
|
|
226
230
|
}
|
|
227
231
|
|
|
228
232
|
function PriorityQueue() {
|
|
229
|
-
var head = null;
|
|
230
|
-
|
|
231
233
|
this.push = function(node, score) {
|
|
232
234
|
if (this.head == null) {
|
|
233
235
|
this.head = new QueueLink(node, score);
|
|
234
236
|
} else if (this.head.score > score) {
|
|
235
|
-
|
|
237
|
+
let tmp = this.head;
|
|
236
238
|
this.head = new QueueLink(node, score);
|
|
237
239
|
this.head.next = tmp;
|
|
238
240
|
} else {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
+
let i = this.head;
|
|
242
|
+
let found = false;
|
|
241
243
|
while (i.next != null && !found) {
|
|
242
244
|
if (i.next.score > score) {
|
|
243
|
-
|
|
245
|
+
let tmp = i.next;
|
|
244
246
|
i.next = new QueueLink(node, score);
|
|
245
247
|
i.next.next = tmp;
|
|
246
248
|
found = true;
|
|
@@ -257,7 +259,7 @@ function PriorityQueue() {
|
|
|
257
259
|
if (this.head == null) {
|
|
258
260
|
return null;
|
|
259
261
|
} else {
|
|
260
|
-
|
|
262
|
+
const result = this.head.node;
|
|
261
263
|
this.head = this.head.next;
|
|
262
264
|
return result;
|
|
263
265
|
}
|
|
@@ -269,12 +271,11 @@ function PriorityQueue() {
|
|
|
269
271
|
}
|
|
270
272
|
|
|
271
273
|
function aStar(origin, destination, nodes) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
var openSet = new PriorityQueue();
|
|
274
|
+
const end = destination; // Nodes already visited.
|
|
275
|
+
let current;
|
|
276
|
+
const start = origin;
|
|
277
|
+
let closedSet = {}; // The neighbours yet to be evaluated.
|
|
278
|
+
let openSet = new PriorityQueue();
|
|
278
279
|
openSet.push(start, 0);
|
|
279
280
|
|
|
280
281
|
initialiseParents(nodes);
|
|
@@ -287,14 +288,14 @@ function aStar(origin, destination, nodes) {
|
|
|
287
288
|
if (current === end) {
|
|
288
289
|
return getNodeList(current);
|
|
289
290
|
}
|
|
290
|
-
for (
|
|
291
|
-
|
|
291
|
+
for (let i = 0; i < current.connectedNodes.length; i++) {
|
|
292
|
+
let neighbour = current.connectedNodes[i];
|
|
292
293
|
if (Object.prototype.hasOwnProperty.call(closedSet, neighbour.id)) {
|
|
293
294
|
continue;
|
|
294
295
|
}
|
|
295
296
|
closedSet[neighbour.id] = true;
|
|
296
297
|
neighbour.parent = current;
|
|
297
|
-
|
|
298
|
+
const score = distanceFromStart(neighbour) + heuristic(destination, neighbour);
|
|
298
299
|
openSet.push(neighbour, score);
|
|
299
300
|
}
|
|
300
301
|
}
|
|
@@ -302,21 +303,21 @@ function aStar(origin, destination, nodes) {
|
|
|
302
303
|
return null;
|
|
303
304
|
|
|
304
305
|
function heuristic(node1, node2) {
|
|
305
|
-
|
|
306
|
-
|
|
306
|
+
const d1 = Math.abs(node2.coordinate.x - node1.coordinate.x);
|
|
307
|
+
const d2 = Math.abs(node2.coordinate.y - node1.coordinate.y);
|
|
307
308
|
return d1 + d2;
|
|
308
309
|
}
|
|
309
310
|
|
|
310
311
|
function initialiseParents(nodes) {
|
|
311
|
-
for (
|
|
312
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
312
313
|
nodes[i].parent = null;
|
|
313
314
|
nodes[i].id = i;
|
|
314
315
|
}
|
|
315
316
|
}
|
|
316
317
|
|
|
317
318
|
function distanceFromStart(current) {
|
|
318
|
-
|
|
319
|
-
|
|
319
|
+
let count = 0;
|
|
320
|
+
let i = current;
|
|
320
321
|
while (i.parent != null) {
|
|
321
322
|
count = count + 1;
|
|
322
323
|
i = i.parent;
|
|
@@ -325,8 +326,8 @@ function aStar(origin, destination, nodes) {
|
|
|
325
326
|
}
|
|
326
327
|
|
|
327
328
|
function getNodeList(current) {
|
|
328
|
-
|
|
329
|
-
|
|
329
|
+
let curr = current;
|
|
330
|
+
let ret = [];
|
|
330
331
|
while (curr !== start && curr !== null) {
|
|
331
332
|
ret.push(curr);
|
|
332
333
|
curr = curr.parent;
|
|
@@ -338,7 +339,7 @@ function aStar(origin, destination, nodes) {
|
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
function areDestinationsReachable(start, destinations, nodes) {
|
|
341
|
-
for (
|
|
342
|
+
for (let i = 0; i < destinations.length; i++) {
|
|
342
343
|
if (aStar(start, destinations[i], nodes) == null) {
|
|
343
344
|
return false;
|
|
344
345
|
}
|