def release_mouse_at(digit, duration, x, y): time_started, mins, secs = duration while True: remaining = get_time_remaining(time_started, mins, secs) sec_str = str(remaining % 60) if len(sec_str) == 1: sec_str = "0" + sec_str digits = (remaining // 60, int(sec_str[0]), int(sec_str[1])) if digit in digits: win_util.mouse_up(x, y) break sleep(0.5)
def solve_needy_discharge(image, mod_pos): if not needy_features.is_active(image): log("Needy Discharge is not active.", config.LOG_DEBUG, "Needy Discharge") return mod_x, mod_y = mod_pos time_to_drain = needy_discharge_solver.solve(image) x_top, y_top = mod_x + 230, mod_y + 92 win_util.mouse_move(x_top, y_top) win_util.mouse_down(x_top, y_top) sleep(time_to_drain) win_util.mouse_up(x_top, y_top)
def solve_needy_discharge(image, mod_pos, time_started): if not needy_features.is_active(image): log("Needy Discharge is not active.", config.LOG_DEBUG, "Needy Discharge") return mod_x, mod_y = mod_pos time_spent = get_time_spent(time_started) x_top, y_top = mod_x + 230, mod_y + 92 win_util.mouse_move(x_top, y_top) win_util.mouse_down(x_top, y_top) sleep_time = 1 + (time_spent / 5) sleep(sleep_time) win_util.mouse_up(x_top, y_top)
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
def inspect(labels, labels_to_inspect): SW, SH = win_util.get_screen_size() filtered_labels = [] images = [] for module in range(12): mod_index = module if module < 6 else module - 6 if labels[module] in labels_to_inspect: main.select_module(mod_index) sleep(1) SC, _, _ = main.screenshot_module() images.append(SC) filtered_labels.append(labels[module]) main.deselect_module() sleep(0.5) if module == 5: # We have gone through 6 modules, flip the bomb over and proceeed. SW, SH = win_util.get_screen_size() flip_bomb(SW, SH) sleep(0.75) win_util.mouse_up(SW // 2, SH // 2, btn="right") sleep(0.5) return images, filtered_labels
def inspect_bomb(num_modules=None): sw, sh = win_util.get_screen_size() mid_x = sw // 2 mid_y = sh // 2 win_util.click(mid_x, mid_y + (mid_y // 8)) sleep(0.5) # Inspect front of bomb. front_img = screenshot(460, 220, 1000, 640) sleep(0.2) # Rotate bomb. win_util.mouse_down(mid_x, mid_y, btn="right") sleep(0.2) # Inspect right side. right_img = inspect_side(sw - int(sw / 2.74), mid_y + int(mid_y / 8), 755, 60, 480, 900) # Inspect left side. left_img = inspect_side(int(sw / 2.76), mid_y + int(mid_y / 8), 755, 60, 480, 900) # Inspect top side. top_img = inspect_side(int(sw / 2.75), sh, 720, 0, 480, sh) # Inspect bottom side. bottom_img = inspect_side(int(sw / 2.75), 0, 720, 0, 480, sh) # Inspect back of bomb. win_util.mouse_up(mid_x, mid_y, btn="right") sleep(0.5) return_tupl = (front_img, left_img, right_img, top_img, bottom_img) if num_modules is None or num_modules > 5: flip_bomb(sw, sh) back_img = screenshot(460, 220, 1000, 640) sleep(0.4) win_util.mouse_up(mid_x, mid_y, btn="right") return_tupl = (back_img, ) + return_tupl else: win_util.click(200, 200, btn="right") sleep(0.4) win_util.click(mid_x, mid_y + (mid_y // 8)) sleep(0.5) return return_tupl
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.