Exemple #1
0
def solve_needy_modules(modules, needy_indices, curr_module, duration):
    SW, SH = win_util.get_screen_size()
    prev_index = curr_module
    timestamp = None
    for index in needy_indices:
        if (index > 5) ^ (prev_index > 5):  # Flip the bomb, if needed.
            inspect_bomb.flip_bomb(SW, SH)
            sleep(0.75)
            win_util.mouse_up(SW // 2, SH // 2, btn="right")
            sleep(0.5)
        mod_index = index if index < 6 else index - 6
        label = modules[index]
        select_module(mod_index)
        add_overlay_properties("module_info", (label))
        SC, x, y = screenshot_module()
        mod_pos = (x, y)
        cv2_img = convert_to_cv2(SC)
        mod_name = module_classifier.LABELS[label]
        log(f"Solving {mod_name}...")
        try:
            if label == 20:  # Needy Vent Gas.
                solve_needy_vent(cv2_img, mod_pos)
            elif label == 21:  # Needy Discharge Capacitor.
                solve_needy_discharge(cv2_img, mod_pos)
            elif label == 22:  # Solve Knob.
                solve_needy_knob(cv2_img, mod_pos)
        except KeyboardInterrupt:
            handle_module_exception(mod_name, cv2_img)
            raise KeyboardInterrupt
        except Exception:
            handle_module_exception(mod_name, cv2_img)
        if timestamp is None:
            cooldown_time = 5
            timestamp = time() + cooldown_time
        sleep(0.5)
        deselect_module()
        prev_index = index
    # Flip the bomb back to it's original state, if needed.
    if (curr_module > 5) ^ (prev_index > 5):
        inspect_bomb.flip_bomb(SW, SH)
        sleep(0.75)
        win_util.mouse_up(SW // 2, SH // 2, btn="right")
        sleep(0.5)
    return timestamp
Exemple #2
0
def extract_side_features(sides, labels, character_model):
    index = 0
    features = {"indicators": [], "parallel_port": False, "batteries": 0}
    for side in sides:
        for img in side:
            cv2_img = convert_to_cv2(img)
            mod_name = module_classifier.LABELS[labels[index]]
            try:
                if labels[index] == 1:  # Single battery (large or small).
                    features["batteries"] += 1
                elif labels[index] == 2:  # Double batteries.
                    features["batteries"] += 2
                elif labels[index] == 3:  # Serial number.
                    serial_num = get_serial_number(cv2_img, character_model)
                    if serial_num is None:
                        log(f"Serial number could not be determined.",
                            config.LOG_WARNING)
                        index += 1
                        continue
                    log(f"Serial number: {serial_num}",
                        verbose=config.LOG_DEBUG)
                    features["serial_number"] = serial_num
                    serial_features = extract_serial_number_features(
                        serial_num)
                    features.update(serial_features)
                elif labels[index] == 5:  # Parallel port.
                    features["parallel_port"] = True
                elif labels[index] == 6:  # Indicator of some kind.
                    lit, text = get_indicator_features(cv2_img,
                                                       character_model)
                    desc = "lit_" + text if lit else "unlit_" + text
                    features["indicators"].append(desc)
            except KeyboardInterrupt:
                handle_module_exception(mod_name, cv2_img)
                raise KeyboardInterrupt
            except Exception:
                handle_module_exception(mod_name, cv2_img)
            index += 1
    return features
Exemple #3
0
def solve_modules(modules, side_features, character_model, symbol_model,
                  duration):
    # Get list of indexes of needy modules (all modules an index over 19).
    needy_indices = list(
        filter(lambda i: modules[i] > 19, [x for x in range(len(modules))]))
    needy_timestamp = duration[0]
    module_durations = [2, 5, 2, 12, 10, 2, 14, 8, 8, 8, 20]
    log(f"Needy modules: {len(needy_indices)}", config.LOG_DEBUG)

    solved_modules = 0
    num_modules = len(list(filter(lambda x: 8 < x < 20, modules)))
    module = 0
    while module < len(modules):
        label = modules[module]
        LIGHT_MONITOR.wait_for_light()  # If the room is dark, wait for light.
        mod_index = module if module < 6 else module - 6
        bomb_solved = solved_modules == num_modules
        mod_duration = 2 if label > 19 else module_durations[label - 9]
        critical = needy_modules_critical(len(needy_indices), needy_timestamp,
                                          mod_duration)
        if not bomb_solved and critical:
            # Needy modules need attention! Solve them, and continue where we left off.
            needy_timestamp = solve_needy_modules(modules, needy_indices,
                                                  module, needy_timestamp)

        if 8 < label < 20:
            select_module(mod_index)
            SC, x, y = screenshot_module()
            #add_overlay_properties("module_selected", (x, y, mod_index))
            mod_pos = (x, y)
            cv2_img = convert_to_cv2(SC)
            mod_name = module_classifier.LABELS[label]
            log(f"Solving {mod_name}...")
            try:
                if label == 9:  # Wires.
                    solve_wires(cv2_img, mod_pos, side_features)
                elif label == 10:  # Button.
                    solve_button(cv2_img, mod_pos, side_features,
                                 character_model, duration)
                elif label == 11:  # Symbols.
                    solve_symbols(cv2_img, mod_pos, symbol_model)
                elif label == 12:  # Simon Says.
                    solve_simon(cv2_img, mod_pos, side_features)
                elif label == 13:  # Wire Sequence.
                    solve_wire_sequence(cv2_img, mod_pos)
                elif label == 14:  # Complicated Wires.
                    solve_complicated_wires(cv2_img, mod_pos, side_features)
                elif label == 15:  # Memory Game.
                    solve_memory(cv2_img, character_model, mod_pos)
                elif label == 16:  # Who's on First?
                    solve_whos_on_first(cv2_img, character_model, mod_pos)
                elif label == 17:  # Maze.
                    solve_maze(cv2_img, mod_pos)
                elif label == 18:  # Password.
                    solve_password(cv2_img, character_model, mod_pos)
                elif label == 19:  # Morse.
                    solve_morse(cv2_img, mod_pos)
                solved_modules += 1
            except KeyboardInterrupt:  # Bomb 'sploded.
                handle_module_exception(mod_name, cv2_img)
                raise KeyboardInterrupt
            except Exception:
                # If an exception happened while lights were off, we try again.
                if not LIGHT_MONITOR.lights_on:
                    log("Exception while light was off. We try again in a bit!"
                        )
                    deselect_module()
                    continue
                handle_module_exception(mod_name, cv2_img)

            sleep(0.1)
            deselect_module()

        if module == 5 and solved_modules != num_modules:
            # We have gone through all modules on one side of the bomb, flip it over and continue.
            SW, SH = win_util.get_screen_size()
            inspect_bomb.flip_bomb(SW, SH)
            sleep(0.75)
            win_util.mouse_up(SW // 2, SH // 2, btn="right")
            sleep(0.5)

        module += 1
    if solved_modules == num_modules:
        log("We did it! We live to defuse another bomb!")
    else:
        log("Some modules could not be disarmed, it seems we are doomed...")
        raise KeyboardInterrupt  # We failed.