INSTRUCTIONS:

  • Follow the instructions on the stage to complete this assessment activity.
  • If you finish the assessment and don’t see the "Great Job" feedback, click Run to try again.
  • When you see "Great Job", click Submit and Next to move on.

#################################################################################### # Assessment Variables (EDIT THIS CODE) #################################################################################### guide_label = "person20" background = "cyber_chip_blue" background_color = "" background_sprite = "" term_to_definition = { # "attack surface": "all of the available attack vectors that could be used for gaining unauthorized access", # "attack vector": "a method of gaining unauthorized access to a network or computer system", "cyber": "involving computers or networks", "cybersecurity": "the art of building secure computer systems that are safe from unauthorized use", # "cybersecurity specialist": "someone who manages and maintains entire cybersecurity systems", "digital citizenship": "the responsible and appropriate use of computing technology", "exploit": "the process of using a system's vulnerabilities to gain unauthorized access or functionality", # "incident and intrusion analyst": "someone who monitors networks for attacks and analyzes potential network vulnerabilities", # "IT support": "someone who helps users with their devices and trains them to practice good computer habits", # "network engineer": "someone who sets up, manages, and ensures secure communication of computer networks", # "pen tester/penetration tester": "an ethical hacker who tests a system's security by hacking it (with permission!)", # "ransomware": "a threat to publish or destroy data unless a payment is received", "security": "having to do with being safe or secure", # "software developer": "someone who writes computer software", "system": "a group of related parts that affect each other and work together as a whole", "systems thinking": "the art of thinking about how the parts of a system interact to produce an outcome", "vulnerability": "any error, weakness, or design flaw that can be exploited by a threat actor", } #################################################################################### # Assessment Code (DON'T EDIT THIS CODE) #################################################################################### import codesters import random from codesters.demo import Demo from codesters import Text demo = Demo() stage_width = int(stage.get_stage_width()) stage_height = int(stage.get_stage_height()) def play_game(term_to_definition, rounds=0): ''' Main function that sets up and runs the game''' global score, num_attempts def click(sprite): ''' Moves clicked sprite to the front (only applied to terms and definitions) and assigns collision event when clicked. ''' sprite.move_to_front() sprite.event_collision(collision) def collision(sprite, hit_sprite): ''' Collision event checks whether there is a valid match ''' if sprite.sprite_type == "definition": sprite, hit_sprite = hit_sprite, sprite # Immediately remove collision event as soon as it is detected # to avoid dragging term through all matches and catching one. # Collision event added back to sprite at the end of event. sprite.event_collision(None) same_group = False term = sprite.get_text() definition = hit_sprite.get_text() # Check if the sprites are both terms or both definitions same_group = sprite.sprite_type == hit_sprite.sprite_type # Exit if term-term collision or definition-definition collision if same_group == True: # Add collision event before exit to allow dragging through same type and still being able to match sprite.event_collision(collision) return correct_definition = term_to_definition[term] # Correct case if same_group == False and definition == correct_definition: # If correct on first try, term is removed from the dictionary and next round if sprite.attempted == False: del term_to_definition[term] stage.remove_sprite(sprite) stage.remove_sprite(hit_sprite) attempt_made("correct") # Incorrect case if same_group == False and definition != correct_definition: guide.say("Nope!") # Remove event from sprites so that they cannot # inadvertently hit the correct sprite while gliding back for t in term_text_sprites+definition_text_sprites: t.event_collision(None) stage.wait(.5) # Mark sprite as attempted (incorrectly) so it shows in next round sprite.attempted = True # Send sprites back to their original locations sprite.glide_to(sprite_to_location[sprite][0],sprite_to_location[sprite][1]) hit_sprite.glide_to(sprite_to_location[hit_sprite][0],sprite_to_location[hit_sprite][1]) attempt_made("incorrect") def attempt_made(answer): ''' Updates stage feedback and displays win/loss results ''' global score, num_attempts # Pause drag functionality for t in term_text_sprites: t.collision_off() guide.say("") minus_1 = Text("-1", 0, 1000, "red") plus_1 = Text("+1", 0, 1000, "green") if answer == "correct": checkmark.move_to_front() checkmark.show() checkmark.set_position(0, 0) correct_text.move_to_front() correct_text.show() correct_text.set_position(0, 135) stage.wait(.25) plus_1.go_to(score_text.get_x()+15, score_text.get_y()) stage.wait(.25) plus_1.turn_right(360) stage.remove_sprite(plus_1) stage.wait(.25) score += 1 score_text.set_text(str(score)+"/"+str(required_score)) stage.wait(1) checkmark.hide() correct_text.hide() else: minus_1.go_to(num_attempts_text.get_x()+15, num_attempts_text.get_y()) stage.wait(.25) minus_1.turn_right(360) stage.wait(.25) stage.remove_sprite(minus_1) num_attempts -= 1 num_attempts_text.set_text(str(num_attempts)) # Win/loss results and feedback if num_attempts == 0: for t in term_text_sprites+definition_text_sprites: t.event_click(None) # only add collision event to terms t.event_collision(None) t.set_drag_off() guide.move_up(50) tester = TestManager() # Win result if score == required_score: tester.display_success_message("Great job!") if rounds > 1: guide.say("Nice job! You won in "+str(rounds)+" rounds!\n\nClick RUN to try and beat your score!") else: guide.say("Excellent job! You won in just 1 round!") # Remind student to submit and click next reminder_sprites = demo.remind_student_to_submit(guide.get_x() - 180, guide.get_top() + 100, 25) # Flash the reminder sprites for counter in range(5): for sprite in reminder_sprites: sprite.set_opacity(.7) stage.wait(0.2) for sprite in reminder_sprites: sprite.set_opacity(1) stage.wait(0.2) # Loss result else: # Create next button and label next_round_button = codesters.Rectangle(0, 150, -(label_x - display_x), 30, "#f1823b") next_round_button.collision_off() next_symbol = u"⇨" next_round_button_text = Text("NEXT ROUND"+next_symbol, next_round_button.get_x(), next_round_button.get_y(), "white") next_round_button_text.collision_off() next_round_button_text.set_text_width(-(label_x - display_x)) next_round_button_text.set_text_align("center") next_round_button_text.set_text_size(17) demo.add_hover_opacity_element(next_round_button) next_round_button.event_click(reset_click) guide.move_to_front() guide.set_say_background("#eee", 1) tester.display_failure_message("Almost! Click the NEXT ROUND button to move on to Round "+str(rounds+1)+".") guide.say("Almost! Click the NEXT ROUND button to move on to Round "+str(rounds+1)+".\n\nMatch a term correctly on the first try so that it doesn't appear in the next round.") ############################ # Main function begins here ############################ rounds += 1 required_score = len(term_to_definition) # Set up stage if background: stage.set_background(background) if background_color: stage.set_background_color(background_color) if background_sprite: bg_sprite = codesters.Sprite(background_sprite, 0, 0) bg_sprite.collision_off() bg_sprite.set_height(stage_height) bg_sprite.set_width(stage_width) guide = demo.create_sprite_off_screen(guide_label, 0, -200, 1) guide.set_bottom(-stage_height/2) # Create checkmark offscreen checkmark = codesters.Sprite("checkmark_0bf", 1000, 0) correct_text = Text("CORRECT", 1000, 0, "green") correct_text.set_text_size(50) correct_text.set_text_weight('bold') ####################################### # Introduction screen ####################################### # Intro explanation in the first round if rounds == 1: guide.say("Welcome to Vocab Match!") stage.wait(2) guide.say("Welcome to Vocab Match!\n\nLet's test your vocabulary knowledge.") stage.wait(2) demo.continue_action() guide.say("Drag the terms and definitions together to match them!") stage.wait(2) guide.say("Drag the terms and definitions together to match them!\n\nAny terms not matched correctly\n on the first try will appear in the next round.") demo.continue_action() ######################################## # Assessment begins here ######################################## guide.say("Round "+str(rounds)+"!") guide.move_down(50) label_x = -70 # left aligned display_x = 70 # right aligned # Round display round_label_text = Text("ROUND: ", label_x, 250,"black") round_label_text.set_text_align("left") round_text = Text(str(rounds), display_x, round_label_text.get_y(), "black") round_text.set_text_align("right") # Score display score = 0 score_label_text = Text("SCORE: ", label_x, 220,"black") score_label_text.set_text_align("left") score_text = Text(str(score)+"/"+str(required_score), display_x, score_label_text.get_y(),"green") score_text.set_text_align("right") # Attempts display num_attempts = len(term_to_definition) num_attempts_label_text = Text("TRIES LEFT: ", label_x, 190, "black") num_attempts_label_text.set_text_align("left") num_attempts_text = Text(str(num_attempts), display_x, num_attempts_label_text.get_y(), "red") num_attempts_text.set_text_align("right") # Turn collision off for all stage objects that are not part of game stage_objects = [guide, checkmark, correct_text, round_label_text, round_text, score_label_text, score_text, num_attempts_label_text, num_attempts_text] for s in stage_objects: s.collision_off() # Store text sprites in separate lists term_text_sprites = [] definition_text_sprites = [] # Store total heights of text sprites terms_total_height = 0 definitions_total_height = 0 # Create term and definition sprites from main dict for key in term_to_definition: # Create term sprites term = codesters.Text(key, 0, 1000) terms_total_height += term.get_height() term_text_sprites.append(term) # Create definition sprites definition = codesters.Text(term_to_definition[key], 0, 1000) definition.set_text_width(350) definitions_total_height += definition.get_height() definition_text_sprites.append(definition) # Randomize order of terms and sprites random.shuffle(term_text_sprites) random.shuffle(definition_text_sprites) # Stores initial sprite locations sprite_to_location = {} # Variables for positioning sprites top_y = 250 # Highest point for stage items num_terms = len(term_to_definition) available_y = stage_height - (stage_height/2-top_y) term_avg_height = terms_total_height/num_terms definition_avg_height = definitions_total_height/num_terms # Calculate padding for terms and definitions term_padding = (available_y-term_avg_height*num_terms)/num_terms definition_padding = (available_y-definition_avg_height*num_terms)/num_terms # Initial top point for all sprites term_top = definition_top = top_y if num_terms < 7: term_top = top_y-.5*term_padding definition_top = top_y-.5*definition_padding # Set up term sprites for t in term_text_sprites: # t.event_collision(collision) # only add collision event to terms t.sprite_type = "word" t.attempted = False t.set_text_background("lightblue", "black", .85) t.set_text_align("left") t.set_speed(15) t.set_drag_on() t.event_click(click) t.collision_on() t.set_x(-500) t.set_top(term_top) sprite_to_location[t] = (t.get_x(), t.get_y()) # Update next top to the bottom of the last term term_top = t.get_bottom() - term_padding # Set up definition sprites for d in definition_text_sprites: d.sprite_type = "definition" d.set_text_background("orange", "black", .85) d.set_text_align("left") d.set_speed(15) d.set_drag_on() d.event_click(click) d.collision_on() d.set_x(150) d.set_top(definition_top) sprite_to_location[d] = (d.get_x(), d.get_y()) # Update next top to the bottom of the last definition definition_top = d.get_bottom() - definition_padding # Click event for reset button def reset_click(sprite): sprites = stage.get_all_sprites() for s in sprites: stage.remove_sprite(s) play_game(term_to_definition, rounds) play_game(term_to_definition)