gameboy_worlds.emulation.harvest_moon.parsers
Harvest Moon GBC game state parser implementations. Uses visual screen regions to parse game state, following the same design principles as the Pokemon parsers.
CORE DESIGN PRINCIPLE: Never branch the parser subclasses for a given variant. The inheritance tree for a parser after the game variant parser should always be a tree with only one child per layer. This is to ensure that we don't double effort, any capability added to a parser will always be valid for that game variant. If this principle is followed, any state tracker can always use the STRONGEST (lowest level) parser for a given variant without concern for missing functionality.
1""" 2Harvest Moon GBC game state parser implementations. 3Uses visual screen regions to parse game state, following the same design principles as the Pokemon parsers. 4 5CORE DESIGN PRINCIPLE: Never branch the parser subclasses for a given variant. The inheritance tree for a parser after the game variant parser should always be a tree with only one child per layer. 6This is to ensure that we don't double effort, any capability added to a parser will always be valid for that game variant. 7If this principle is followed, any state tracker can always use the STRONGEST (lowest level) parser for a given variant without concern for missing functionality. 8""" 9 10from gameboy_worlds.emulation.parser import NamedScreenRegion 11from gameboy_worlds.utils import ( 12 log_warn, 13 log_info, 14 log_error, 15 load_parameters, 16 verify_parameters, 17) 18from gameboy_worlds.emulation.parser import StateParser, _get_proper_regions 19 20from typing import Set, List, Type, Dict, Optional, Tuple 21import os 22from abc import ABC, abstractmethod 23from enum import Enum 24 25from pyboy import PyBoy 26 27import json 28import numpy as np 29from bidict import bidict 30 31 32class AgentState(Enum): 33 """ 34 0. FREE_ROAM: The agent is freely roaming the game world. 35 1. IN_DIALOGUE: The agent is currently in a dialogue state. 36 2. IN_MENU: The agent has a menu open. 37 """ 38 39 FREE_ROAM = 0 40 IN_DIALOGUE = 1 41 IN_MENU = 2 42 IN_STORAGE_LIST = 3 43 44 45class HarvestMoonStateParser(StateParser, ABC): 46 """ 47 Base class for Harvest Moon GBC game state parsers. Uses visual screen regions to parse game state. 48 Defines common named screen regions and methods for determining game states such as being in dialogue. 49 50 Can be used to determine the exact AgentState. 51 """ 52 53 COMMON_REGIONS = [] 54 """ List of common single-target named screen regions for Harvest Moon games. """ 55 56 COMMON_MULTI_TARGET_REGIONS = [ 57 ("screen", 0, 0, 150, 140), 58 ("screen_middle", 65, 55, 20, 20), 59 ("dialogue_box_top", 58, 10, 40, 10), 60 ] 61 """ List of common multi-target named screen regions for Harvest Moon games. 62 63 - dialogue_bottom_right: Bottom-right corner of the dialogue box (x=153, y=135, 10x10px). 64 Capture while dialogue is visible in dev_play: `c dialogue_bottom_right,<type_name>` 65 - screen_bottom: Bottom strip of the screen (x=0, y=100, 160x40px). 66 Useful for detecting locations and events. Capture in dev_play: `c screen_bottom,<target_name>` 67 """ 68 69 COMMON_MULTI_TARGETS = { 70 "screen_bottom": [ 71 "cow_barn_entrance", 72 "chicken_coop_entrance", 73 ], 74 } 75 """ Common multi-targets for the common multi-target named screen regions. 76 - screen_bottom: Location/event captures for the bottom strip of the screen. 77 """ 78 79 def __init__( 80 self, 81 variant: str, 82 pyboy: PyBoy, 83 parameters: dict, 84 additional_named_screen_region_details: List[ 85 Tuple[str, int, int, int, int] 86 ] = [], 87 additional_multi_target_named_screen_region_details: List[ 88 Tuple[str, int, int, int, int] 89 ] = [], 90 override_multi_targets: Dict[str, List[str]] = {}, 91 ): 92 """ 93 Initializes the HarvestMoonStateParser. 94 Args: 95 pyboy (PyBoy): The PyBoy emulator instance. 96 parameters (dict): Configuration parameters for the emulator. 97 additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include. 98 additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include. 99 override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions. 100 """ 101 verify_parameters(parameters) 102 regions = _get_proper_regions( 103 override_regions=additional_named_screen_region_details, 104 base_regions=self.COMMON_REGIONS, 105 ) 106 self.variant = variant 107 if f"{variant}_rom_data_path" not in parameters: 108 log_error( 109 f"ROM data path not found for variant: {variant}. Add {variant}_rom_data_path to the config files. See configs/pokemon_red_vars.yaml for an example", 110 parameters, 111 ) 112 self.rom_data_path = parameters[f"{variant}_rom_data_path"] 113 """ Path to the ROM data directory for the specific Harvest Moon variant.""" 114 captures_dir = self.rom_data_path + "/captures/" 115 named_screen_regions = [] 116 for region_name, x, y, w, h in regions: 117 region = NamedScreenRegion( 118 region_name, 119 x, 120 y, 121 w, 122 h, 123 parameters=parameters, 124 target_path=os.path.join(captures_dir, region_name), 125 ) 126 named_screen_regions.append(region) 127 multi_target_regions = _get_proper_regions( 128 override_regions=additional_multi_target_named_screen_region_details, 129 base_regions=self.COMMON_MULTI_TARGET_REGIONS, 130 ) 131 multi_target_region_names = [region[0] for region in multi_target_regions] 132 multi_targets = self.COMMON_MULTI_TARGETS.copy() 133 for key in override_multi_targets: 134 if key in multi_targets: 135 multi_targets[key].extend(override_multi_targets[key]) 136 else: 137 multi_targets[key] = override_multi_targets[key] 138 multi_target_provided_region_names = list(multi_targets.keys()) 139 if not set(multi_target_provided_region_names).issubset( 140 set(multi_target_region_names) 141 ): 142 log_error( 143 f"Multi-target regions provided in multi_targets do not match the defined multi-target regions. Provided: {multi_target_provided_region_names}, Defined: {multi_target_region_names}", 144 parameters, 145 ) 146 for region_name, x, y, w, h in multi_target_regions: 147 region_target_paths = {} 148 subdir = captures_dir + f"/{region_name}/" 149 for target_name in multi_targets.get(region_name, []): 150 region_target_paths[target_name] = os.path.join(subdir, target_name) 151 region = NamedScreenRegion( 152 region_name, 153 x, 154 y, 155 w, 156 h, 157 parameters=parameters, 158 multi_target_paths=region_target_paths, 159 ) 160 named_screen_regions.append(region) 161 super().__init__(pyboy, parameters, named_screen_regions) 162 163 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 164 if self.is_in_dialogue(current_screen): 165 return AgentState.IN_DIALOGUE 166 return AgentState.FREE_ROAM 167 168 169class BaseHarvestMoonStateParser(HarvestMoonStateParser, ABC): 170 """ 171 Game state parser for all Harvest Moon GBC-based games. 172 """ 173 174 REGIONS = [ 175 ] 176 """ Additional named screen regions specific to Harvest Moon GBC games. 177 """ 178 179 MULTI_TARGET_REGIONS = [ 180 ] 181 """ Additional multi-target named screen regions specific to Harvest Moon GBC games. 182 """ 183 184 def __init__( 185 self, 186 pyboy: PyBoy, 187 variant: str, 188 parameters: dict, 189 override_regions: List[Tuple[str, int, int, int, int]] = [], 190 override_multi_target_regions: List[Tuple[str, int, int, int, int]] = [], 191 override_multi_targets: Dict[str, List[str]] = {}, 192 ): 193 self.REGIONS = _get_proper_regions( 194 override_regions=override_regions, base_regions=self.REGIONS 195 ) 196 self.MULTI_TARGET_REGIONS = _get_proper_regions( 197 override_regions=override_multi_target_regions, 198 base_regions=self.MULTI_TARGET_REGIONS, 199 ) 200 super().__init__( 201 variant=variant, 202 pyboy=pyboy, 203 parameters=parameters, 204 additional_named_screen_region_details=self.REGIONS, 205 additional_multi_target_named_screen_region_details=self.MULTI_TARGET_REGIONS, 206 override_multi_targets=override_multi_targets, 207 ) 208 209 def __repr__(self): 210 return f"<HarvestMoonParser(variant={self.variant})>" 211 212class HarvestMoon1Parser(BaseHarvestMoonStateParser): 213 214 DIALOGUE_TYPES = [ 215 "home_dialogue", 216 "shop_dialogue", 217 "church_dialogue", 218 "harvest_spirits_dialogue", 219 "read_signs_dialogue", 220 "evening_dialogue", 221 "barn_dialogue", 222 "winter_read_signs_dialogue", 223 "winter_evening_dialogue", 224 ] 225 def __init__(self, pyboy, parameters): 226 override_regions = [ 227 ("menu_top_right", 153, 0, 5, 5), 228 ("storage_list_top_right", 153, 0, 6, 6), 229 ] 230 231 override_multi_target_regions = [ 232 ("dialogue_bottom_right", 153, 135, 10, 10), 233 ("screen", 0, 0, 160, 143), 234 ("screen_middle", 65, 63, 30, 30), 235 ("screen_bottom", 0, 100, 160, 40), 236 ("dialogue_box_top", 60, 11, 40, 8), 237 ("dialogue_box_top_mid", 68, 11, 22, 8), 238 ("dialogue_box_top_short", 71, 11, 15, 8), 239 ("dialogue_box_bottom", 0, 105, 160, 35), 240 ("item_bed", 0, 40, 40, 40), 241 ("item_watercan_above", 56, 85, 15, 35), 242 ("item_watercan_right", 55, 80, 30, 20), 243 ("item_watercan_below", 56, 70, 15, 30), 244 ("item_cowbell_above", 39, 49, 15, 35), 245 ("item_cowbell_below", 39, 70, 15, 30), 246 ("item_sickle_above", 88, 85, 15, 35), 247 ("item_sickle_left", 70, 80, 30, 20), 248 ("item_sickle_below", 88, 70, 15, 30), 249 ("item_hoe_above", 102, 85, 15, 35), 250 ("item_hoe_below", 102, 70, 15, 30), 251 ("item_hammer_above", 120, 85, 15, 35), 252 ("item_hammer_below", 120, 70, 15, 30), 253 ("item_grass_seed_above", 56, 55, 15, 35), 254 ("item_grass_seed_right", 55, 70, 30, 20), 255 ("item_grass_seed_below", 56, 70, 15, 30), 256 ("item_storage_list", 0, 40, 20, 30), 257 ("item_spirit_left", 70, 50, 30, 30), 258 ("item_spirit_below", 70, 50, 30, 30), 259 ("item_spirit_above", 70, 50, 15, 50), 260 ("item_safe_below", 40, 30, 15, 40), 261 ("item_lost_bird_left", 70, 65, 30, 25), 262 ("item_lost_bird_right", 60, 65, 30, 25), 263 ("item_lost_bird_below", 70, 50, 20, 35), 264 ("item_blue_hair_girl_left", 80, 20, 30, 30), 265 ("item_blue_hair_girl_right", 95, 20, 30, 30), 266 ("item_blue_hair_girl_below", 95, 20, 20, 40), 267 ("item_golden_hair_girl_above", 32, 40, 15, 40), 268 ("item_golden_hair_girl_right", 30, 55, 35, 25), 269 ("item_golden_hair_girl_below", 32, 55, 15, 35), 270 ("item_pink_hair_girl_left", 32, 68, 33, 22), 271 ("item_pink_hair_girl_right", 48, 68, 30, 22), 272 ("item_pink_hair_girl_above", 48, 68, 15, 38), 273 ("item_blue_hair_girl_wg_left", 80, 25, 30, 20), 274 ("item_blue_hair_girl_wg_right", 97, 25, 30, 21), 275 ("item_blue_hair_girl_wg_below", 97, 25, 13, 35), 276 ("item_pink_hair_girl_wg_left", 32, 68, 33, 22), 277 ("item_pink_hair_girl_wg_right", 48, 68, 30, 22), 278 ("item_pink_hair_girl_wg_above", 48, 68, 15, 38), 279 ("item_red_hair_girl_wg_left", 80, 68, 30, 22), 280 ("item_red_hair_girl_wg_right", 97, 68, 30, 22), 281 ("item_red_hair_girl_wg_above", 97, 68, 13, 40), 282 ("item_chicken_stall_block1", 5, 40, 25, 20), 283 ("item_next_to_chicken_stall_block1", 5, 55, 25, 25), 284 ("item_chicken_silo_left", 100, 40, 30, 30), 285 ("item_chicken_silo_below1", 120, 50, 15, 35), 286 ("item_chicken_silo_below2", 135, 50, 15, 35), 287 ("item_cow_feeding_stall", 55, 25, 30, 45), 288 ("item_cow_feeding_stall_right", 55, 25, 45, 45), 289 ("item_egg_left", 89, 75, 31, 25), 290 ("item_egg_above", 105, 78, 15, 37), 291 ("item_egg_right", 110, 75, 22, 25), 292 ("item_hatching_box", 120, 70, 35, 30), 293 ("turnip_center", 70, 90, 20, 20), 294 ("turnip_top", 70, 70, 20, 35), 295 ("item_turnip_field", 55, 65, 47, 54), 296 ("item_turnip_field_water", 40, 58, 47, 47), 297 ("item_potato_field", 55, 40, 47, 54), 298 ("item_rock_left", 0, 65, 45, 20), 299 ("item_rightmost_rock_above", 55, 60, 33, 40), 300 ("item_weed_above", 15, 65, 30, 50), 301 ("item_top_left_weed", 25, 60, 25, 25), 302 ("item_grassland_right", 50, 60, 35, 30), 303 ("item_center_grassline", 40, 70, 95, 20), 304 ("item_broken_fence_field", 63, 55, 30, 30), 305 ("item_fence_field", 0, 40, 30, 60), 306 ("center_sign", 55, 65, 50, 15), 307 ("screen_top_half", 0, 0, 160, 65), 308 ("screen_bottom_half", 0, 75, 160, 65), 309 ("left_border_frame", 0, 0, 5, 140), 310 ] 311 312 override_multi_targets = { 313 "dialogue_bottom_right":[ 314 "home_dialogue", 315 "shop_dialogue", 316 "church_dialogue", 317 "harvest_spirits_dialogue", 318 "read_signs_dialogue", 319 "evening_dialogue", 320 "barn_dialogue", 321 "winter_read_signs_dialogue", 322 "winter_evening_dialogue", 323 ], 324 "screen_middle":[ 325 "outside_cow_barn_left", 326 "outside_cow_barn_right", 327 "outside_cow_barn_up", 328 "outside_chicken_coop_left", 329 "outside_chicken_coop_right", 330 "outside_chicken_coop_up", 331 "outside_storage_left", 332 "outside_storage_right", 333 "outside_storage_up", 334 ], 335 "screen_bottom": [ 336 "cow_barn_entrance", 337 "chicken_coop_entrance", 338 "storage_shed_entrance", 339 ], 340 "dialogue_box_bottom":[ 341 "found_rainy_money", 342 "select_material", 343 "select_home_expansion", 344 "select_chicken", 345 "select_selling_chicken", 346 "select_cow", 347 "bought_named_cow", 348 "select_cow_brush", 349 "select_saddlebag", 350 "select_milker", 351 "choose_yes_for_sleep", 352 "fed_spirit", 353 "helped_spirit_earthquake", 354 "select_rice_ball", 355 "select_croissant", 356 "select_cake", 357 "select_grape_juice", 358 "found_bird_for_friend", 359 "speaking_to_blue_hair_girl", 360 "speaking_to_golden_hair_girl", 361 "speaking_to_pink_hair_girl", 362 "speaking_to_blue_hair_girl_wg", 363 "speaking_to_pink_hair_girl_wg", 364 "speaking_to_red_hair_girl_wg", 365 "option_to_pray", 366 "praying", 367 ], 368 "item_bed":[ 369 "sleep_in_bed", 370 ], 371 "item_storage_list":[ 372 "next_to_storage_list", 373 ], 374 "item_watercan_above":[ 375 "pickup_watercan_down", 376 ], 377 "item_watercan_right":[ 378 "pickup_watercan_left", 379 ], 380 "item_cowbell_above":[ 381 "next_to_cowbell_down", 382 ], 383 "item_cowbell_below":[ 384 "next_to_cowbell_up", 385 ], 386 "item_watercan_below":[ 387 "pickup_watercan_up", 388 ], 389 "item_sickle_above":[ 390 "pickup_sickle_down", 391 ], 392 "item_sickle_left":[ 393 "pickup_sickle_right", 394 ], 395 "item_sickle_below":[ 396 "pickup_sickle_up", 397 ], 398 "item_hoe_above":[ 399 "pickup_hoe_down", 400 ], 401 "item_hoe_below":[ 402 "pickup_hoe_up", 403 ], 404 "item_hammer_above":[ 405 "pickup_hammer_down", 406 ], 407 "item_hammer_below":[ 408 "pickup_hammer_up", 409 ], 410 "item_grass_seed_above":[ 411 "pickup_grass_seed_down", 412 ], 413 "item_grass_seed_right":[ 414 "pickup_grass_seed_left", 415 ], 416 "item_grass_seed_below":[ 417 "pickup_grass_seed_up", 418 ], 419 "item_spirit_left":[ 420 "feed_spirit_right", 421 "help_spirit_earthquake_right", 422 ], 423 "item_spirit_above":[ 424 "feed_spirit_down", 425 "help_spirit_earthquake_down", 426 ], 427 "item_spirit_below":[ 428 "feed_spirit_up", 429 "help_spirit_earthquake_up", 430 ], 431 "item_safe_below":[ 432 "next_to_safe_up", 433 "next_to_safe_left", 434 ], 435 "item_lost_bird_left":[ 436 "find_lost_bird_right", 437 ], 438 "item_lost_bird_right":[ 439 "find_lost_bird_left", 440 ], 441 "item_lost_bird_below":[ 442 "find_lost_bird_up", 443 ], 444 "item_blue_hair_girl_left":[ 445 "next_to_blue_hair_girl_right", 446 ], 447 "item_blue_hair_girl_right":[ 448 "next_to_blue_hair_girl_left", 449 ], 450 "item_blue_hair_girl_below":[ 451 "next_to_blue_hair_girl_up", 452 ], 453 "item_golden_hair_girl_above":[ 454 "next_to_golden_hair_girl_down", 455 ], 456 "item_golden_hair_girl_right":[ 457 "next_to_golden_hair_girl_left", 458 ], 459 "item_golden_hair_girl_below":[ 460 "next_to_golden_hair_girl_up", 461 ], 462 "item_pink_hair_girl_left":[ 463 "next_to_pink_hair_girl_right", 464 ], 465 "item_pink_hair_girl_right":[ 466 "next_to_pink_hair_girl_left", 467 ], 468 "item_pink_hair_girl_above":[ 469 "next_to_pink_hair_girl_down", 470 ], 471 "item_blue_hair_girl_wg_left": [ 472 "next_to_blue_hair_girl_wg_right", 473 ], 474 "item_blue_hair_girl_wg_right": [ 475 "next_to_blue_hair_girl_wg_left", 476 ], 477 "item_blue_hair_girl_wg_below": [ 478 "next_to_blue_hair_girl_wg_up", 479 ], 480 "item_pink_hair_girl_wg_left": [ 481 "next_to_pink_hair_girl_wg_right", 482 ], 483 "item_pink_hair_girl_wg_right": [ 484 "next_to_pink_hair_girl_wg_left", 485 ], 486 "item_pink_hair_girl_wg_above": [ 487 "next_to_pink_hair_girl_wg_down", 488 ], 489 "item_red_hair_girl_wg_left": [ 490 "next_to_red_hair_girl_wg_right", 491 ], 492 "item_red_hair_girl_wg_right": [ 493 "next_to_red_hair_girl_wg_left", 494 ], 495 "item_red_hair_girl_wg_above": [ 496 "next_to_red_hair_girl_wg_down", 497 ], 498 "item_chicken_stall_block1":[ 499 "filled_chicken_stall_block1", 500 ], 501 "item_next_to_chicken_stall_block1":[ 502 "next_to_chicken_stall_block1", 503 ], 504 "item_chicken_silo_left":[ 505 "next_to_chicken_silo_right", 506 "got_fodder_from_chicken_silo_right", 507 ], 508 "item_chicken_silo_below1":[ 509 "next_to_chicken_silo_up1", 510 "got_fodder_from_chicken_silo_up1", 511 ], 512 "item_chicken_silo_below2":[ 513 "next_to_chicken_silo_up2", 514 "got_fodder_from_chicken_silo_up2", 515 ], 516 "item_cow_feeding_stall": [ 517 "cow_feeding_stall_filled", 518 ], 519 "item_cow_feeding_stall_right": [ 520 "next_to_cow_feeding_stall_left", 521 ], 522 "item_egg_left": [ 523 "next_to_egg_right", 524 ], 525 "item_egg_above": [ 526 "next_to_egg_down", 527 ], 528 "item_egg_right": [ 529 "next_to_egg_left", 530 ], 531 "item_hatching_box": [ 532 "dropped_egg_into_hatching_box", 533 ], 534 "dialogue_box_top":[ 535 "pick_up_watercan", 536 "pick_up_grass_seed", 537 ], 538 "dialogue_box_top_mid":[ 539 "pick_up_sickle", 540 "pick_up_hammer", 541 "pick_up_cowbell", 542 ], 543 "dialogue_box_top_short":[ 544 "pick_up_hoe", 545 ], 546 "turnip_center":[ 547 "finish_watering_1", 548 "finish_watering_2", 549 ], 550 "turnip_top":[ 551 "ready_to_water_1", 552 "ready_to_water_2", 553 ], 554 "item_turnip_field": [ 555 "next_to_center_turnip_down_1", 556 "next_to_center_turnip_down_2", 557 "center_turnip_harvested_1", 558 "center_turnip_harvested_2", 559 ], 560 "item_turnip_field_water":[ 561 "next_to_center_turnip_left_1", 562 "next_to_center_turnip_left_2", 563 "center_turnip_watered_1", 564 "center_turnip_watered_2", 565 ], 566 "item_potato_field": [ 567 "next_to_center_potato_up_1", 568 "next_to_center_potato_up_2", 569 "next_to_center_potato_below_up_1", 570 "next_to_center_potato_below_up_2", 571 "center_potato_watered_1", 572 "center_potato_watered_2", 573 "center_potato_harvested_1", 574 "center_potato_harvested_2", 575 ], 576 "item_rock_left": [ 577 "next_to_rock_right", 578 "rock_cleared", 579 ], 580 "item_rightmost_rock_above": [ 581 "next_to_rightmost_rock_down", 582 "rightmost_rock_cleared", 583 ], 584 "item_weed_above": [ 585 "next_to_lowest_weed_down", 586 "lowest_weed_removed", 587 "lowest_weed_cut", 588 ], 589 "item_top_left_weed": [ 590 "next_to_top_left_weed_up", 591 "top_left_weed_removed", 592 "top_left_weed_cut", 593 ], 594 "item_grassland_right": [ 595 "next_to_grassland_left", 596 ], 597 "item_center_grassline": [ 598 "center_grass_harvested_1", 599 "center_grass_harvested_2", 600 ], 601 "item_broken_fence_field": [ 602 "picked_up_broken_fence_up", 603 "picked_up_broken_fence_down", 604 "picked_up_broken_fence_left", 605 "picked_up_broken_fence_right", 606 ], 607 "item_fence_field": [ 608 "restored_fence", 609 ], 610 "center_sign":[ 611 "outside_carpenter", 612 "outside_animal_shop", 613 "outside_tool_shop", 614 "outside_restaurant", 615 "outside_juice_bar", 616 "outside_church", 617 ], 618 "screen_bottom_half":[ 619 "bought_material", 620 "home_expansion_estimate", 621 "bought_chicken", 622 "sold_chicken", 623 "bought_cow_brush", 624 "bought_saddlebag", 625 "bought_milker", 626 "option_to_buy_rice_ball", 627 "bought_rice_ball", 628 "option_to_buy_croissant", 629 "bought_croissant", 630 "option_to_buy_cake", 631 "bought_cake", 632 "option_to_buy_grape_juice", 633 "bought_grape_juice", 634 ], 635 "screen_top_half":[ 636 "in_carpenter", 637 "in_animal_shop", 638 "in_tool_shop", 639 "in_restaurant", 640 "in_juice_bar", 641 "in_church", 642 ], 643 "left_border_frame":[ 644 "open_storage_list", 645 ], 646 } 647 648 super().__init__( 649 pyboy, 650 variant="harvest_moon_1", 651 parameters=parameters, 652 override_regions=override_regions, 653 override_multi_target_regions=override_multi_target_regions, 654 override_multi_targets=override_multi_targets, 655 ) 656 657 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 658 """ 659 Determines if a dialogue box is currently open by checking the dialogue bottom right region. 660 Args: 661 current_screen (np.ndarray): The current screen frame from the emulator. 662 Returns: 663 bool: True if a dialogue box is open, False otherwise. 664 """ 665 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 666 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 667 self.DIALOGUE_TYPES, captured 668 ) 669 670 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 671 box = self.capture_named_region( 672 current_frame=current_screen, name="dialogue_box_bottom" 673 ) 674 perc_lt_255 = np.mean(box < 255) 675 if perc_lt_255 < 0.082: # Empirical threshold 676 return True 677 return False 678 679 def is_in_menu(self, current_screen: np.ndarray) -> bool: 680 return self.named_region_matches_target(current_screen, "menu_top_right") 681 682 def is_in_storage_list(self, current_screen: np.ndarray) -> bool: 683 return self.named_region_matches_target(current_screen, "storage_list_top_right") 684 685 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 686 """ 687 Returns True if the dialogue_bottom_right region matches any of the saved dialogue type targets. 688 """ 689 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 690 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 691 self.DIALOGUE_TYPES, captured 692 ) 693 694 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 695 """ 696 Determines the current agent state based on the screen. 697 698 Args: 699 current_screen (np.ndarray): The current screen frame from the emulator. 700 701 Returns: 702 AgentState: The current agent state. 703 """ 704 if self.is_in_menu(current_screen): 705 return AgentState.IN_MENU 706 if self.is_in_storage_list(current_screen): 707 return AgentState.IN_STORAGE_LIST 708 if self.is_in_dialogue(current_screen): 709 return AgentState.IN_DIALOGUE 710 return AgentState.FREE_ROAM 711 712class HarvestMoon2Parser(BaseHarvestMoonStateParser): 713 DIALOGUE_TYPES = [ 714 "home_dialogue", 715 "carpenter_dialogue", 716 "hospital_dialogue", 717 "tool_shop_dialogue", 718 "animal_shop_dialogue", 719 "restaurant_dialogue", 720 "library_dialogue", 721 "flower_shop_dialogue", 722 "church_dialogue", 723 "read_signs_dialogue", 724 "barn_dialogue", 725 ] 726 727 def __init__(self, pyboy, parameters): 728 override_regions = [ 729 ("menu_top_right", 153, 8, 6, 6), 730 ("storage_list_top_right", 153, 0, 6, 6), 731 ] 732 override_multi_target_regions = [ 733 ("dialogue_bottom_right", 153, 135, 10, 10), 734 ("screen_middle", 50, 25, 40, 43), 735 ("outside_barns", 40, 15, 50, 53), 736 ("screen_bottom", 0, 95, 160, 40), 737 ("dialogue_box_top", 60, 11, 40, 8), 738 ("dialogue_box_bottom", 0, 105, 160, 35), 739 ("hospital_location", 65, 0, 55, 70), 740 ("tool_shop_location", 65, 0, 55, 70), 741 ("carpenter_location", 35, 0, 55, 70), 742 ("animal_shop_location", 65, 0, 55, 70), 743 ("library_location", 35, 0, 55, 70), 744 ("flower_shop_location", 30, 0, 105, 70), 745 ("restaurant_location", 40, 0, 70, 70), 746 ("item_clock_below", 95, 25, 15, 45), 747 ("item_bed", 0, 40, 40, 40), 748 ("item_diary", 45, 40, 20, 40), 749 ("item_storage_list", 0, 40, 20, 30), 750 ("item_village_sign_above", 70, 85, 20, 35), 751 ("item_village_sign_left", 55, 70, 30, 25), 752 ("item_village_sign_right", 75, 70, 30, 25), 753 ("item_farm_sign_above", 70, 85, 20, 35), 754 ("item_farm_sign_left", 55, 70, 30, 25), 755 ("item_farm_sign_right", 75, 70, 30, 25), 756 ("item_secret_garden_sign_above", 74, 50, 15, 45), 757 ("item_secret_garden_sign_right", 58, 50, 27, 25), 758 ("item_secret_garden_sign_left", 72, 50, 30, 25), 759 ("item_crop_field_sign_above", 71, 55, 24, 40), 760 ("item_notice_board_above", 70, 85, 20, 35), 761 ("item_notice_board_left", 55, 70, 30, 25), 762 ("item_notice_board_right", 75, 70, 30, 25), 763 ("turnip_center", 70, 90, 20, 20), 764 ("turnip_top", 70, 70, 20, 35), 765 ("item_eggplant_field", 55, 25, 50, 45), 766 ("item_carrot_field", 55, 25, 50, 45), 767 ("item_next_to_shipping_box", 0, 20, 30, 50), 768 ("item_shipping_box_field", 0, 20, 45, 25), 769 ("item_start_line", 0, 20, 30, 50), 770 ("item_distance_markers", 65, 40, 30, 30), 771 ("item_potato_field", 32, 40, 50, 45), 772 ("item_asparagus_field", 70, 40, 50, 45), 773 ("item_corn_field", 55, 40, 48, 47), 774 ("item_cabbage_field", 55, 40, 48, 47), 775 ("item_center_corn_above", 58, 50, 45, 50), 776 ("item_leftmost_weed_right", 10, 50, 35, 23), 777 ("item_leftmost_weed_above", 10, 50, 20, 43), 778 ("item_berry_left", 70, 39, 32, 31), 779 ("item_berry_above", 68, 38, 18, 48), 780 ("item_chicken_stall_block1", 5, 20, 35, 20), 781 ("item_next_to_chicken_stall_block1", 5, 35, 35, 30), 782 ("item_chicken_silo_left1", 100, 30, 30, 30), 783 ("item_chicken_silo_left2", 100, 40, 30, 30), 784 ("item_chicken_silo_below", 115, 38, 15, 35), 785 ("item_next_to_hatching_box", 113, 60, 37, 40), 786 ("item_hatching_box", 129, 66, 16, 30), 787 ("npc_blue_hair_girl_left", 66, 39, 29, 21), 788 ("npc_blue_hair_girl_below", 72, 28, 16, 39), 789 ("npc_blue_hair_girl_right", 56, 39, 29, 21), 790 ("npc_purple_hair_girl_left", 98, 39, 30, 21), 791 ("npc_purple_hair_girl_below", 114, 31, 16, 39), 792 ("npc_blonde_girl_right", 31, 48, 29, 21), 793 ("npc_blonde_girl_above", 31, 48, 14, 47), 794 ("center_sign", 55, 65, 50, 15), 795 ("screen_top_half", 0, 0, 160, 65), 796 ("screen_bottom_half", 0, 75, 160, 65), 797 ("left_border_frame", 0, 0, 5, 140), 798 ("top_left_label", 0, 0, 160, 15), 799 ("equipment_region_1", 45, 15, 26, 17), 800 ("equipment_region_2", 72, 15, 26, 17), 801 ("equipment_region_3", 95, 15, 26, 17), 802 ("equipment_region_4", 119, 15, 26, 17), 803 ] 804 override_multi_targets = { 805 "dialogue_bottom_right": [ 806 "home_dialogue", 807 "carpenter_dialogue", 808 "hospital_dialogue", 809 "tool_shop_dialogue", 810 "animal_shop_dialogue", 811 "restaurant_dialogue", 812 "library_dialogue", 813 "flower_shop_dialogue", 814 "church_dialogue", 815 "read_signs_dialogue", 816 "barn_dialogue", 817 ], 818 "dialogue_box_bottom": [ 819 "found_lucky_money", 820 "option_to_diary_sleep", 821 "reading_secret_garden_sign", 822 "reading_crop_field_sign", 823 "computers_article_selected", 824 "reading_computers_article", 825 "boulders_article_selected", 826 "reading_boulders_article", 827 "crops_article_selected", 828 "reading_crops_article", 829 "select_cow", 830 "bought_named_cow", 831 "select_chicken", 832 "select_selling_chicken", 833 "select_selling_cow", 834 "select_hothouse", 835 "select_bridge", 836 "select_milker", 837 "speaking_to_blue_hair_girl", 838 "speaking_to_purple_hair_girl", 839 "speaking_to_blonde_girl", 840 ], 841 "item_clock_below": [ 842 "next_to_clock_up", 843 ], 844 "flower_shop_location": [ 845 "outside_flower_shop_up", 846 "outside_flower_shop_left", 847 "outside_flower_shop_right", 848 ], 849 "item_bed": [ 850 "sleep_in_bed", 851 ], 852 "item_diary": [ 853 "next_to_diary", 854 ], 855 "item_secret_garden_sign_above": [ 856 "next_to_secret_garden_sign_down", 857 ], 858 "item_secret_garden_sign_right": [ 859 "next_to_secret_garden_sign_left", 860 ], 861 "item_secret_garden_sign_left": [ 862 "next_to_secret_garden_sign_right", 863 ], 864 "item_crop_field_sign_above": [ 865 "next_to_crop_field_sign_down", 866 ], 867 "item_start_line": [ 868 "at_the_start_line", 869 ], 870 "item_next_to_shipping_box": [ 871 "next_to_shipping_box_up", 872 ], 873 "item_shipping_box_field": [ 874 "drop_eggplant_into_shipping_box", 875 ], 876 "item_distance_markers": [ 877 "crossed_500m_line", 878 "crossed_1000m_line", 879 ], 880 "item_eggplant_field": [ 881 "next_to_center_eggplant_up_1", 882 "next_to_center_eggplant_up_2", 883 "center_eggplant_harvested_1", 884 "center_eggplant_harvested_2", 885 ], 886 "item_carrot_field": [ 887 "next_to_center_carrot_up_1", 888 "next_to_center_carrot_up_2", 889 "center_carrot_harvested_1", 890 "center_carrot_harvested_2", 891 ], 892 "item_cabbage_field": [ 893 "at_cabbage_center_1", 894 "at_cabbage_center_2", 895 "cabbage_field_watered_1", 896 "cabbage_field_watered_2", 897 ], 898 "item_potato_field": [ 899 "next_to_center_potato_up_1", 900 "next_to_center_potato_up_2", 901 "center_potato_watered_1", 902 "center_potato_watered_2", 903 ], 904 "item_asparagus_field": [ 905 "next_to_center_asparagus_right_1", 906 "next_to_center_asparagus_right_2", 907 "center_asparagus_watered_1", 908 "center_asparagus_watered_2", 909 ], 910 "item_corn_field": [ 911 "at_corn_center_1", 912 "at_corn_center_2", 913 "corn_field_watered_1", 914 "corn_field_watered_2", 915 ], 916 "item_center_corn_above": [ 917 "next_to_center_corn_down_1", 918 "next_to_center_corn_down_2", 919 "center_corn_cut_1", 920 "center_corn_cut_2", 921 ], 922 "restaurant_location": [ 923 "outside_restaurant_up", 924 "outside_restaurant_left", 925 "outside_restaurant_right", 926 ], 927 "hospital_location": [ 928 "outside_hospital_up", 929 "outside_hospital_left", 930 "outside_hospital_right", 931 ], 932 "tool_shop_location": [ 933 "outside_tool_shop_up", 934 "outside_tool_shop_left", 935 "outside_tool_shop_right", 936 ], 937 "carpenter_location": [ 938 "outside_carpenter_up", 939 "outside_carpenter_left", 940 "outside_carpenter_right", 941 ], 942 "animal_shop_location": [ 943 "outside_animal_shop_up", 944 "outside_animal_shop_left", 945 "outside_animal_shop_right", 946 ], 947 "library_location": [ 948 "outside_library_up", 949 "outside_library_left", 950 "outside_library_right", 951 ], 952 "screen_top_half": [ 953 "in_hospital", 954 "in_tool_shop", 955 "in_carpenter", 956 "in_animal_shop", 957 "in_library", 958 "in_flower_shop", 959 "in_restaurant", 960 "shop_for_construction_estimates", 961 ], 962 "screen_bottom_half": [ 963 "bought_potato_seeds", 964 "bought_asparagus_seeds", 965 "select_potato_seeds", 966 "select_potato_seeds_portion", 967 "select_asparagus_seeds", 968 "select_asparagus_seeds_portion", 969 "bought_lunch_set", 970 "select_lunch_set", 971 "option_to_buy_lunch_set", 972 "bought_beverage_set", 973 "select_beverage_set", 974 "option_to_buy_beverage_set", 975 "bought_todays_special", 976 "select_todays_special", 977 "option_to_buy_todays_special", 978 "bought_chicken", 979 "sold_cow", 980 "sold_chicken", 981 "hothouse_estimate", 982 "bridge_estimate", 983 "bought_milker", 984 ], 985 "outside_barns":[ 986 "outside_cow_barn_left", 987 "outside_cow_barn_right", 988 "outside_cow_barn_up", 989 "outside_chicken_coop_left", 990 "outside_chicken_coop_right", 991 "outside_chicken_coop_up", 992 ], 993 "top_left_label": [ 994 "ready_to_pick_sickle", 995 "ready_to_pick_hammer", 996 "ready_to_pick_fishing_rod", 997 "ready_to_pick_net", 998 "ready_to_pick_rosemary_seeds", 999 ], 1000 "equipment_region_1": [ 1001 "sprinkler_selected_1", 1002 "sickle_equipped_1", 1003 ], 1004 "equipment_region_2": [ 1005 "ax_selected_2", 1006 "net_equipped", 1007 "rosemary_seeds_equipped", 1008 ], 1009 "equipment_region_3": [ 1010 "hoe_selected_3", 1011 "net_equipped_3", 1012 ], 1013 "equipment_region_4":[ 1014 "empty_hands_selected", 1015 "sickle_equipped", 1016 "hammer_equipped", 1017 "fishing_rod_equipped", 1018 ], 1019 "item_leftmost_weed_right": [ 1020 "next_to_leftmost_weed_left", 1021 "leftmost_weed_removed_left", 1022 ], 1023 "item_leftmost_weed_above": [ 1024 "next_to_leftmost_weed_down", 1025 "leftmost_weed_removed_down", 1026 ], 1027 "item_berry_left": [ 1028 "next_to_berry_right", 1029 "berry_picked_right", 1030 ], 1031 "item_berry_above": [ 1032 "next_to_berry_down_1", 1033 "next_to_berry_down_2", 1034 "berry_picked_above_1", 1035 "berry_picked_above_2", 1036 ], 1037 "item_chicken_stall_block1": [ 1038 "filled_chicken_stall_block1", 1039 ], 1040 "item_next_to_chicken_stall_block1": [ 1041 "next_to_chicken_stall_block1", 1042 ], 1043 "item_chicken_silo_left1": [ 1044 "next_to_chicken_silo_right1", 1045 "got_fodder_from_chicken_silo_right1", 1046 ], 1047 "item_chicken_silo_left2": [ 1048 "next_to_chicken_silo_right2", 1049 "got_fodder_from_chicken_silo_right2", 1050 ], 1051 "item_chicken_silo_below": [ 1052 "next_to_chicken_silo_up", 1053 "got_fodder_from_chicken_silo_up", 1054 ], 1055 "item_next_to_hatching_box": [ 1056 "next_to_hatching_box", 1057 ], 1058 "item_hatching_box": [ 1059 "dropped_egg_into_hatching_box", 1060 ], 1061 "npc_blue_hair_girl_left": [ 1062 "next_to_blue_hair_girl_right", 1063 ], 1064 "npc_blue_hair_girl_below": [ 1065 "next_to_blue_hair_girl_up", 1066 ], 1067 "npc_blue_hair_girl_right": [ 1068 "next_to_blue_hair_girl_left", 1069 ], 1070 "npc_purple_hair_girl_left": [ 1071 "next_to_purple_hair_girl_right", 1072 ], 1073 "npc_purple_hair_girl_below": [ 1074 "next_to_purple_hair_girl_up", 1075 ], 1076 "npc_blonde_girl_right": [ 1077 "next_to_blonde_girl_left", 1078 ], 1079 "npc_blonde_girl_above": [ 1080 "next_to_blonde_girl_down", 1081 ], 1082 } 1083 super().__init__( 1084 pyboy, 1085 variant="harvest_moon_2", 1086 parameters=parameters, 1087 override_regions=override_regions, 1088 override_multi_target_regions=override_multi_target_regions, 1089 override_multi_targets=override_multi_targets, 1090 ) 1091 1092 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 1093 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1094 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1095 self.DIALOGUE_TYPES, captured 1096 ) 1097 1098 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1099 box = self.capture_named_region( 1100 current_frame=current_screen, name="dialogue_box_bottom" 1101 ) 1102 perc_lt_255 = np.mean(box < 255) 1103 if perc_lt_255 < 0.082: # Empirical threshold 1104 return True 1105 return False 1106 1107 def is_in_menu(self, current_screen: np.ndarray) -> bool: 1108 return self.named_region_matches_target(current_screen, "menu_top_right") 1109 1110 def is_in_storage_list(self, current_screen: np.ndarray) -> bool: 1111 return self.named_region_matches_target(current_screen, "storage_list_top_right") 1112 1113 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 1114 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1115 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1116 self.DIALOGUE_TYPES, captured 1117 ) 1118 1119 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 1120 if self.is_in_menu(current_screen): 1121 return AgentState.IN_MENU 1122 if self.is_in_storage_list(current_screen): 1123 return AgentState.IN_STORAGE_LIST 1124 if self.is_in_dialogue(current_screen): 1125 return AgentState.IN_DIALOGUE 1126 return AgentState.FREE_ROAM 1127 1128 1129class HarvestMoon3Parser(BaseHarvestMoonStateParser): 1130 DIALOGUE_TYPES = [ 1131 "normal_dialogue", 1132 "mainland_dialogue", 1133 ] 1134 1135 def __init__(self, pyboy, parameters): 1136 override_regions = [ 1137 ("menu_top_right", 153, 0, 6, 6), 1138 ] 1139 override_multi_target_regions = [ 1140 ("dialogue_bottom_right", 153, 135, 10, 10), 1141 ("screen_bottom", 0, 95, 160, 40), 1142 ("dialogue_box_bottom", 0, 98, 160, 45), 1143 ("item_secret_garden_sign_above", 60, 55, 20, 40), 1144 ("item_secret_garden_sign_right", 50, 55, 35, 25), 1145 ("item_turnip_seeds_above", 30, 55, 17, 41), 1146 ("item_turnip_seeds_below", 30, 40, 17, 39), 1147 ("item_potato_seeds_above", 63, 55, 17, 41), 1148 ("item_potato_seeds_below", 63, 40, 17, 39), 1149 ("screen_top_half", 0, 0, 160, 65), 1150 ("screen_bottom_half", 0, 75, 160, 65), 1151 ("item_storage_sign_below", 70, 40, 20, 40), 1152 ("item_storage_sign_left", 70, 55, 35, 25), 1153 ("item_storage_sign_right", 55, 55, 30, 25), 1154 ("item_morning_market_sign_left", 128, 55, 31, 27), 1155 ("npc_kirk_above", 65, 55, 25, 40), 1156 ("npc_kirk_mainland_right", 55, 45, 30, 25), 1157 ("npc_kirk_mainland_below", 70, 40, 15, 40), 1158 ("npc_joe_left", 125, 55, 34, 25), 1159 ("npc_lukia_right", 38, 55, 34, 25), 1160 ("dialogue_box_upper_border", 0, 96, 160, 8), 1161 ("npc_lucus_above", 70, 55, 19, 40), 1162 ("npc_lucus_left", 70, 55, 34, 25), 1163 ("npc_lucus_right", 55, 55, 34, 25), 1164 ("npc_lyla_right", 54, 55, 34, 25), 1165 ("item_meal_set_empty_1", 80, 40, 30, 15), 1166 ("item_meal_set_empty_2", 80, 80, 30, 15), 1167 ("item_coffee_above", 72, 55, 15, 39), 1168 ("item_coffee_below", 72, 40, 13, 30), 1169 ("entrance", 40, 65, 80, 80), 1170 ("top_entrance", 45, 0, 70, 40), 1171 ("outside_chicken_coop", 45, 40, 45, 35), 1172 ("outside_hot_spring", 45, 40, 45, 35), 1173 ("item_tea_above", 70, 55, 17, 41), 1174 ("item_tea_below", 70, 40, 17, 39), 1175 ("item_asparagus_seeds_above", 72, 55, 17, 41), 1176 ("item_asparagus_seeds_below", 72, 40, 17, 39), 1177 ("item_right_cow_stall_block", 115, 25, 45, 25), 1178 ("item_right_cow_stall_block_below", 115, 25, 45, 50), 1179 ("item_right_cow_stall_block_left", 95, 35, 55, 35), 1180 ("item_cow_stall_block_2", 112, 35, 38, 35), 1181 ("item_ferry_sign_above", 70, 60, 16, 45), 1182 ("item_ferry_sign_left", 70, 60, 30, 28), 1183 ("item_fireplace_below", 105, 40, 15, 40), 1184 ("item_rock_left", 95, 55, 30, 25), 1185 ("item_target_potato_below", 56, 32, 48, 47), 1186 ("item_center_spotato_above", 56, 60, 47, 50), 1187 ("item_center_watermelon_above", 30, 25, 49, 54), 1188 ("npc_kate_left", 50, 58, 28, 19), 1189 ("npc_kate_right", 63, 55, 33, 23), 1190 ("npc_kate_below", 63, 39, 16, 40), 1191 ("item_weed_left", 70, 0, 50, 45), 1192 ("item_cherry_left", 95, 50, 30, 38), 1193 ("item_fodder_set_below", 113, 40, 14, 40), 1194 ("item_horse_medicine_below", 97, 40, 14, 40), 1195 ("item_chicken_silo_left1", 96, 50, 30, 30), 1196 ("item_chicken_silo_left2", 96, 65, 30, 30), 1197 ("item_chicken_silo_above", 110, 50, 20, 40), 1198 ("item_topmost_chicken_stall_block", 115, 36, 35, 29), 1199 ("item_next_to_topmost_chicken_stall_block", 97, 36, 53, 29), 1200 ("item_fodder_set", 97, 40, 30, 5), 1201 ("item_horse_medicine", 97, 40, 30, 5), 1202 ("item_next_to_hatching_box", 7, 62, 36, 38), 1203 ("item_hatching_box", 7, 62, 23, 38), 1204 ("item_stairs", 40, 0, 95, 80), 1205 ("item_flower_vase_empty_1", 0, 80, 50, 15), 1206 ("item_flower_vase_empty_2", 0, 40, 50, 5), 1207 ("item_flower_vase_above", 32, 56, 16, 40), 1208 ("item_flower_vase_below", 32, 40, 16, 40), 1209 ("item_horse_saddle_empty_1", 78, 80, 80, 15), 1210 ("item_horse_saddle_empty_2", 78, 40, 80, 15), 1211 ("item_horse_saddle_above", 72, 55, 24, 41), 1212 ("item_horse_saddle_below", 78, 40, 17, 39), 1213 ("item_center_eggplant_above", 52, 15, 51, 64), 1214 ("item_center_eggplant_left", 70, 32, 48, 48), 1215 ("menu_box", 106, 0, 53, 122), 1216 ("player_top_left", 0, 0, 35, 40), 1217 ("item_berry_above", 0, 50, 35, 45), 1218 ("sell_animal_section_1", 62, 80, 83, 16), 1219 ("sell_animal_section_2", 62, 40, 83, 16), 1220 ("item_sell_chicken_below", 80, 40, 15, 40), 1221 ("item_sell_chicken_above", 78, 56, 17, 39), 1222 ("item_center_turnip_below", 56, 32, 48, 47), 1223 ("item_bookshelf_below", 125, 32, 25, 48), 1224 ] 1225 override_multi_targets = { 1226 "dialogue_bottom_right": [ 1227 "normal_dialogue", 1228 "mainland_dialogue", 1229 ], 1230 "dialogue_box_bottom": [ 1231 "reading_secret_garden_sign", 1232 "reading_storage_sign", 1233 "reading_morning_market_sign", 1234 "reading_ferry_sign", 1235 "found_secret_savings", 1236 "select_tea", 1237 "select_asparagus_seeds", 1238 "select_coffee", 1239 "select_turnip_seeds", 1240 "select_turnip_seeds_portion", 1241 "select_potato_seeds", 1242 "select_potato_seeds_portion", 1243 "bought_turnip_seeds", 1244 "bought_potato_seeds", 1245 "select_meal_set", 1246 "speaking_to_kate", 1247 "farm_label", 1248 "village_label", 1249 "grassland_label", 1250 "forest_label", 1251 "cliff_label", 1252 "mountain_label", 1253 "shopping_mall_label", 1254 "farmers_union_label", 1255 "aquarium_label", 1256 "theatre_label", 1257 "selected_fodder_set", 1258 "selected_horse_medicine", 1259 "bought_from_farmers_union", 1260 "bought_from_flower_shop", 1261 "animal_sold", 1262 "finish_animal_ch2", 1263 ], 1264 "item_rock_left": [ 1265 "next_to_rock_right", 1266 "rock_cleared", 1267 ], 1268 "item_target_potato_below": [ 1269 "next_to_target_potato_up", 1270 "target_potato_harvested", 1271 ], 1272 "item_center_spotato_above": [ 1273 "next_to_spotato_down", 1274 "center_spotato_watered", 1275 ], 1276 "item_center_watermelon_above": [ 1277 "next_to_center_watermelon_down", 1278 "center_watermelon_watered", 1279 ], 1280 "npc_kate_left": [ 1281 "next_to_kate_right", 1282 ], 1283 "npc_kate_right": [ 1284 "next_to_kate_left", 1285 ], 1286 "npc_kate_below": [ 1287 "next_to_kate_up", 1288 ], 1289 "item_weed_left": [ 1290 "next_to_weed_right", 1291 "weed_removed", 1292 ], 1293 "item_cherry_left": [ 1294 "next_to_cherry_right", 1295 "cherry_picked", 1296 ], 1297 "item_chicken_silo_left1": [ 1298 "next_to_chicken_silo_right1", 1299 "got_fodder_from_chicken_silo_right1", 1300 ], 1301 "item_chicken_silo_left2": [ 1302 "next_to_chicken_silo_right2", 1303 "got_fodder_from_chicken_silo_right2", 1304 ], 1305 "item_chicken_silo_above": [ 1306 "next_to_chicken_silo_down", 1307 "got_fodder_from_chicken_silo_down", 1308 ], 1309 "item_topmost_chicken_stall_block": [ 1310 "filled_topmost_chicken_stall_block", 1311 ], 1312 "item_next_to_topmost_chicken_stall_block": [ 1313 "next_to_topmost_chicken_stall_block", 1314 ], 1315 "item_next_to_hatching_box": [ 1316 "next_to_hatching_box", 1317 ], 1318 "item_hatching_box": [ 1319 "dropped_egg_into_hatching_box", 1320 ], 1321 "item_stairs": [ 1322 "next_to_stairs_1", 1323 "next_to_stairs_2", 1324 "next_to_stairs_3", 1325 ], 1326 "item_fodder_set_below": [ 1327 "next_to_fodder_set_up", 1328 ], 1329 "item_horse_medicine_below": [ 1330 "next_to_horse_medicine_up", 1331 ], 1332 "item_fodder_set": [ 1333 "picked_fodder_set", 1334 ], 1335 "item_horse_medicine": [ 1336 "picked_horse_medicine", 1337 ], 1338 "item_storage_sign_below": [ 1339 "next_to_storage_sign_up", 1340 ], 1341 "item_storage_sign_left": [ 1342 "next_to_storage_sign_right", 1343 ], 1344 "item_storage_sign_right": [ 1345 "next_to_storage_sign_left", 1346 ], 1347 "item_morning_market_sign_left": [ 1348 "next_to_morning_market_sign_right", 1349 ], 1350 "npc_kirk_above": [ 1351 "next_to_kirk_down", 1352 ], 1353 "npc_kirk_mainland_right": [ 1354 "next_to_kirk_mainland_left", 1355 ], 1356 "npc_kirk_mainland_below": [ 1357 "next_to_kirk_mainland_up", 1358 ], 1359 "npc_joe_left": [ 1360 "next_to_joe_right", 1361 ], 1362 "dialogue_box_upper_border": [ 1363 "speaking_to_kirk_village", 1364 "speaking_to_joe", 1365 "speaking_to_lukia", 1366 "speaking_to_lucus", 1367 "speaking_to_lyla", 1368 ], 1369 "item_secret_garden_sign_above": [ 1370 "next_to_secret_garden_sign_down", 1371 ], 1372 "item_secret_garden_sign_right": [ 1373 "next_to_secret_garden_sign_left", 1374 ], 1375 "item_turnip_seeds_above": [ 1376 "next_to_turnip_seeds_down", 1377 ], 1378 "item_turnip_seeds_below": [ 1379 "next_to_turnip_seeds_up", 1380 ], 1381 "item_potato_seeds_above": [ 1382 "next_to_potato_seeds_down", 1383 ], 1384 "item_potato_seeds_below": [ 1385 "next_to_potato_seeds_up", 1386 ], 1387 "npc_lukia_right": [ 1388 "next_to_lukia_left", 1389 ], 1390 "npc_lucus_above": [ 1391 "next_to_lucus_down", 1392 ], 1393 "npc_lucus_left": [ 1394 "next_to_lucus_right", 1395 ], 1396 "npc_lucus_right": [ 1397 "next_to_lucus_left", 1398 ], 1399 "npc_lyla_right": [ 1400 "next_to_lyla_left", 1401 ], 1402 "outside_chicken_coop": [ 1403 "outside_chicken_coop_left", 1404 "outside_chicken_coop_right", 1405 "outside_chicken_coop_up", 1406 ], 1407 "item_flower_vase_empty_1": [ 1408 "bought_flower_vase_1", 1409 ], 1410 "item_flower_vase_empty_2": [ 1411 "bought_flower_vase_2", 1412 ], 1413 "item_flower_vase_above": [ 1414 "next_to_vase_down", 1415 ], 1416 "item_flower_vase_below": [ 1417 "next_to_vase_up", 1418 ], 1419 "item_center_eggplant_above": [ 1420 "next_to_eggplant_down", 1421 "center_eggplant_harvested_down", 1422 ], 1423 "item_center_eggplant_left": [ 1424 "next_to_eggplant_right", 1425 "center_eggplant_harvested_right", 1426 ], 1427 "menu_box": [ 1428 "choose_may", 1429 ], 1430 "player_top_left": [ 1431 "display_player_status", 1432 ], 1433 "item_berry_above": [ 1434 "next_to_berry_down", 1435 "berry_picked_above", 1436 ], 1437 "sell_animal_section_1": [ 1438 "selling_animal_1", 1439 ], 1440 "sell_animal_section_2": [ 1441 "selling_animal_2", 1442 ], 1443 "item_sell_chicken_below": [ 1444 "next_to_sell_chicken_up", 1445 ], 1446 "item_sell_chicken_above": [ 1447 "next_to_sell_chicken_down", 1448 ], 1449 "item_center_turnip_below": [ 1450 "next_to_center_turnip_up", 1451 "center_turnip_harvested", 1452 ], 1453 "item_bookshelf_below": [ 1454 "next_to_bookshelf_up", 1455 ], 1456 "item_horse_saddle_empty_1": [ 1457 "bought_horse_saddle_1", 1458 ], 1459 "item_horse_saddle_empty_2": [ 1460 "bought_horse_saddle_2", 1461 ], 1462 "item_horse_saddle_above": [ 1463 "next_to_horse_saddle_down", 1464 ], 1465 "item_horse_saddle_below": [ 1466 "next_to_horse_saddle_up", 1467 ], 1468 "item_meal_set_empty_1": [ 1469 "bought_meal_set_1", 1470 ], 1471 "item_meal_set_empty_2": [ 1472 "bought_meal_set_2", 1473 ], 1474 "item_coffee_above": [ 1475 "next_to_coffee_down", 1476 ], 1477 "item_coffee_below": [ 1478 "next_to_coffee_up", 1479 ], 1480 "top_entrance": [ 1481 "village_entrance", 1482 ], 1483 "entrance": [ 1484 "village_ferry_entrance", 1485 "farm_entrance", 1486 "grassland_entrance", 1487 "forest_entrance", 1488 "cliff_entrance", 1489 "mountain_entrance", 1490 "shopping_mall_entrance", 1491 "farmers_union_entrance", 1492 "aquarium_entrance", 1493 "theatre_entrance", 1494 "hot_spring_entrance", 1495 "shopping_mall_second_floor", 1496 ], 1497 "item_tea_above": [ 1498 "next_to_tea_down", 1499 ], 1500 "item_tea_below": [ 1501 "next_to_tea_up", 1502 ], 1503 "item_asparagus_seeds_above": [ 1504 "next_to_asparagus_seeds_down", 1505 ], 1506 "item_asparagus_seeds_below": [ 1507 "next_to_asparagus_seeds_up", 1508 ], 1509 "item_right_cow_stall_block": [ 1510 "filled_right_cow_stall_block", 1511 ], 1512 "item_right_cow_stall_block_below": [ 1513 "next_to_right_cow_stall_block_up", 1514 ], 1515 "item_right_cow_stall_block_left": [ 1516 "next_to_right_cow_stall_block_right", 1517 ], 1518 "item_cow_stall_block_2": [ 1519 "filled_cow_stall_block_right", 1520 ], 1521 "item_ferry_sign_above": [ 1522 "next_to_ferry_sign_down", 1523 ], 1524 "item_ferry_sign_left": [ 1525 "next_to_ferry_sign_right", 1526 ], 1527 "item_fireplace_below": [ 1528 "next_to_fireplace_up", 1529 ], 1530 "outside_hot_spring": [ 1531 "outside_hot_spring_left", 1532 "outside_hot_spring_right", 1533 "outside_hot_spring_up", 1534 ], 1535 } 1536 super().__init__( 1537 pyboy, 1538 variant="harvest_moon_3", 1539 parameters=parameters, 1540 override_regions=override_regions, 1541 override_multi_target_regions=override_multi_target_regions, 1542 override_multi_targets=override_multi_targets, 1543 ) 1544 1545 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 1546 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1547 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1548 self.DIALOGUE_TYPES, captured 1549 ): 1550 return True 1551 return False 1552 1553 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1554 box = self.capture_named_region( 1555 current_frame=current_screen, name="dialogue_box_bottom" 1556 ) 1557 perc_lt_255 = np.mean(box < 255) 1558 if perc_lt_255 < 0.082: # Empirical threshold 1559 return True 1560 return False 1561 1562 def is_in_menu(self, current_screen: np.ndarray) -> bool: 1563 return self.named_region_matches_target(current_screen, "menu_top_right") 1564 1565 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 1566 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1567 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1568 self.DIALOGUE_TYPES, captured 1569 ): 1570 return True 1571 return False 1572 1573 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 1574 if self.is_in_menu(current_screen): 1575 return AgentState.IN_MENU 1576 if self.is_in_dialogue(current_screen): 1577 return AgentState.IN_DIALOGUE 1578 return AgentState.FREE_ROAM
33class AgentState(Enum): 34 """ 35 0. FREE_ROAM: The agent is freely roaming the game world. 36 1. IN_DIALOGUE: The agent is currently in a dialogue state. 37 2. IN_MENU: The agent has a menu open. 38 """ 39 40 FREE_ROAM = 0 41 IN_DIALOGUE = 1 42 IN_MENU = 2 43 IN_STORAGE_LIST = 3
- FREE_ROAM: The agent is freely roaming the game world.
- IN_DIALOGUE: The agent is currently in a dialogue state.
- IN_MENU: The agent has a menu open.
46class HarvestMoonStateParser(StateParser, ABC): 47 """ 48 Base class for Harvest Moon GBC game state parsers. Uses visual screen regions to parse game state. 49 Defines common named screen regions and methods for determining game states such as being in dialogue. 50 51 Can be used to determine the exact AgentState. 52 """ 53 54 COMMON_REGIONS = [] 55 """ List of common single-target named screen regions for Harvest Moon games. """ 56 57 COMMON_MULTI_TARGET_REGIONS = [ 58 ("screen", 0, 0, 150, 140), 59 ("screen_middle", 65, 55, 20, 20), 60 ("dialogue_box_top", 58, 10, 40, 10), 61 ] 62 """ List of common multi-target named screen regions for Harvest Moon games. 63 64 - dialogue_bottom_right: Bottom-right corner of the dialogue box (x=153, y=135, 10x10px). 65 Capture while dialogue is visible in dev_play: `c dialogue_bottom_right,<type_name>` 66 - screen_bottom: Bottom strip of the screen (x=0, y=100, 160x40px). 67 Useful for detecting locations and events. Capture in dev_play: `c screen_bottom,<target_name>` 68 """ 69 70 COMMON_MULTI_TARGETS = { 71 "screen_bottom": [ 72 "cow_barn_entrance", 73 "chicken_coop_entrance", 74 ], 75 } 76 """ Common multi-targets for the common multi-target named screen regions. 77 - screen_bottom: Location/event captures for the bottom strip of the screen. 78 """ 79 80 def __init__( 81 self, 82 variant: str, 83 pyboy: PyBoy, 84 parameters: dict, 85 additional_named_screen_region_details: List[ 86 Tuple[str, int, int, int, int] 87 ] = [], 88 additional_multi_target_named_screen_region_details: List[ 89 Tuple[str, int, int, int, int] 90 ] = [], 91 override_multi_targets: Dict[str, List[str]] = {}, 92 ): 93 """ 94 Initializes the HarvestMoonStateParser. 95 Args: 96 pyboy (PyBoy): The PyBoy emulator instance. 97 parameters (dict): Configuration parameters for the emulator. 98 additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include. 99 additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include. 100 override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions. 101 """ 102 verify_parameters(parameters) 103 regions = _get_proper_regions( 104 override_regions=additional_named_screen_region_details, 105 base_regions=self.COMMON_REGIONS, 106 ) 107 self.variant = variant 108 if f"{variant}_rom_data_path" not in parameters: 109 log_error( 110 f"ROM data path not found for variant: {variant}. Add {variant}_rom_data_path to the config files. See configs/pokemon_red_vars.yaml for an example", 111 parameters, 112 ) 113 self.rom_data_path = parameters[f"{variant}_rom_data_path"] 114 """ Path to the ROM data directory for the specific Harvest Moon variant.""" 115 captures_dir = self.rom_data_path + "/captures/" 116 named_screen_regions = [] 117 for region_name, x, y, w, h in regions: 118 region = NamedScreenRegion( 119 region_name, 120 x, 121 y, 122 w, 123 h, 124 parameters=parameters, 125 target_path=os.path.join(captures_dir, region_name), 126 ) 127 named_screen_regions.append(region) 128 multi_target_regions = _get_proper_regions( 129 override_regions=additional_multi_target_named_screen_region_details, 130 base_regions=self.COMMON_MULTI_TARGET_REGIONS, 131 ) 132 multi_target_region_names = [region[0] for region in multi_target_regions] 133 multi_targets = self.COMMON_MULTI_TARGETS.copy() 134 for key in override_multi_targets: 135 if key in multi_targets: 136 multi_targets[key].extend(override_multi_targets[key]) 137 else: 138 multi_targets[key] = override_multi_targets[key] 139 multi_target_provided_region_names = list(multi_targets.keys()) 140 if not set(multi_target_provided_region_names).issubset( 141 set(multi_target_region_names) 142 ): 143 log_error( 144 f"Multi-target regions provided in multi_targets do not match the defined multi-target regions. Provided: {multi_target_provided_region_names}, Defined: {multi_target_region_names}", 145 parameters, 146 ) 147 for region_name, x, y, w, h in multi_target_regions: 148 region_target_paths = {} 149 subdir = captures_dir + f"/{region_name}/" 150 for target_name in multi_targets.get(region_name, []): 151 region_target_paths[target_name] = os.path.join(subdir, target_name) 152 region = NamedScreenRegion( 153 region_name, 154 x, 155 y, 156 w, 157 h, 158 parameters=parameters, 159 multi_target_paths=region_target_paths, 160 ) 161 named_screen_regions.append(region) 162 super().__init__(pyboy, parameters, named_screen_regions) 163 164 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 165 if self.is_in_dialogue(current_screen): 166 return AgentState.IN_DIALOGUE 167 return AgentState.FREE_ROAM
Base class for Harvest Moon GBC game state parsers. Uses visual screen regions to parse game state. Defines common named screen regions and methods for determining game states such as being in dialogue.
Can be used to determine the exact AgentState.
80 def __init__( 81 self, 82 variant: str, 83 pyboy: PyBoy, 84 parameters: dict, 85 additional_named_screen_region_details: List[ 86 Tuple[str, int, int, int, int] 87 ] = [], 88 additional_multi_target_named_screen_region_details: List[ 89 Tuple[str, int, int, int, int] 90 ] = [], 91 override_multi_targets: Dict[str, List[str]] = {}, 92 ): 93 """ 94 Initializes the HarvestMoonStateParser. 95 Args: 96 pyboy (PyBoy): The PyBoy emulator instance. 97 parameters (dict): Configuration parameters for the emulator. 98 additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include. 99 additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include. 100 override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions. 101 """ 102 verify_parameters(parameters) 103 regions = _get_proper_regions( 104 override_regions=additional_named_screen_region_details, 105 base_regions=self.COMMON_REGIONS, 106 ) 107 self.variant = variant 108 if f"{variant}_rom_data_path" not in parameters: 109 log_error( 110 f"ROM data path not found for variant: {variant}. Add {variant}_rom_data_path to the config files. See configs/pokemon_red_vars.yaml for an example", 111 parameters, 112 ) 113 self.rom_data_path = parameters[f"{variant}_rom_data_path"] 114 """ Path to the ROM data directory for the specific Harvest Moon variant.""" 115 captures_dir = self.rom_data_path + "/captures/" 116 named_screen_regions = [] 117 for region_name, x, y, w, h in regions: 118 region = NamedScreenRegion( 119 region_name, 120 x, 121 y, 122 w, 123 h, 124 parameters=parameters, 125 target_path=os.path.join(captures_dir, region_name), 126 ) 127 named_screen_regions.append(region) 128 multi_target_regions = _get_proper_regions( 129 override_regions=additional_multi_target_named_screen_region_details, 130 base_regions=self.COMMON_MULTI_TARGET_REGIONS, 131 ) 132 multi_target_region_names = [region[0] for region in multi_target_regions] 133 multi_targets = self.COMMON_MULTI_TARGETS.copy() 134 for key in override_multi_targets: 135 if key in multi_targets: 136 multi_targets[key].extend(override_multi_targets[key]) 137 else: 138 multi_targets[key] = override_multi_targets[key] 139 multi_target_provided_region_names = list(multi_targets.keys()) 140 if not set(multi_target_provided_region_names).issubset( 141 set(multi_target_region_names) 142 ): 143 log_error( 144 f"Multi-target regions provided in multi_targets do not match the defined multi-target regions. Provided: {multi_target_provided_region_names}, Defined: {multi_target_region_names}", 145 parameters, 146 ) 147 for region_name, x, y, w, h in multi_target_regions: 148 region_target_paths = {} 149 subdir = captures_dir + f"/{region_name}/" 150 for target_name in multi_targets.get(region_name, []): 151 region_target_paths[target_name] = os.path.join(subdir, target_name) 152 region = NamedScreenRegion( 153 region_name, 154 x, 155 y, 156 w, 157 h, 158 parameters=parameters, 159 multi_target_paths=region_target_paths, 160 ) 161 named_screen_regions.append(region) 162 super().__init__(pyboy, parameters, named_screen_regions)
Initializes the HarvestMoonStateParser.
Arguments:
- pyboy (PyBoy): The PyBoy emulator instance.
- parameters (dict): Configuration parameters for the emulator.
- additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include.
- additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include.
- override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions.
List of common multi-target named screen regions for Harvest Moon games.
- dialogue_bottom_right: Bottom-right corner of the dialogue box (x=153, y=135, 10x10px).
Capture while dialogue is visible in dev_play:
c dialogue_bottom_right,<type_name> - screen_bottom: Bottom strip of the screen (x=0, y=100, 160x40px).
Useful for detecting locations and events. Capture in dev_play:
c screen_bottom,<target_name>
Common multi-targets for the common multi-target named screen regions.
- screen_bottom: Location/event captures for the bottom strip of the screen.
Inherited Members
- gameboy_worlds.emulation.parser.StateParser
- named_screen_regions
- image_references
- bit_count
- read_m
- read_bits
- read_bit
- read_m_bit
- get_raised_flags
- get_current_frame
- capture_box
- capture_square_centered
- draw_box
- draw_square_centered
- capture_named_region
- compare_named_region_against_target
- named_region_matches_target
- compare_named_region_against_multi_target
- named_region_matches_multi_target
- draw_named_region
- draw_grid_overlay
- capture_grid_cells
- reform_image
- get_quadrant_frame
- get_image_reference
170class BaseHarvestMoonStateParser(HarvestMoonStateParser, ABC): 171 """ 172 Game state parser for all Harvest Moon GBC-based games. 173 """ 174 175 REGIONS = [ 176 ] 177 """ Additional named screen regions specific to Harvest Moon GBC games. 178 """ 179 180 MULTI_TARGET_REGIONS = [ 181 ] 182 """ Additional multi-target named screen regions specific to Harvest Moon GBC games. 183 """ 184 185 def __init__( 186 self, 187 pyboy: PyBoy, 188 variant: str, 189 parameters: dict, 190 override_regions: List[Tuple[str, int, int, int, int]] = [], 191 override_multi_target_regions: List[Tuple[str, int, int, int, int]] = [], 192 override_multi_targets: Dict[str, List[str]] = {}, 193 ): 194 self.REGIONS = _get_proper_regions( 195 override_regions=override_regions, base_regions=self.REGIONS 196 ) 197 self.MULTI_TARGET_REGIONS = _get_proper_regions( 198 override_regions=override_multi_target_regions, 199 base_regions=self.MULTI_TARGET_REGIONS, 200 ) 201 super().__init__( 202 variant=variant, 203 pyboy=pyboy, 204 parameters=parameters, 205 additional_named_screen_region_details=self.REGIONS, 206 additional_multi_target_named_screen_region_details=self.MULTI_TARGET_REGIONS, 207 override_multi_targets=override_multi_targets, 208 ) 209 210 def __repr__(self): 211 return f"<HarvestMoonParser(variant={self.variant})>"
Game state parser for all Harvest Moon GBC-based games.
185 def __init__( 186 self, 187 pyboy: PyBoy, 188 variant: str, 189 parameters: dict, 190 override_regions: List[Tuple[str, int, int, int, int]] = [], 191 override_multi_target_regions: List[Tuple[str, int, int, int, int]] = [], 192 override_multi_targets: Dict[str, List[str]] = {}, 193 ): 194 self.REGIONS = _get_proper_regions( 195 override_regions=override_regions, base_regions=self.REGIONS 196 ) 197 self.MULTI_TARGET_REGIONS = _get_proper_regions( 198 override_regions=override_multi_target_regions, 199 base_regions=self.MULTI_TARGET_REGIONS, 200 ) 201 super().__init__( 202 variant=variant, 203 pyboy=pyboy, 204 parameters=parameters, 205 additional_named_screen_region_details=self.REGIONS, 206 additional_multi_target_named_screen_region_details=self.MULTI_TARGET_REGIONS, 207 override_multi_targets=override_multi_targets, 208 )
Initializes the HarvestMoonStateParser.
Arguments:
- pyboy (PyBoy): The PyBoy emulator instance.
- parameters (dict): Configuration parameters for the emulator.
- additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include.
- additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include.
- override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions.
Additional multi-target named screen regions specific to Harvest Moon GBC games.
Inherited Members
- HarvestMoonStateParser
- COMMON_REGIONS
- COMMON_MULTI_TARGET_REGIONS
- COMMON_MULTI_TARGETS
- variant
- rom_data_path
- get_agent_state
- gameboy_worlds.emulation.parser.StateParser
- named_screen_regions
- image_references
- bit_count
- read_m
- read_bits
- read_bit
- read_m_bit
- get_raised_flags
- get_current_frame
- capture_box
- capture_square_centered
- draw_box
- draw_square_centered
- capture_named_region
- compare_named_region_against_target
- named_region_matches_target
- compare_named_region_against_multi_target
- named_region_matches_multi_target
- draw_named_region
- draw_grid_overlay
- capture_grid_cells
- reform_image
- get_quadrant_frame
- get_image_reference
213class HarvestMoon1Parser(BaseHarvestMoonStateParser): 214 215 DIALOGUE_TYPES = [ 216 "home_dialogue", 217 "shop_dialogue", 218 "church_dialogue", 219 "harvest_spirits_dialogue", 220 "read_signs_dialogue", 221 "evening_dialogue", 222 "barn_dialogue", 223 "winter_read_signs_dialogue", 224 "winter_evening_dialogue", 225 ] 226 def __init__(self, pyboy, parameters): 227 override_regions = [ 228 ("menu_top_right", 153, 0, 5, 5), 229 ("storage_list_top_right", 153, 0, 6, 6), 230 ] 231 232 override_multi_target_regions = [ 233 ("dialogue_bottom_right", 153, 135, 10, 10), 234 ("screen", 0, 0, 160, 143), 235 ("screen_middle", 65, 63, 30, 30), 236 ("screen_bottom", 0, 100, 160, 40), 237 ("dialogue_box_top", 60, 11, 40, 8), 238 ("dialogue_box_top_mid", 68, 11, 22, 8), 239 ("dialogue_box_top_short", 71, 11, 15, 8), 240 ("dialogue_box_bottom", 0, 105, 160, 35), 241 ("item_bed", 0, 40, 40, 40), 242 ("item_watercan_above", 56, 85, 15, 35), 243 ("item_watercan_right", 55, 80, 30, 20), 244 ("item_watercan_below", 56, 70, 15, 30), 245 ("item_cowbell_above", 39, 49, 15, 35), 246 ("item_cowbell_below", 39, 70, 15, 30), 247 ("item_sickle_above", 88, 85, 15, 35), 248 ("item_sickle_left", 70, 80, 30, 20), 249 ("item_sickle_below", 88, 70, 15, 30), 250 ("item_hoe_above", 102, 85, 15, 35), 251 ("item_hoe_below", 102, 70, 15, 30), 252 ("item_hammer_above", 120, 85, 15, 35), 253 ("item_hammer_below", 120, 70, 15, 30), 254 ("item_grass_seed_above", 56, 55, 15, 35), 255 ("item_grass_seed_right", 55, 70, 30, 20), 256 ("item_grass_seed_below", 56, 70, 15, 30), 257 ("item_storage_list", 0, 40, 20, 30), 258 ("item_spirit_left", 70, 50, 30, 30), 259 ("item_spirit_below", 70, 50, 30, 30), 260 ("item_spirit_above", 70, 50, 15, 50), 261 ("item_safe_below", 40, 30, 15, 40), 262 ("item_lost_bird_left", 70, 65, 30, 25), 263 ("item_lost_bird_right", 60, 65, 30, 25), 264 ("item_lost_bird_below", 70, 50, 20, 35), 265 ("item_blue_hair_girl_left", 80, 20, 30, 30), 266 ("item_blue_hair_girl_right", 95, 20, 30, 30), 267 ("item_blue_hair_girl_below", 95, 20, 20, 40), 268 ("item_golden_hair_girl_above", 32, 40, 15, 40), 269 ("item_golden_hair_girl_right", 30, 55, 35, 25), 270 ("item_golden_hair_girl_below", 32, 55, 15, 35), 271 ("item_pink_hair_girl_left", 32, 68, 33, 22), 272 ("item_pink_hair_girl_right", 48, 68, 30, 22), 273 ("item_pink_hair_girl_above", 48, 68, 15, 38), 274 ("item_blue_hair_girl_wg_left", 80, 25, 30, 20), 275 ("item_blue_hair_girl_wg_right", 97, 25, 30, 21), 276 ("item_blue_hair_girl_wg_below", 97, 25, 13, 35), 277 ("item_pink_hair_girl_wg_left", 32, 68, 33, 22), 278 ("item_pink_hair_girl_wg_right", 48, 68, 30, 22), 279 ("item_pink_hair_girl_wg_above", 48, 68, 15, 38), 280 ("item_red_hair_girl_wg_left", 80, 68, 30, 22), 281 ("item_red_hair_girl_wg_right", 97, 68, 30, 22), 282 ("item_red_hair_girl_wg_above", 97, 68, 13, 40), 283 ("item_chicken_stall_block1", 5, 40, 25, 20), 284 ("item_next_to_chicken_stall_block1", 5, 55, 25, 25), 285 ("item_chicken_silo_left", 100, 40, 30, 30), 286 ("item_chicken_silo_below1", 120, 50, 15, 35), 287 ("item_chicken_silo_below2", 135, 50, 15, 35), 288 ("item_cow_feeding_stall", 55, 25, 30, 45), 289 ("item_cow_feeding_stall_right", 55, 25, 45, 45), 290 ("item_egg_left", 89, 75, 31, 25), 291 ("item_egg_above", 105, 78, 15, 37), 292 ("item_egg_right", 110, 75, 22, 25), 293 ("item_hatching_box", 120, 70, 35, 30), 294 ("turnip_center", 70, 90, 20, 20), 295 ("turnip_top", 70, 70, 20, 35), 296 ("item_turnip_field", 55, 65, 47, 54), 297 ("item_turnip_field_water", 40, 58, 47, 47), 298 ("item_potato_field", 55, 40, 47, 54), 299 ("item_rock_left", 0, 65, 45, 20), 300 ("item_rightmost_rock_above", 55, 60, 33, 40), 301 ("item_weed_above", 15, 65, 30, 50), 302 ("item_top_left_weed", 25, 60, 25, 25), 303 ("item_grassland_right", 50, 60, 35, 30), 304 ("item_center_grassline", 40, 70, 95, 20), 305 ("item_broken_fence_field", 63, 55, 30, 30), 306 ("item_fence_field", 0, 40, 30, 60), 307 ("center_sign", 55, 65, 50, 15), 308 ("screen_top_half", 0, 0, 160, 65), 309 ("screen_bottom_half", 0, 75, 160, 65), 310 ("left_border_frame", 0, 0, 5, 140), 311 ] 312 313 override_multi_targets = { 314 "dialogue_bottom_right":[ 315 "home_dialogue", 316 "shop_dialogue", 317 "church_dialogue", 318 "harvest_spirits_dialogue", 319 "read_signs_dialogue", 320 "evening_dialogue", 321 "barn_dialogue", 322 "winter_read_signs_dialogue", 323 "winter_evening_dialogue", 324 ], 325 "screen_middle":[ 326 "outside_cow_barn_left", 327 "outside_cow_barn_right", 328 "outside_cow_barn_up", 329 "outside_chicken_coop_left", 330 "outside_chicken_coop_right", 331 "outside_chicken_coop_up", 332 "outside_storage_left", 333 "outside_storage_right", 334 "outside_storage_up", 335 ], 336 "screen_bottom": [ 337 "cow_barn_entrance", 338 "chicken_coop_entrance", 339 "storage_shed_entrance", 340 ], 341 "dialogue_box_bottom":[ 342 "found_rainy_money", 343 "select_material", 344 "select_home_expansion", 345 "select_chicken", 346 "select_selling_chicken", 347 "select_cow", 348 "bought_named_cow", 349 "select_cow_brush", 350 "select_saddlebag", 351 "select_milker", 352 "choose_yes_for_sleep", 353 "fed_spirit", 354 "helped_spirit_earthquake", 355 "select_rice_ball", 356 "select_croissant", 357 "select_cake", 358 "select_grape_juice", 359 "found_bird_for_friend", 360 "speaking_to_blue_hair_girl", 361 "speaking_to_golden_hair_girl", 362 "speaking_to_pink_hair_girl", 363 "speaking_to_blue_hair_girl_wg", 364 "speaking_to_pink_hair_girl_wg", 365 "speaking_to_red_hair_girl_wg", 366 "option_to_pray", 367 "praying", 368 ], 369 "item_bed":[ 370 "sleep_in_bed", 371 ], 372 "item_storage_list":[ 373 "next_to_storage_list", 374 ], 375 "item_watercan_above":[ 376 "pickup_watercan_down", 377 ], 378 "item_watercan_right":[ 379 "pickup_watercan_left", 380 ], 381 "item_cowbell_above":[ 382 "next_to_cowbell_down", 383 ], 384 "item_cowbell_below":[ 385 "next_to_cowbell_up", 386 ], 387 "item_watercan_below":[ 388 "pickup_watercan_up", 389 ], 390 "item_sickle_above":[ 391 "pickup_sickle_down", 392 ], 393 "item_sickle_left":[ 394 "pickup_sickle_right", 395 ], 396 "item_sickle_below":[ 397 "pickup_sickle_up", 398 ], 399 "item_hoe_above":[ 400 "pickup_hoe_down", 401 ], 402 "item_hoe_below":[ 403 "pickup_hoe_up", 404 ], 405 "item_hammer_above":[ 406 "pickup_hammer_down", 407 ], 408 "item_hammer_below":[ 409 "pickup_hammer_up", 410 ], 411 "item_grass_seed_above":[ 412 "pickup_grass_seed_down", 413 ], 414 "item_grass_seed_right":[ 415 "pickup_grass_seed_left", 416 ], 417 "item_grass_seed_below":[ 418 "pickup_grass_seed_up", 419 ], 420 "item_spirit_left":[ 421 "feed_spirit_right", 422 "help_spirit_earthquake_right", 423 ], 424 "item_spirit_above":[ 425 "feed_spirit_down", 426 "help_spirit_earthquake_down", 427 ], 428 "item_spirit_below":[ 429 "feed_spirit_up", 430 "help_spirit_earthquake_up", 431 ], 432 "item_safe_below":[ 433 "next_to_safe_up", 434 "next_to_safe_left", 435 ], 436 "item_lost_bird_left":[ 437 "find_lost_bird_right", 438 ], 439 "item_lost_bird_right":[ 440 "find_lost_bird_left", 441 ], 442 "item_lost_bird_below":[ 443 "find_lost_bird_up", 444 ], 445 "item_blue_hair_girl_left":[ 446 "next_to_blue_hair_girl_right", 447 ], 448 "item_blue_hair_girl_right":[ 449 "next_to_blue_hair_girl_left", 450 ], 451 "item_blue_hair_girl_below":[ 452 "next_to_blue_hair_girl_up", 453 ], 454 "item_golden_hair_girl_above":[ 455 "next_to_golden_hair_girl_down", 456 ], 457 "item_golden_hair_girl_right":[ 458 "next_to_golden_hair_girl_left", 459 ], 460 "item_golden_hair_girl_below":[ 461 "next_to_golden_hair_girl_up", 462 ], 463 "item_pink_hair_girl_left":[ 464 "next_to_pink_hair_girl_right", 465 ], 466 "item_pink_hair_girl_right":[ 467 "next_to_pink_hair_girl_left", 468 ], 469 "item_pink_hair_girl_above":[ 470 "next_to_pink_hair_girl_down", 471 ], 472 "item_blue_hair_girl_wg_left": [ 473 "next_to_blue_hair_girl_wg_right", 474 ], 475 "item_blue_hair_girl_wg_right": [ 476 "next_to_blue_hair_girl_wg_left", 477 ], 478 "item_blue_hair_girl_wg_below": [ 479 "next_to_blue_hair_girl_wg_up", 480 ], 481 "item_pink_hair_girl_wg_left": [ 482 "next_to_pink_hair_girl_wg_right", 483 ], 484 "item_pink_hair_girl_wg_right": [ 485 "next_to_pink_hair_girl_wg_left", 486 ], 487 "item_pink_hair_girl_wg_above": [ 488 "next_to_pink_hair_girl_wg_down", 489 ], 490 "item_red_hair_girl_wg_left": [ 491 "next_to_red_hair_girl_wg_right", 492 ], 493 "item_red_hair_girl_wg_right": [ 494 "next_to_red_hair_girl_wg_left", 495 ], 496 "item_red_hair_girl_wg_above": [ 497 "next_to_red_hair_girl_wg_down", 498 ], 499 "item_chicken_stall_block1":[ 500 "filled_chicken_stall_block1", 501 ], 502 "item_next_to_chicken_stall_block1":[ 503 "next_to_chicken_stall_block1", 504 ], 505 "item_chicken_silo_left":[ 506 "next_to_chicken_silo_right", 507 "got_fodder_from_chicken_silo_right", 508 ], 509 "item_chicken_silo_below1":[ 510 "next_to_chicken_silo_up1", 511 "got_fodder_from_chicken_silo_up1", 512 ], 513 "item_chicken_silo_below2":[ 514 "next_to_chicken_silo_up2", 515 "got_fodder_from_chicken_silo_up2", 516 ], 517 "item_cow_feeding_stall": [ 518 "cow_feeding_stall_filled", 519 ], 520 "item_cow_feeding_stall_right": [ 521 "next_to_cow_feeding_stall_left", 522 ], 523 "item_egg_left": [ 524 "next_to_egg_right", 525 ], 526 "item_egg_above": [ 527 "next_to_egg_down", 528 ], 529 "item_egg_right": [ 530 "next_to_egg_left", 531 ], 532 "item_hatching_box": [ 533 "dropped_egg_into_hatching_box", 534 ], 535 "dialogue_box_top":[ 536 "pick_up_watercan", 537 "pick_up_grass_seed", 538 ], 539 "dialogue_box_top_mid":[ 540 "pick_up_sickle", 541 "pick_up_hammer", 542 "pick_up_cowbell", 543 ], 544 "dialogue_box_top_short":[ 545 "pick_up_hoe", 546 ], 547 "turnip_center":[ 548 "finish_watering_1", 549 "finish_watering_2", 550 ], 551 "turnip_top":[ 552 "ready_to_water_1", 553 "ready_to_water_2", 554 ], 555 "item_turnip_field": [ 556 "next_to_center_turnip_down_1", 557 "next_to_center_turnip_down_2", 558 "center_turnip_harvested_1", 559 "center_turnip_harvested_2", 560 ], 561 "item_turnip_field_water":[ 562 "next_to_center_turnip_left_1", 563 "next_to_center_turnip_left_2", 564 "center_turnip_watered_1", 565 "center_turnip_watered_2", 566 ], 567 "item_potato_field": [ 568 "next_to_center_potato_up_1", 569 "next_to_center_potato_up_2", 570 "next_to_center_potato_below_up_1", 571 "next_to_center_potato_below_up_2", 572 "center_potato_watered_1", 573 "center_potato_watered_2", 574 "center_potato_harvested_1", 575 "center_potato_harvested_2", 576 ], 577 "item_rock_left": [ 578 "next_to_rock_right", 579 "rock_cleared", 580 ], 581 "item_rightmost_rock_above": [ 582 "next_to_rightmost_rock_down", 583 "rightmost_rock_cleared", 584 ], 585 "item_weed_above": [ 586 "next_to_lowest_weed_down", 587 "lowest_weed_removed", 588 "lowest_weed_cut", 589 ], 590 "item_top_left_weed": [ 591 "next_to_top_left_weed_up", 592 "top_left_weed_removed", 593 "top_left_weed_cut", 594 ], 595 "item_grassland_right": [ 596 "next_to_grassland_left", 597 ], 598 "item_center_grassline": [ 599 "center_grass_harvested_1", 600 "center_grass_harvested_2", 601 ], 602 "item_broken_fence_field": [ 603 "picked_up_broken_fence_up", 604 "picked_up_broken_fence_down", 605 "picked_up_broken_fence_left", 606 "picked_up_broken_fence_right", 607 ], 608 "item_fence_field": [ 609 "restored_fence", 610 ], 611 "center_sign":[ 612 "outside_carpenter", 613 "outside_animal_shop", 614 "outside_tool_shop", 615 "outside_restaurant", 616 "outside_juice_bar", 617 "outside_church", 618 ], 619 "screen_bottom_half":[ 620 "bought_material", 621 "home_expansion_estimate", 622 "bought_chicken", 623 "sold_chicken", 624 "bought_cow_brush", 625 "bought_saddlebag", 626 "bought_milker", 627 "option_to_buy_rice_ball", 628 "bought_rice_ball", 629 "option_to_buy_croissant", 630 "bought_croissant", 631 "option_to_buy_cake", 632 "bought_cake", 633 "option_to_buy_grape_juice", 634 "bought_grape_juice", 635 ], 636 "screen_top_half":[ 637 "in_carpenter", 638 "in_animal_shop", 639 "in_tool_shop", 640 "in_restaurant", 641 "in_juice_bar", 642 "in_church", 643 ], 644 "left_border_frame":[ 645 "open_storage_list", 646 ], 647 } 648 649 super().__init__( 650 pyboy, 651 variant="harvest_moon_1", 652 parameters=parameters, 653 override_regions=override_regions, 654 override_multi_target_regions=override_multi_target_regions, 655 override_multi_targets=override_multi_targets, 656 ) 657 658 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 659 """ 660 Determines if a dialogue box is currently open by checking the dialogue bottom right region. 661 Args: 662 current_screen (np.ndarray): The current screen frame from the emulator. 663 Returns: 664 bool: True if a dialogue box is open, False otherwise. 665 """ 666 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 667 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 668 self.DIALOGUE_TYPES, captured 669 ) 670 671 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 672 box = self.capture_named_region( 673 current_frame=current_screen, name="dialogue_box_bottom" 674 ) 675 perc_lt_255 = np.mean(box < 255) 676 if perc_lt_255 < 0.082: # Empirical threshold 677 return True 678 return False 679 680 def is_in_menu(self, current_screen: np.ndarray) -> bool: 681 return self.named_region_matches_target(current_screen, "menu_top_right") 682 683 def is_in_storage_list(self, current_screen: np.ndarray) -> bool: 684 return self.named_region_matches_target(current_screen, "storage_list_top_right") 685 686 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 687 """ 688 Returns True if the dialogue_bottom_right region matches any of the saved dialogue type targets. 689 """ 690 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 691 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 692 self.DIALOGUE_TYPES, captured 693 ) 694 695 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 696 """ 697 Determines the current agent state based on the screen. 698 699 Args: 700 current_screen (np.ndarray): The current screen frame from the emulator. 701 702 Returns: 703 AgentState: The current agent state. 704 """ 705 if self.is_in_menu(current_screen): 706 return AgentState.IN_MENU 707 if self.is_in_storage_list(current_screen): 708 return AgentState.IN_STORAGE_LIST 709 if self.is_in_dialogue(current_screen): 710 return AgentState.IN_DIALOGUE 711 return AgentState.FREE_ROAM
Game state parser for all Harvest Moon GBC-based games.
226 def __init__(self, pyboy, parameters): 227 override_regions = [ 228 ("menu_top_right", 153, 0, 5, 5), 229 ("storage_list_top_right", 153, 0, 6, 6), 230 ] 231 232 override_multi_target_regions = [ 233 ("dialogue_bottom_right", 153, 135, 10, 10), 234 ("screen", 0, 0, 160, 143), 235 ("screen_middle", 65, 63, 30, 30), 236 ("screen_bottom", 0, 100, 160, 40), 237 ("dialogue_box_top", 60, 11, 40, 8), 238 ("dialogue_box_top_mid", 68, 11, 22, 8), 239 ("dialogue_box_top_short", 71, 11, 15, 8), 240 ("dialogue_box_bottom", 0, 105, 160, 35), 241 ("item_bed", 0, 40, 40, 40), 242 ("item_watercan_above", 56, 85, 15, 35), 243 ("item_watercan_right", 55, 80, 30, 20), 244 ("item_watercan_below", 56, 70, 15, 30), 245 ("item_cowbell_above", 39, 49, 15, 35), 246 ("item_cowbell_below", 39, 70, 15, 30), 247 ("item_sickle_above", 88, 85, 15, 35), 248 ("item_sickle_left", 70, 80, 30, 20), 249 ("item_sickle_below", 88, 70, 15, 30), 250 ("item_hoe_above", 102, 85, 15, 35), 251 ("item_hoe_below", 102, 70, 15, 30), 252 ("item_hammer_above", 120, 85, 15, 35), 253 ("item_hammer_below", 120, 70, 15, 30), 254 ("item_grass_seed_above", 56, 55, 15, 35), 255 ("item_grass_seed_right", 55, 70, 30, 20), 256 ("item_grass_seed_below", 56, 70, 15, 30), 257 ("item_storage_list", 0, 40, 20, 30), 258 ("item_spirit_left", 70, 50, 30, 30), 259 ("item_spirit_below", 70, 50, 30, 30), 260 ("item_spirit_above", 70, 50, 15, 50), 261 ("item_safe_below", 40, 30, 15, 40), 262 ("item_lost_bird_left", 70, 65, 30, 25), 263 ("item_lost_bird_right", 60, 65, 30, 25), 264 ("item_lost_bird_below", 70, 50, 20, 35), 265 ("item_blue_hair_girl_left", 80, 20, 30, 30), 266 ("item_blue_hair_girl_right", 95, 20, 30, 30), 267 ("item_blue_hair_girl_below", 95, 20, 20, 40), 268 ("item_golden_hair_girl_above", 32, 40, 15, 40), 269 ("item_golden_hair_girl_right", 30, 55, 35, 25), 270 ("item_golden_hair_girl_below", 32, 55, 15, 35), 271 ("item_pink_hair_girl_left", 32, 68, 33, 22), 272 ("item_pink_hair_girl_right", 48, 68, 30, 22), 273 ("item_pink_hair_girl_above", 48, 68, 15, 38), 274 ("item_blue_hair_girl_wg_left", 80, 25, 30, 20), 275 ("item_blue_hair_girl_wg_right", 97, 25, 30, 21), 276 ("item_blue_hair_girl_wg_below", 97, 25, 13, 35), 277 ("item_pink_hair_girl_wg_left", 32, 68, 33, 22), 278 ("item_pink_hair_girl_wg_right", 48, 68, 30, 22), 279 ("item_pink_hair_girl_wg_above", 48, 68, 15, 38), 280 ("item_red_hair_girl_wg_left", 80, 68, 30, 22), 281 ("item_red_hair_girl_wg_right", 97, 68, 30, 22), 282 ("item_red_hair_girl_wg_above", 97, 68, 13, 40), 283 ("item_chicken_stall_block1", 5, 40, 25, 20), 284 ("item_next_to_chicken_stall_block1", 5, 55, 25, 25), 285 ("item_chicken_silo_left", 100, 40, 30, 30), 286 ("item_chicken_silo_below1", 120, 50, 15, 35), 287 ("item_chicken_silo_below2", 135, 50, 15, 35), 288 ("item_cow_feeding_stall", 55, 25, 30, 45), 289 ("item_cow_feeding_stall_right", 55, 25, 45, 45), 290 ("item_egg_left", 89, 75, 31, 25), 291 ("item_egg_above", 105, 78, 15, 37), 292 ("item_egg_right", 110, 75, 22, 25), 293 ("item_hatching_box", 120, 70, 35, 30), 294 ("turnip_center", 70, 90, 20, 20), 295 ("turnip_top", 70, 70, 20, 35), 296 ("item_turnip_field", 55, 65, 47, 54), 297 ("item_turnip_field_water", 40, 58, 47, 47), 298 ("item_potato_field", 55, 40, 47, 54), 299 ("item_rock_left", 0, 65, 45, 20), 300 ("item_rightmost_rock_above", 55, 60, 33, 40), 301 ("item_weed_above", 15, 65, 30, 50), 302 ("item_top_left_weed", 25, 60, 25, 25), 303 ("item_grassland_right", 50, 60, 35, 30), 304 ("item_center_grassline", 40, 70, 95, 20), 305 ("item_broken_fence_field", 63, 55, 30, 30), 306 ("item_fence_field", 0, 40, 30, 60), 307 ("center_sign", 55, 65, 50, 15), 308 ("screen_top_half", 0, 0, 160, 65), 309 ("screen_bottom_half", 0, 75, 160, 65), 310 ("left_border_frame", 0, 0, 5, 140), 311 ] 312 313 override_multi_targets = { 314 "dialogue_bottom_right":[ 315 "home_dialogue", 316 "shop_dialogue", 317 "church_dialogue", 318 "harvest_spirits_dialogue", 319 "read_signs_dialogue", 320 "evening_dialogue", 321 "barn_dialogue", 322 "winter_read_signs_dialogue", 323 "winter_evening_dialogue", 324 ], 325 "screen_middle":[ 326 "outside_cow_barn_left", 327 "outside_cow_barn_right", 328 "outside_cow_barn_up", 329 "outside_chicken_coop_left", 330 "outside_chicken_coop_right", 331 "outside_chicken_coop_up", 332 "outside_storage_left", 333 "outside_storage_right", 334 "outside_storage_up", 335 ], 336 "screen_bottom": [ 337 "cow_barn_entrance", 338 "chicken_coop_entrance", 339 "storage_shed_entrance", 340 ], 341 "dialogue_box_bottom":[ 342 "found_rainy_money", 343 "select_material", 344 "select_home_expansion", 345 "select_chicken", 346 "select_selling_chicken", 347 "select_cow", 348 "bought_named_cow", 349 "select_cow_brush", 350 "select_saddlebag", 351 "select_milker", 352 "choose_yes_for_sleep", 353 "fed_spirit", 354 "helped_spirit_earthquake", 355 "select_rice_ball", 356 "select_croissant", 357 "select_cake", 358 "select_grape_juice", 359 "found_bird_for_friend", 360 "speaking_to_blue_hair_girl", 361 "speaking_to_golden_hair_girl", 362 "speaking_to_pink_hair_girl", 363 "speaking_to_blue_hair_girl_wg", 364 "speaking_to_pink_hair_girl_wg", 365 "speaking_to_red_hair_girl_wg", 366 "option_to_pray", 367 "praying", 368 ], 369 "item_bed":[ 370 "sleep_in_bed", 371 ], 372 "item_storage_list":[ 373 "next_to_storage_list", 374 ], 375 "item_watercan_above":[ 376 "pickup_watercan_down", 377 ], 378 "item_watercan_right":[ 379 "pickup_watercan_left", 380 ], 381 "item_cowbell_above":[ 382 "next_to_cowbell_down", 383 ], 384 "item_cowbell_below":[ 385 "next_to_cowbell_up", 386 ], 387 "item_watercan_below":[ 388 "pickup_watercan_up", 389 ], 390 "item_sickle_above":[ 391 "pickup_sickle_down", 392 ], 393 "item_sickle_left":[ 394 "pickup_sickle_right", 395 ], 396 "item_sickle_below":[ 397 "pickup_sickle_up", 398 ], 399 "item_hoe_above":[ 400 "pickup_hoe_down", 401 ], 402 "item_hoe_below":[ 403 "pickup_hoe_up", 404 ], 405 "item_hammer_above":[ 406 "pickup_hammer_down", 407 ], 408 "item_hammer_below":[ 409 "pickup_hammer_up", 410 ], 411 "item_grass_seed_above":[ 412 "pickup_grass_seed_down", 413 ], 414 "item_grass_seed_right":[ 415 "pickup_grass_seed_left", 416 ], 417 "item_grass_seed_below":[ 418 "pickup_grass_seed_up", 419 ], 420 "item_spirit_left":[ 421 "feed_spirit_right", 422 "help_spirit_earthquake_right", 423 ], 424 "item_spirit_above":[ 425 "feed_spirit_down", 426 "help_spirit_earthquake_down", 427 ], 428 "item_spirit_below":[ 429 "feed_spirit_up", 430 "help_spirit_earthquake_up", 431 ], 432 "item_safe_below":[ 433 "next_to_safe_up", 434 "next_to_safe_left", 435 ], 436 "item_lost_bird_left":[ 437 "find_lost_bird_right", 438 ], 439 "item_lost_bird_right":[ 440 "find_lost_bird_left", 441 ], 442 "item_lost_bird_below":[ 443 "find_lost_bird_up", 444 ], 445 "item_blue_hair_girl_left":[ 446 "next_to_blue_hair_girl_right", 447 ], 448 "item_blue_hair_girl_right":[ 449 "next_to_blue_hair_girl_left", 450 ], 451 "item_blue_hair_girl_below":[ 452 "next_to_blue_hair_girl_up", 453 ], 454 "item_golden_hair_girl_above":[ 455 "next_to_golden_hair_girl_down", 456 ], 457 "item_golden_hair_girl_right":[ 458 "next_to_golden_hair_girl_left", 459 ], 460 "item_golden_hair_girl_below":[ 461 "next_to_golden_hair_girl_up", 462 ], 463 "item_pink_hair_girl_left":[ 464 "next_to_pink_hair_girl_right", 465 ], 466 "item_pink_hair_girl_right":[ 467 "next_to_pink_hair_girl_left", 468 ], 469 "item_pink_hair_girl_above":[ 470 "next_to_pink_hair_girl_down", 471 ], 472 "item_blue_hair_girl_wg_left": [ 473 "next_to_blue_hair_girl_wg_right", 474 ], 475 "item_blue_hair_girl_wg_right": [ 476 "next_to_blue_hair_girl_wg_left", 477 ], 478 "item_blue_hair_girl_wg_below": [ 479 "next_to_blue_hair_girl_wg_up", 480 ], 481 "item_pink_hair_girl_wg_left": [ 482 "next_to_pink_hair_girl_wg_right", 483 ], 484 "item_pink_hair_girl_wg_right": [ 485 "next_to_pink_hair_girl_wg_left", 486 ], 487 "item_pink_hair_girl_wg_above": [ 488 "next_to_pink_hair_girl_wg_down", 489 ], 490 "item_red_hair_girl_wg_left": [ 491 "next_to_red_hair_girl_wg_right", 492 ], 493 "item_red_hair_girl_wg_right": [ 494 "next_to_red_hair_girl_wg_left", 495 ], 496 "item_red_hair_girl_wg_above": [ 497 "next_to_red_hair_girl_wg_down", 498 ], 499 "item_chicken_stall_block1":[ 500 "filled_chicken_stall_block1", 501 ], 502 "item_next_to_chicken_stall_block1":[ 503 "next_to_chicken_stall_block1", 504 ], 505 "item_chicken_silo_left":[ 506 "next_to_chicken_silo_right", 507 "got_fodder_from_chicken_silo_right", 508 ], 509 "item_chicken_silo_below1":[ 510 "next_to_chicken_silo_up1", 511 "got_fodder_from_chicken_silo_up1", 512 ], 513 "item_chicken_silo_below2":[ 514 "next_to_chicken_silo_up2", 515 "got_fodder_from_chicken_silo_up2", 516 ], 517 "item_cow_feeding_stall": [ 518 "cow_feeding_stall_filled", 519 ], 520 "item_cow_feeding_stall_right": [ 521 "next_to_cow_feeding_stall_left", 522 ], 523 "item_egg_left": [ 524 "next_to_egg_right", 525 ], 526 "item_egg_above": [ 527 "next_to_egg_down", 528 ], 529 "item_egg_right": [ 530 "next_to_egg_left", 531 ], 532 "item_hatching_box": [ 533 "dropped_egg_into_hatching_box", 534 ], 535 "dialogue_box_top":[ 536 "pick_up_watercan", 537 "pick_up_grass_seed", 538 ], 539 "dialogue_box_top_mid":[ 540 "pick_up_sickle", 541 "pick_up_hammer", 542 "pick_up_cowbell", 543 ], 544 "dialogue_box_top_short":[ 545 "pick_up_hoe", 546 ], 547 "turnip_center":[ 548 "finish_watering_1", 549 "finish_watering_2", 550 ], 551 "turnip_top":[ 552 "ready_to_water_1", 553 "ready_to_water_2", 554 ], 555 "item_turnip_field": [ 556 "next_to_center_turnip_down_1", 557 "next_to_center_turnip_down_2", 558 "center_turnip_harvested_1", 559 "center_turnip_harvested_2", 560 ], 561 "item_turnip_field_water":[ 562 "next_to_center_turnip_left_1", 563 "next_to_center_turnip_left_2", 564 "center_turnip_watered_1", 565 "center_turnip_watered_2", 566 ], 567 "item_potato_field": [ 568 "next_to_center_potato_up_1", 569 "next_to_center_potato_up_2", 570 "next_to_center_potato_below_up_1", 571 "next_to_center_potato_below_up_2", 572 "center_potato_watered_1", 573 "center_potato_watered_2", 574 "center_potato_harvested_1", 575 "center_potato_harvested_2", 576 ], 577 "item_rock_left": [ 578 "next_to_rock_right", 579 "rock_cleared", 580 ], 581 "item_rightmost_rock_above": [ 582 "next_to_rightmost_rock_down", 583 "rightmost_rock_cleared", 584 ], 585 "item_weed_above": [ 586 "next_to_lowest_weed_down", 587 "lowest_weed_removed", 588 "lowest_weed_cut", 589 ], 590 "item_top_left_weed": [ 591 "next_to_top_left_weed_up", 592 "top_left_weed_removed", 593 "top_left_weed_cut", 594 ], 595 "item_grassland_right": [ 596 "next_to_grassland_left", 597 ], 598 "item_center_grassline": [ 599 "center_grass_harvested_1", 600 "center_grass_harvested_2", 601 ], 602 "item_broken_fence_field": [ 603 "picked_up_broken_fence_up", 604 "picked_up_broken_fence_down", 605 "picked_up_broken_fence_left", 606 "picked_up_broken_fence_right", 607 ], 608 "item_fence_field": [ 609 "restored_fence", 610 ], 611 "center_sign":[ 612 "outside_carpenter", 613 "outside_animal_shop", 614 "outside_tool_shop", 615 "outside_restaurant", 616 "outside_juice_bar", 617 "outside_church", 618 ], 619 "screen_bottom_half":[ 620 "bought_material", 621 "home_expansion_estimate", 622 "bought_chicken", 623 "sold_chicken", 624 "bought_cow_brush", 625 "bought_saddlebag", 626 "bought_milker", 627 "option_to_buy_rice_ball", 628 "bought_rice_ball", 629 "option_to_buy_croissant", 630 "bought_croissant", 631 "option_to_buy_cake", 632 "bought_cake", 633 "option_to_buy_grape_juice", 634 "bought_grape_juice", 635 ], 636 "screen_top_half":[ 637 "in_carpenter", 638 "in_animal_shop", 639 "in_tool_shop", 640 "in_restaurant", 641 "in_juice_bar", 642 "in_church", 643 ], 644 "left_border_frame":[ 645 "open_storage_list", 646 ], 647 } 648 649 super().__init__( 650 pyboy, 651 variant="harvest_moon_1", 652 parameters=parameters, 653 override_regions=override_regions, 654 override_multi_target_regions=override_multi_target_regions, 655 override_multi_targets=override_multi_targets, 656 )
Initializes the HarvestMoonStateParser.
Arguments:
- pyboy (PyBoy): The PyBoy emulator instance.
- parameters (dict): Configuration parameters for the emulator.
- additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include.
- additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include.
- override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions.
658 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 659 """ 660 Determines if a dialogue box is currently open by checking the dialogue bottom right region. 661 Args: 662 current_screen (np.ndarray): The current screen frame from the emulator. 663 Returns: 664 bool: True if a dialogue box is open, False otherwise. 665 """ 666 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 667 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 668 self.DIALOGUE_TYPES, captured 669 )
Determines if a dialogue box is currently open by checking the dialogue bottom right region.
Arguments:
- current_screen (np.ndarray): The current screen frame from the emulator.
Returns:
bool: True if a dialogue box is open, False otherwise.
686 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 687 """ 688 Returns True if the dialogue_bottom_right region matches any of the saved dialogue type targets. 689 """ 690 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 691 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 692 self.DIALOGUE_TYPES, captured 693 )
Returns True if the dialogue_bottom_right region matches any of the saved dialogue type targets.
695 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 696 """ 697 Determines the current agent state based on the screen. 698 699 Args: 700 current_screen (np.ndarray): The current screen frame from the emulator. 701 702 Returns: 703 AgentState: The current agent state. 704 """ 705 if self.is_in_menu(current_screen): 706 return AgentState.IN_MENU 707 if self.is_in_storage_list(current_screen): 708 return AgentState.IN_STORAGE_LIST 709 if self.is_in_dialogue(current_screen): 710 return AgentState.IN_DIALOGUE 711 return AgentState.FREE_ROAM
Determines the current agent state based on the screen.
Arguments:
- current_screen (np.ndarray): The current screen frame from the emulator.
Returns:
AgentState: The current agent state.
Inherited Members
- HarvestMoonStateParser
- COMMON_REGIONS
- COMMON_MULTI_TARGET_REGIONS
- COMMON_MULTI_TARGETS
- variant
- rom_data_path
- gameboy_worlds.emulation.parser.StateParser
- named_screen_regions
- image_references
- bit_count
- read_m
- read_bits
- read_bit
- read_m_bit
- get_raised_flags
- get_current_frame
- capture_box
- capture_square_centered
- draw_box
- draw_square_centered
- capture_named_region
- compare_named_region_against_target
- named_region_matches_target
- compare_named_region_against_multi_target
- named_region_matches_multi_target
- draw_named_region
- draw_grid_overlay
- capture_grid_cells
- reform_image
- get_quadrant_frame
- get_image_reference
713class HarvestMoon2Parser(BaseHarvestMoonStateParser): 714 DIALOGUE_TYPES = [ 715 "home_dialogue", 716 "carpenter_dialogue", 717 "hospital_dialogue", 718 "tool_shop_dialogue", 719 "animal_shop_dialogue", 720 "restaurant_dialogue", 721 "library_dialogue", 722 "flower_shop_dialogue", 723 "church_dialogue", 724 "read_signs_dialogue", 725 "barn_dialogue", 726 ] 727 728 def __init__(self, pyboy, parameters): 729 override_regions = [ 730 ("menu_top_right", 153, 8, 6, 6), 731 ("storage_list_top_right", 153, 0, 6, 6), 732 ] 733 override_multi_target_regions = [ 734 ("dialogue_bottom_right", 153, 135, 10, 10), 735 ("screen_middle", 50, 25, 40, 43), 736 ("outside_barns", 40, 15, 50, 53), 737 ("screen_bottom", 0, 95, 160, 40), 738 ("dialogue_box_top", 60, 11, 40, 8), 739 ("dialogue_box_bottom", 0, 105, 160, 35), 740 ("hospital_location", 65, 0, 55, 70), 741 ("tool_shop_location", 65, 0, 55, 70), 742 ("carpenter_location", 35, 0, 55, 70), 743 ("animal_shop_location", 65, 0, 55, 70), 744 ("library_location", 35, 0, 55, 70), 745 ("flower_shop_location", 30, 0, 105, 70), 746 ("restaurant_location", 40, 0, 70, 70), 747 ("item_clock_below", 95, 25, 15, 45), 748 ("item_bed", 0, 40, 40, 40), 749 ("item_diary", 45, 40, 20, 40), 750 ("item_storage_list", 0, 40, 20, 30), 751 ("item_village_sign_above", 70, 85, 20, 35), 752 ("item_village_sign_left", 55, 70, 30, 25), 753 ("item_village_sign_right", 75, 70, 30, 25), 754 ("item_farm_sign_above", 70, 85, 20, 35), 755 ("item_farm_sign_left", 55, 70, 30, 25), 756 ("item_farm_sign_right", 75, 70, 30, 25), 757 ("item_secret_garden_sign_above", 74, 50, 15, 45), 758 ("item_secret_garden_sign_right", 58, 50, 27, 25), 759 ("item_secret_garden_sign_left", 72, 50, 30, 25), 760 ("item_crop_field_sign_above", 71, 55, 24, 40), 761 ("item_notice_board_above", 70, 85, 20, 35), 762 ("item_notice_board_left", 55, 70, 30, 25), 763 ("item_notice_board_right", 75, 70, 30, 25), 764 ("turnip_center", 70, 90, 20, 20), 765 ("turnip_top", 70, 70, 20, 35), 766 ("item_eggplant_field", 55, 25, 50, 45), 767 ("item_carrot_field", 55, 25, 50, 45), 768 ("item_next_to_shipping_box", 0, 20, 30, 50), 769 ("item_shipping_box_field", 0, 20, 45, 25), 770 ("item_start_line", 0, 20, 30, 50), 771 ("item_distance_markers", 65, 40, 30, 30), 772 ("item_potato_field", 32, 40, 50, 45), 773 ("item_asparagus_field", 70, 40, 50, 45), 774 ("item_corn_field", 55, 40, 48, 47), 775 ("item_cabbage_field", 55, 40, 48, 47), 776 ("item_center_corn_above", 58, 50, 45, 50), 777 ("item_leftmost_weed_right", 10, 50, 35, 23), 778 ("item_leftmost_weed_above", 10, 50, 20, 43), 779 ("item_berry_left", 70, 39, 32, 31), 780 ("item_berry_above", 68, 38, 18, 48), 781 ("item_chicken_stall_block1", 5, 20, 35, 20), 782 ("item_next_to_chicken_stall_block1", 5, 35, 35, 30), 783 ("item_chicken_silo_left1", 100, 30, 30, 30), 784 ("item_chicken_silo_left2", 100, 40, 30, 30), 785 ("item_chicken_silo_below", 115, 38, 15, 35), 786 ("item_next_to_hatching_box", 113, 60, 37, 40), 787 ("item_hatching_box", 129, 66, 16, 30), 788 ("npc_blue_hair_girl_left", 66, 39, 29, 21), 789 ("npc_blue_hair_girl_below", 72, 28, 16, 39), 790 ("npc_blue_hair_girl_right", 56, 39, 29, 21), 791 ("npc_purple_hair_girl_left", 98, 39, 30, 21), 792 ("npc_purple_hair_girl_below", 114, 31, 16, 39), 793 ("npc_blonde_girl_right", 31, 48, 29, 21), 794 ("npc_blonde_girl_above", 31, 48, 14, 47), 795 ("center_sign", 55, 65, 50, 15), 796 ("screen_top_half", 0, 0, 160, 65), 797 ("screen_bottom_half", 0, 75, 160, 65), 798 ("left_border_frame", 0, 0, 5, 140), 799 ("top_left_label", 0, 0, 160, 15), 800 ("equipment_region_1", 45, 15, 26, 17), 801 ("equipment_region_2", 72, 15, 26, 17), 802 ("equipment_region_3", 95, 15, 26, 17), 803 ("equipment_region_4", 119, 15, 26, 17), 804 ] 805 override_multi_targets = { 806 "dialogue_bottom_right": [ 807 "home_dialogue", 808 "carpenter_dialogue", 809 "hospital_dialogue", 810 "tool_shop_dialogue", 811 "animal_shop_dialogue", 812 "restaurant_dialogue", 813 "library_dialogue", 814 "flower_shop_dialogue", 815 "church_dialogue", 816 "read_signs_dialogue", 817 "barn_dialogue", 818 ], 819 "dialogue_box_bottom": [ 820 "found_lucky_money", 821 "option_to_diary_sleep", 822 "reading_secret_garden_sign", 823 "reading_crop_field_sign", 824 "computers_article_selected", 825 "reading_computers_article", 826 "boulders_article_selected", 827 "reading_boulders_article", 828 "crops_article_selected", 829 "reading_crops_article", 830 "select_cow", 831 "bought_named_cow", 832 "select_chicken", 833 "select_selling_chicken", 834 "select_selling_cow", 835 "select_hothouse", 836 "select_bridge", 837 "select_milker", 838 "speaking_to_blue_hair_girl", 839 "speaking_to_purple_hair_girl", 840 "speaking_to_blonde_girl", 841 ], 842 "item_clock_below": [ 843 "next_to_clock_up", 844 ], 845 "flower_shop_location": [ 846 "outside_flower_shop_up", 847 "outside_flower_shop_left", 848 "outside_flower_shop_right", 849 ], 850 "item_bed": [ 851 "sleep_in_bed", 852 ], 853 "item_diary": [ 854 "next_to_diary", 855 ], 856 "item_secret_garden_sign_above": [ 857 "next_to_secret_garden_sign_down", 858 ], 859 "item_secret_garden_sign_right": [ 860 "next_to_secret_garden_sign_left", 861 ], 862 "item_secret_garden_sign_left": [ 863 "next_to_secret_garden_sign_right", 864 ], 865 "item_crop_field_sign_above": [ 866 "next_to_crop_field_sign_down", 867 ], 868 "item_start_line": [ 869 "at_the_start_line", 870 ], 871 "item_next_to_shipping_box": [ 872 "next_to_shipping_box_up", 873 ], 874 "item_shipping_box_field": [ 875 "drop_eggplant_into_shipping_box", 876 ], 877 "item_distance_markers": [ 878 "crossed_500m_line", 879 "crossed_1000m_line", 880 ], 881 "item_eggplant_field": [ 882 "next_to_center_eggplant_up_1", 883 "next_to_center_eggplant_up_2", 884 "center_eggplant_harvested_1", 885 "center_eggplant_harvested_2", 886 ], 887 "item_carrot_field": [ 888 "next_to_center_carrot_up_1", 889 "next_to_center_carrot_up_2", 890 "center_carrot_harvested_1", 891 "center_carrot_harvested_2", 892 ], 893 "item_cabbage_field": [ 894 "at_cabbage_center_1", 895 "at_cabbage_center_2", 896 "cabbage_field_watered_1", 897 "cabbage_field_watered_2", 898 ], 899 "item_potato_field": [ 900 "next_to_center_potato_up_1", 901 "next_to_center_potato_up_2", 902 "center_potato_watered_1", 903 "center_potato_watered_2", 904 ], 905 "item_asparagus_field": [ 906 "next_to_center_asparagus_right_1", 907 "next_to_center_asparagus_right_2", 908 "center_asparagus_watered_1", 909 "center_asparagus_watered_2", 910 ], 911 "item_corn_field": [ 912 "at_corn_center_1", 913 "at_corn_center_2", 914 "corn_field_watered_1", 915 "corn_field_watered_2", 916 ], 917 "item_center_corn_above": [ 918 "next_to_center_corn_down_1", 919 "next_to_center_corn_down_2", 920 "center_corn_cut_1", 921 "center_corn_cut_2", 922 ], 923 "restaurant_location": [ 924 "outside_restaurant_up", 925 "outside_restaurant_left", 926 "outside_restaurant_right", 927 ], 928 "hospital_location": [ 929 "outside_hospital_up", 930 "outside_hospital_left", 931 "outside_hospital_right", 932 ], 933 "tool_shop_location": [ 934 "outside_tool_shop_up", 935 "outside_tool_shop_left", 936 "outside_tool_shop_right", 937 ], 938 "carpenter_location": [ 939 "outside_carpenter_up", 940 "outside_carpenter_left", 941 "outside_carpenter_right", 942 ], 943 "animal_shop_location": [ 944 "outside_animal_shop_up", 945 "outside_animal_shop_left", 946 "outside_animal_shop_right", 947 ], 948 "library_location": [ 949 "outside_library_up", 950 "outside_library_left", 951 "outside_library_right", 952 ], 953 "screen_top_half": [ 954 "in_hospital", 955 "in_tool_shop", 956 "in_carpenter", 957 "in_animal_shop", 958 "in_library", 959 "in_flower_shop", 960 "in_restaurant", 961 "shop_for_construction_estimates", 962 ], 963 "screen_bottom_half": [ 964 "bought_potato_seeds", 965 "bought_asparagus_seeds", 966 "select_potato_seeds", 967 "select_potato_seeds_portion", 968 "select_asparagus_seeds", 969 "select_asparagus_seeds_portion", 970 "bought_lunch_set", 971 "select_lunch_set", 972 "option_to_buy_lunch_set", 973 "bought_beverage_set", 974 "select_beverage_set", 975 "option_to_buy_beverage_set", 976 "bought_todays_special", 977 "select_todays_special", 978 "option_to_buy_todays_special", 979 "bought_chicken", 980 "sold_cow", 981 "sold_chicken", 982 "hothouse_estimate", 983 "bridge_estimate", 984 "bought_milker", 985 ], 986 "outside_barns":[ 987 "outside_cow_barn_left", 988 "outside_cow_barn_right", 989 "outside_cow_barn_up", 990 "outside_chicken_coop_left", 991 "outside_chicken_coop_right", 992 "outside_chicken_coop_up", 993 ], 994 "top_left_label": [ 995 "ready_to_pick_sickle", 996 "ready_to_pick_hammer", 997 "ready_to_pick_fishing_rod", 998 "ready_to_pick_net", 999 "ready_to_pick_rosemary_seeds", 1000 ], 1001 "equipment_region_1": [ 1002 "sprinkler_selected_1", 1003 "sickle_equipped_1", 1004 ], 1005 "equipment_region_2": [ 1006 "ax_selected_2", 1007 "net_equipped", 1008 "rosemary_seeds_equipped", 1009 ], 1010 "equipment_region_3": [ 1011 "hoe_selected_3", 1012 "net_equipped_3", 1013 ], 1014 "equipment_region_4":[ 1015 "empty_hands_selected", 1016 "sickle_equipped", 1017 "hammer_equipped", 1018 "fishing_rod_equipped", 1019 ], 1020 "item_leftmost_weed_right": [ 1021 "next_to_leftmost_weed_left", 1022 "leftmost_weed_removed_left", 1023 ], 1024 "item_leftmost_weed_above": [ 1025 "next_to_leftmost_weed_down", 1026 "leftmost_weed_removed_down", 1027 ], 1028 "item_berry_left": [ 1029 "next_to_berry_right", 1030 "berry_picked_right", 1031 ], 1032 "item_berry_above": [ 1033 "next_to_berry_down_1", 1034 "next_to_berry_down_2", 1035 "berry_picked_above_1", 1036 "berry_picked_above_2", 1037 ], 1038 "item_chicken_stall_block1": [ 1039 "filled_chicken_stall_block1", 1040 ], 1041 "item_next_to_chicken_stall_block1": [ 1042 "next_to_chicken_stall_block1", 1043 ], 1044 "item_chicken_silo_left1": [ 1045 "next_to_chicken_silo_right1", 1046 "got_fodder_from_chicken_silo_right1", 1047 ], 1048 "item_chicken_silo_left2": [ 1049 "next_to_chicken_silo_right2", 1050 "got_fodder_from_chicken_silo_right2", 1051 ], 1052 "item_chicken_silo_below": [ 1053 "next_to_chicken_silo_up", 1054 "got_fodder_from_chicken_silo_up", 1055 ], 1056 "item_next_to_hatching_box": [ 1057 "next_to_hatching_box", 1058 ], 1059 "item_hatching_box": [ 1060 "dropped_egg_into_hatching_box", 1061 ], 1062 "npc_blue_hair_girl_left": [ 1063 "next_to_blue_hair_girl_right", 1064 ], 1065 "npc_blue_hair_girl_below": [ 1066 "next_to_blue_hair_girl_up", 1067 ], 1068 "npc_blue_hair_girl_right": [ 1069 "next_to_blue_hair_girl_left", 1070 ], 1071 "npc_purple_hair_girl_left": [ 1072 "next_to_purple_hair_girl_right", 1073 ], 1074 "npc_purple_hair_girl_below": [ 1075 "next_to_purple_hair_girl_up", 1076 ], 1077 "npc_blonde_girl_right": [ 1078 "next_to_blonde_girl_left", 1079 ], 1080 "npc_blonde_girl_above": [ 1081 "next_to_blonde_girl_down", 1082 ], 1083 } 1084 super().__init__( 1085 pyboy, 1086 variant="harvest_moon_2", 1087 parameters=parameters, 1088 override_regions=override_regions, 1089 override_multi_target_regions=override_multi_target_regions, 1090 override_multi_targets=override_multi_targets, 1091 ) 1092 1093 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 1094 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1095 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1096 self.DIALOGUE_TYPES, captured 1097 ) 1098 1099 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1100 box = self.capture_named_region( 1101 current_frame=current_screen, name="dialogue_box_bottom" 1102 ) 1103 perc_lt_255 = np.mean(box < 255) 1104 if perc_lt_255 < 0.082: # Empirical threshold 1105 return True 1106 return False 1107 1108 def is_in_menu(self, current_screen: np.ndarray) -> bool: 1109 return self.named_region_matches_target(current_screen, "menu_top_right") 1110 1111 def is_in_storage_list(self, current_screen: np.ndarray) -> bool: 1112 return self.named_region_matches_target(current_screen, "storage_list_top_right") 1113 1114 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 1115 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1116 return self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1117 self.DIALOGUE_TYPES, captured 1118 ) 1119 1120 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 1121 if self.is_in_menu(current_screen): 1122 return AgentState.IN_MENU 1123 if self.is_in_storage_list(current_screen): 1124 return AgentState.IN_STORAGE_LIST 1125 if self.is_in_dialogue(current_screen): 1126 return AgentState.IN_DIALOGUE 1127 return AgentState.FREE_ROAM
Game state parser for all Harvest Moon GBC-based games.
728 def __init__(self, pyboy, parameters): 729 override_regions = [ 730 ("menu_top_right", 153, 8, 6, 6), 731 ("storage_list_top_right", 153, 0, 6, 6), 732 ] 733 override_multi_target_regions = [ 734 ("dialogue_bottom_right", 153, 135, 10, 10), 735 ("screen_middle", 50, 25, 40, 43), 736 ("outside_barns", 40, 15, 50, 53), 737 ("screen_bottom", 0, 95, 160, 40), 738 ("dialogue_box_top", 60, 11, 40, 8), 739 ("dialogue_box_bottom", 0, 105, 160, 35), 740 ("hospital_location", 65, 0, 55, 70), 741 ("tool_shop_location", 65, 0, 55, 70), 742 ("carpenter_location", 35, 0, 55, 70), 743 ("animal_shop_location", 65, 0, 55, 70), 744 ("library_location", 35, 0, 55, 70), 745 ("flower_shop_location", 30, 0, 105, 70), 746 ("restaurant_location", 40, 0, 70, 70), 747 ("item_clock_below", 95, 25, 15, 45), 748 ("item_bed", 0, 40, 40, 40), 749 ("item_diary", 45, 40, 20, 40), 750 ("item_storage_list", 0, 40, 20, 30), 751 ("item_village_sign_above", 70, 85, 20, 35), 752 ("item_village_sign_left", 55, 70, 30, 25), 753 ("item_village_sign_right", 75, 70, 30, 25), 754 ("item_farm_sign_above", 70, 85, 20, 35), 755 ("item_farm_sign_left", 55, 70, 30, 25), 756 ("item_farm_sign_right", 75, 70, 30, 25), 757 ("item_secret_garden_sign_above", 74, 50, 15, 45), 758 ("item_secret_garden_sign_right", 58, 50, 27, 25), 759 ("item_secret_garden_sign_left", 72, 50, 30, 25), 760 ("item_crop_field_sign_above", 71, 55, 24, 40), 761 ("item_notice_board_above", 70, 85, 20, 35), 762 ("item_notice_board_left", 55, 70, 30, 25), 763 ("item_notice_board_right", 75, 70, 30, 25), 764 ("turnip_center", 70, 90, 20, 20), 765 ("turnip_top", 70, 70, 20, 35), 766 ("item_eggplant_field", 55, 25, 50, 45), 767 ("item_carrot_field", 55, 25, 50, 45), 768 ("item_next_to_shipping_box", 0, 20, 30, 50), 769 ("item_shipping_box_field", 0, 20, 45, 25), 770 ("item_start_line", 0, 20, 30, 50), 771 ("item_distance_markers", 65, 40, 30, 30), 772 ("item_potato_field", 32, 40, 50, 45), 773 ("item_asparagus_field", 70, 40, 50, 45), 774 ("item_corn_field", 55, 40, 48, 47), 775 ("item_cabbage_field", 55, 40, 48, 47), 776 ("item_center_corn_above", 58, 50, 45, 50), 777 ("item_leftmost_weed_right", 10, 50, 35, 23), 778 ("item_leftmost_weed_above", 10, 50, 20, 43), 779 ("item_berry_left", 70, 39, 32, 31), 780 ("item_berry_above", 68, 38, 18, 48), 781 ("item_chicken_stall_block1", 5, 20, 35, 20), 782 ("item_next_to_chicken_stall_block1", 5, 35, 35, 30), 783 ("item_chicken_silo_left1", 100, 30, 30, 30), 784 ("item_chicken_silo_left2", 100, 40, 30, 30), 785 ("item_chicken_silo_below", 115, 38, 15, 35), 786 ("item_next_to_hatching_box", 113, 60, 37, 40), 787 ("item_hatching_box", 129, 66, 16, 30), 788 ("npc_blue_hair_girl_left", 66, 39, 29, 21), 789 ("npc_blue_hair_girl_below", 72, 28, 16, 39), 790 ("npc_blue_hair_girl_right", 56, 39, 29, 21), 791 ("npc_purple_hair_girl_left", 98, 39, 30, 21), 792 ("npc_purple_hair_girl_below", 114, 31, 16, 39), 793 ("npc_blonde_girl_right", 31, 48, 29, 21), 794 ("npc_blonde_girl_above", 31, 48, 14, 47), 795 ("center_sign", 55, 65, 50, 15), 796 ("screen_top_half", 0, 0, 160, 65), 797 ("screen_bottom_half", 0, 75, 160, 65), 798 ("left_border_frame", 0, 0, 5, 140), 799 ("top_left_label", 0, 0, 160, 15), 800 ("equipment_region_1", 45, 15, 26, 17), 801 ("equipment_region_2", 72, 15, 26, 17), 802 ("equipment_region_3", 95, 15, 26, 17), 803 ("equipment_region_4", 119, 15, 26, 17), 804 ] 805 override_multi_targets = { 806 "dialogue_bottom_right": [ 807 "home_dialogue", 808 "carpenter_dialogue", 809 "hospital_dialogue", 810 "tool_shop_dialogue", 811 "animal_shop_dialogue", 812 "restaurant_dialogue", 813 "library_dialogue", 814 "flower_shop_dialogue", 815 "church_dialogue", 816 "read_signs_dialogue", 817 "barn_dialogue", 818 ], 819 "dialogue_box_bottom": [ 820 "found_lucky_money", 821 "option_to_diary_sleep", 822 "reading_secret_garden_sign", 823 "reading_crop_field_sign", 824 "computers_article_selected", 825 "reading_computers_article", 826 "boulders_article_selected", 827 "reading_boulders_article", 828 "crops_article_selected", 829 "reading_crops_article", 830 "select_cow", 831 "bought_named_cow", 832 "select_chicken", 833 "select_selling_chicken", 834 "select_selling_cow", 835 "select_hothouse", 836 "select_bridge", 837 "select_milker", 838 "speaking_to_blue_hair_girl", 839 "speaking_to_purple_hair_girl", 840 "speaking_to_blonde_girl", 841 ], 842 "item_clock_below": [ 843 "next_to_clock_up", 844 ], 845 "flower_shop_location": [ 846 "outside_flower_shop_up", 847 "outside_flower_shop_left", 848 "outside_flower_shop_right", 849 ], 850 "item_bed": [ 851 "sleep_in_bed", 852 ], 853 "item_diary": [ 854 "next_to_diary", 855 ], 856 "item_secret_garden_sign_above": [ 857 "next_to_secret_garden_sign_down", 858 ], 859 "item_secret_garden_sign_right": [ 860 "next_to_secret_garden_sign_left", 861 ], 862 "item_secret_garden_sign_left": [ 863 "next_to_secret_garden_sign_right", 864 ], 865 "item_crop_field_sign_above": [ 866 "next_to_crop_field_sign_down", 867 ], 868 "item_start_line": [ 869 "at_the_start_line", 870 ], 871 "item_next_to_shipping_box": [ 872 "next_to_shipping_box_up", 873 ], 874 "item_shipping_box_field": [ 875 "drop_eggplant_into_shipping_box", 876 ], 877 "item_distance_markers": [ 878 "crossed_500m_line", 879 "crossed_1000m_line", 880 ], 881 "item_eggplant_field": [ 882 "next_to_center_eggplant_up_1", 883 "next_to_center_eggplant_up_2", 884 "center_eggplant_harvested_1", 885 "center_eggplant_harvested_2", 886 ], 887 "item_carrot_field": [ 888 "next_to_center_carrot_up_1", 889 "next_to_center_carrot_up_2", 890 "center_carrot_harvested_1", 891 "center_carrot_harvested_2", 892 ], 893 "item_cabbage_field": [ 894 "at_cabbage_center_1", 895 "at_cabbage_center_2", 896 "cabbage_field_watered_1", 897 "cabbage_field_watered_2", 898 ], 899 "item_potato_field": [ 900 "next_to_center_potato_up_1", 901 "next_to_center_potato_up_2", 902 "center_potato_watered_1", 903 "center_potato_watered_2", 904 ], 905 "item_asparagus_field": [ 906 "next_to_center_asparagus_right_1", 907 "next_to_center_asparagus_right_2", 908 "center_asparagus_watered_1", 909 "center_asparagus_watered_2", 910 ], 911 "item_corn_field": [ 912 "at_corn_center_1", 913 "at_corn_center_2", 914 "corn_field_watered_1", 915 "corn_field_watered_2", 916 ], 917 "item_center_corn_above": [ 918 "next_to_center_corn_down_1", 919 "next_to_center_corn_down_2", 920 "center_corn_cut_1", 921 "center_corn_cut_2", 922 ], 923 "restaurant_location": [ 924 "outside_restaurant_up", 925 "outside_restaurant_left", 926 "outside_restaurant_right", 927 ], 928 "hospital_location": [ 929 "outside_hospital_up", 930 "outside_hospital_left", 931 "outside_hospital_right", 932 ], 933 "tool_shop_location": [ 934 "outside_tool_shop_up", 935 "outside_tool_shop_left", 936 "outside_tool_shop_right", 937 ], 938 "carpenter_location": [ 939 "outside_carpenter_up", 940 "outside_carpenter_left", 941 "outside_carpenter_right", 942 ], 943 "animal_shop_location": [ 944 "outside_animal_shop_up", 945 "outside_animal_shop_left", 946 "outside_animal_shop_right", 947 ], 948 "library_location": [ 949 "outside_library_up", 950 "outside_library_left", 951 "outside_library_right", 952 ], 953 "screen_top_half": [ 954 "in_hospital", 955 "in_tool_shop", 956 "in_carpenter", 957 "in_animal_shop", 958 "in_library", 959 "in_flower_shop", 960 "in_restaurant", 961 "shop_for_construction_estimates", 962 ], 963 "screen_bottom_half": [ 964 "bought_potato_seeds", 965 "bought_asparagus_seeds", 966 "select_potato_seeds", 967 "select_potato_seeds_portion", 968 "select_asparagus_seeds", 969 "select_asparagus_seeds_portion", 970 "bought_lunch_set", 971 "select_lunch_set", 972 "option_to_buy_lunch_set", 973 "bought_beverage_set", 974 "select_beverage_set", 975 "option_to_buy_beverage_set", 976 "bought_todays_special", 977 "select_todays_special", 978 "option_to_buy_todays_special", 979 "bought_chicken", 980 "sold_cow", 981 "sold_chicken", 982 "hothouse_estimate", 983 "bridge_estimate", 984 "bought_milker", 985 ], 986 "outside_barns":[ 987 "outside_cow_barn_left", 988 "outside_cow_barn_right", 989 "outside_cow_barn_up", 990 "outside_chicken_coop_left", 991 "outside_chicken_coop_right", 992 "outside_chicken_coop_up", 993 ], 994 "top_left_label": [ 995 "ready_to_pick_sickle", 996 "ready_to_pick_hammer", 997 "ready_to_pick_fishing_rod", 998 "ready_to_pick_net", 999 "ready_to_pick_rosemary_seeds", 1000 ], 1001 "equipment_region_1": [ 1002 "sprinkler_selected_1", 1003 "sickle_equipped_1", 1004 ], 1005 "equipment_region_2": [ 1006 "ax_selected_2", 1007 "net_equipped", 1008 "rosemary_seeds_equipped", 1009 ], 1010 "equipment_region_3": [ 1011 "hoe_selected_3", 1012 "net_equipped_3", 1013 ], 1014 "equipment_region_4":[ 1015 "empty_hands_selected", 1016 "sickle_equipped", 1017 "hammer_equipped", 1018 "fishing_rod_equipped", 1019 ], 1020 "item_leftmost_weed_right": [ 1021 "next_to_leftmost_weed_left", 1022 "leftmost_weed_removed_left", 1023 ], 1024 "item_leftmost_weed_above": [ 1025 "next_to_leftmost_weed_down", 1026 "leftmost_weed_removed_down", 1027 ], 1028 "item_berry_left": [ 1029 "next_to_berry_right", 1030 "berry_picked_right", 1031 ], 1032 "item_berry_above": [ 1033 "next_to_berry_down_1", 1034 "next_to_berry_down_2", 1035 "berry_picked_above_1", 1036 "berry_picked_above_2", 1037 ], 1038 "item_chicken_stall_block1": [ 1039 "filled_chicken_stall_block1", 1040 ], 1041 "item_next_to_chicken_stall_block1": [ 1042 "next_to_chicken_stall_block1", 1043 ], 1044 "item_chicken_silo_left1": [ 1045 "next_to_chicken_silo_right1", 1046 "got_fodder_from_chicken_silo_right1", 1047 ], 1048 "item_chicken_silo_left2": [ 1049 "next_to_chicken_silo_right2", 1050 "got_fodder_from_chicken_silo_right2", 1051 ], 1052 "item_chicken_silo_below": [ 1053 "next_to_chicken_silo_up", 1054 "got_fodder_from_chicken_silo_up", 1055 ], 1056 "item_next_to_hatching_box": [ 1057 "next_to_hatching_box", 1058 ], 1059 "item_hatching_box": [ 1060 "dropped_egg_into_hatching_box", 1061 ], 1062 "npc_blue_hair_girl_left": [ 1063 "next_to_blue_hair_girl_right", 1064 ], 1065 "npc_blue_hair_girl_below": [ 1066 "next_to_blue_hair_girl_up", 1067 ], 1068 "npc_blue_hair_girl_right": [ 1069 "next_to_blue_hair_girl_left", 1070 ], 1071 "npc_purple_hair_girl_left": [ 1072 "next_to_purple_hair_girl_right", 1073 ], 1074 "npc_purple_hair_girl_below": [ 1075 "next_to_purple_hair_girl_up", 1076 ], 1077 "npc_blonde_girl_right": [ 1078 "next_to_blonde_girl_left", 1079 ], 1080 "npc_blonde_girl_above": [ 1081 "next_to_blonde_girl_down", 1082 ], 1083 } 1084 super().__init__( 1085 pyboy, 1086 variant="harvest_moon_2", 1087 parameters=parameters, 1088 override_regions=override_regions, 1089 override_multi_target_regions=override_multi_target_regions, 1090 override_multi_targets=override_multi_targets, 1091 )
Initializes the HarvestMoonStateParser.
Arguments:
- pyboy (PyBoy): The PyBoy emulator instance.
- parameters (dict): Configuration parameters for the emulator.
- additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include.
- additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include.
- override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions.
1099 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1100 box = self.capture_named_region( 1101 current_frame=current_screen, name="dialogue_box_bottom" 1102 ) 1103 perc_lt_255 = np.mean(box < 255) 1104 if perc_lt_255 < 0.082: # Empirical threshold 1105 return True 1106 return False
1120 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 1121 if self.is_in_menu(current_screen): 1122 return AgentState.IN_MENU 1123 if self.is_in_storage_list(current_screen): 1124 return AgentState.IN_STORAGE_LIST 1125 if self.is_in_dialogue(current_screen): 1126 return AgentState.IN_DIALOGUE 1127 return AgentState.FREE_ROAM
Inherited Members
- HarvestMoonStateParser
- COMMON_REGIONS
- COMMON_MULTI_TARGET_REGIONS
- COMMON_MULTI_TARGETS
- variant
- rom_data_path
- gameboy_worlds.emulation.parser.StateParser
- named_screen_regions
- image_references
- bit_count
- read_m
- read_bits
- read_bit
- read_m_bit
- get_raised_flags
- get_current_frame
- capture_box
- capture_square_centered
- draw_box
- draw_square_centered
- capture_named_region
- compare_named_region_against_target
- named_region_matches_target
- compare_named_region_against_multi_target
- named_region_matches_multi_target
- draw_named_region
- draw_grid_overlay
- capture_grid_cells
- reform_image
- get_quadrant_frame
- get_image_reference
1130class HarvestMoon3Parser(BaseHarvestMoonStateParser): 1131 DIALOGUE_TYPES = [ 1132 "normal_dialogue", 1133 "mainland_dialogue", 1134 ] 1135 1136 def __init__(self, pyboy, parameters): 1137 override_regions = [ 1138 ("menu_top_right", 153, 0, 6, 6), 1139 ] 1140 override_multi_target_regions = [ 1141 ("dialogue_bottom_right", 153, 135, 10, 10), 1142 ("screen_bottom", 0, 95, 160, 40), 1143 ("dialogue_box_bottom", 0, 98, 160, 45), 1144 ("item_secret_garden_sign_above", 60, 55, 20, 40), 1145 ("item_secret_garden_sign_right", 50, 55, 35, 25), 1146 ("item_turnip_seeds_above", 30, 55, 17, 41), 1147 ("item_turnip_seeds_below", 30, 40, 17, 39), 1148 ("item_potato_seeds_above", 63, 55, 17, 41), 1149 ("item_potato_seeds_below", 63, 40, 17, 39), 1150 ("screen_top_half", 0, 0, 160, 65), 1151 ("screen_bottom_half", 0, 75, 160, 65), 1152 ("item_storage_sign_below", 70, 40, 20, 40), 1153 ("item_storage_sign_left", 70, 55, 35, 25), 1154 ("item_storage_sign_right", 55, 55, 30, 25), 1155 ("item_morning_market_sign_left", 128, 55, 31, 27), 1156 ("npc_kirk_above", 65, 55, 25, 40), 1157 ("npc_kirk_mainland_right", 55, 45, 30, 25), 1158 ("npc_kirk_mainland_below", 70, 40, 15, 40), 1159 ("npc_joe_left", 125, 55, 34, 25), 1160 ("npc_lukia_right", 38, 55, 34, 25), 1161 ("dialogue_box_upper_border", 0, 96, 160, 8), 1162 ("npc_lucus_above", 70, 55, 19, 40), 1163 ("npc_lucus_left", 70, 55, 34, 25), 1164 ("npc_lucus_right", 55, 55, 34, 25), 1165 ("npc_lyla_right", 54, 55, 34, 25), 1166 ("item_meal_set_empty_1", 80, 40, 30, 15), 1167 ("item_meal_set_empty_2", 80, 80, 30, 15), 1168 ("item_coffee_above", 72, 55, 15, 39), 1169 ("item_coffee_below", 72, 40, 13, 30), 1170 ("entrance", 40, 65, 80, 80), 1171 ("top_entrance", 45, 0, 70, 40), 1172 ("outside_chicken_coop", 45, 40, 45, 35), 1173 ("outside_hot_spring", 45, 40, 45, 35), 1174 ("item_tea_above", 70, 55, 17, 41), 1175 ("item_tea_below", 70, 40, 17, 39), 1176 ("item_asparagus_seeds_above", 72, 55, 17, 41), 1177 ("item_asparagus_seeds_below", 72, 40, 17, 39), 1178 ("item_right_cow_stall_block", 115, 25, 45, 25), 1179 ("item_right_cow_stall_block_below", 115, 25, 45, 50), 1180 ("item_right_cow_stall_block_left", 95, 35, 55, 35), 1181 ("item_cow_stall_block_2", 112, 35, 38, 35), 1182 ("item_ferry_sign_above", 70, 60, 16, 45), 1183 ("item_ferry_sign_left", 70, 60, 30, 28), 1184 ("item_fireplace_below", 105, 40, 15, 40), 1185 ("item_rock_left", 95, 55, 30, 25), 1186 ("item_target_potato_below", 56, 32, 48, 47), 1187 ("item_center_spotato_above", 56, 60, 47, 50), 1188 ("item_center_watermelon_above", 30, 25, 49, 54), 1189 ("npc_kate_left", 50, 58, 28, 19), 1190 ("npc_kate_right", 63, 55, 33, 23), 1191 ("npc_kate_below", 63, 39, 16, 40), 1192 ("item_weed_left", 70, 0, 50, 45), 1193 ("item_cherry_left", 95, 50, 30, 38), 1194 ("item_fodder_set_below", 113, 40, 14, 40), 1195 ("item_horse_medicine_below", 97, 40, 14, 40), 1196 ("item_chicken_silo_left1", 96, 50, 30, 30), 1197 ("item_chicken_silo_left2", 96, 65, 30, 30), 1198 ("item_chicken_silo_above", 110, 50, 20, 40), 1199 ("item_topmost_chicken_stall_block", 115, 36, 35, 29), 1200 ("item_next_to_topmost_chicken_stall_block", 97, 36, 53, 29), 1201 ("item_fodder_set", 97, 40, 30, 5), 1202 ("item_horse_medicine", 97, 40, 30, 5), 1203 ("item_next_to_hatching_box", 7, 62, 36, 38), 1204 ("item_hatching_box", 7, 62, 23, 38), 1205 ("item_stairs", 40, 0, 95, 80), 1206 ("item_flower_vase_empty_1", 0, 80, 50, 15), 1207 ("item_flower_vase_empty_2", 0, 40, 50, 5), 1208 ("item_flower_vase_above", 32, 56, 16, 40), 1209 ("item_flower_vase_below", 32, 40, 16, 40), 1210 ("item_horse_saddle_empty_1", 78, 80, 80, 15), 1211 ("item_horse_saddle_empty_2", 78, 40, 80, 15), 1212 ("item_horse_saddle_above", 72, 55, 24, 41), 1213 ("item_horse_saddle_below", 78, 40, 17, 39), 1214 ("item_center_eggplant_above", 52, 15, 51, 64), 1215 ("item_center_eggplant_left", 70, 32, 48, 48), 1216 ("menu_box", 106, 0, 53, 122), 1217 ("player_top_left", 0, 0, 35, 40), 1218 ("item_berry_above", 0, 50, 35, 45), 1219 ("sell_animal_section_1", 62, 80, 83, 16), 1220 ("sell_animal_section_2", 62, 40, 83, 16), 1221 ("item_sell_chicken_below", 80, 40, 15, 40), 1222 ("item_sell_chicken_above", 78, 56, 17, 39), 1223 ("item_center_turnip_below", 56, 32, 48, 47), 1224 ("item_bookshelf_below", 125, 32, 25, 48), 1225 ] 1226 override_multi_targets = { 1227 "dialogue_bottom_right": [ 1228 "normal_dialogue", 1229 "mainland_dialogue", 1230 ], 1231 "dialogue_box_bottom": [ 1232 "reading_secret_garden_sign", 1233 "reading_storage_sign", 1234 "reading_morning_market_sign", 1235 "reading_ferry_sign", 1236 "found_secret_savings", 1237 "select_tea", 1238 "select_asparagus_seeds", 1239 "select_coffee", 1240 "select_turnip_seeds", 1241 "select_turnip_seeds_portion", 1242 "select_potato_seeds", 1243 "select_potato_seeds_portion", 1244 "bought_turnip_seeds", 1245 "bought_potato_seeds", 1246 "select_meal_set", 1247 "speaking_to_kate", 1248 "farm_label", 1249 "village_label", 1250 "grassland_label", 1251 "forest_label", 1252 "cliff_label", 1253 "mountain_label", 1254 "shopping_mall_label", 1255 "farmers_union_label", 1256 "aquarium_label", 1257 "theatre_label", 1258 "selected_fodder_set", 1259 "selected_horse_medicine", 1260 "bought_from_farmers_union", 1261 "bought_from_flower_shop", 1262 "animal_sold", 1263 "finish_animal_ch2", 1264 ], 1265 "item_rock_left": [ 1266 "next_to_rock_right", 1267 "rock_cleared", 1268 ], 1269 "item_target_potato_below": [ 1270 "next_to_target_potato_up", 1271 "target_potato_harvested", 1272 ], 1273 "item_center_spotato_above": [ 1274 "next_to_spotato_down", 1275 "center_spotato_watered", 1276 ], 1277 "item_center_watermelon_above": [ 1278 "next_to_center_watermelon_down", 1279 "center_watermelon_watered", 1280 ], 1281 "npc_kate_left": [ 1282 "next_to_kate_right", 1283 ], 1284 "npc_kate_right": [ 1285 "next_to_kate_left", 1286 ], 1287 "npc_kate_below": [ 1288 "next_to_kate_up", 1289 ], 1290 "item_weed_left": [ 1291 "next_to_weed_right", 1292 "weed_removed", 1293 ], 1294 "item_cherry_left": [ 1295 "next_to_cherry_right", 1296 "cherry_picked", 1297 ], 1298 "item_chicken_silo_left1": [ 1299 "next_to_chicken_silo_right1", 1300 "got_fodder_from_chicken_silo_right1", 1301 ], 1302 "item_chicken_silo_left2": [ 1303 "next_to_chicken_silo_right2", 1304 "got_fodder_from_chicken_silo_right2", 1305 ], 1306 "item_chicken_silo_above": [ 1307 "next_to_chicken_silo_down", 1308 "got_fodder_from_chicken_silo_down", 1309 ], 1310 "item_topmost_chicken_stall_block": [ 1311 "filled_topmost_chicken_stall_block", 1312 ], 1313 "item_next_to_topmost_chicken_stall_block": [ 1314 "next_to_topmost_chicken_stall_block", 1315 ], 1316 "item_next_to_hatching_box": [ 1317 "next_to_hatching_box", 1318 ], 1319 "item_hatching_box": [ 1320 "dropped_egg_into_hatching_box", 1321 ], 1322 "item_stairs": [ 1323 "next_to_stairs_1", 1324 "next_to_stairs_2", 1325 "next_to_stairs_3", 1326 ], 1327 "item_fodder_set_below": [ 1328 "next_to_fodder_set_up", 1329 ], 1330 "item_horse_medicine_below": [ 1331 "next_to_horse_medicine_up", 1332 ], 1333 "item_fodder_set": [ 1334 "picked_fodder_set", 1335 ], 1336 "item_horse_medicine": [ 1337 "picked_horse_medicine", 1338 ], 1339 "item_storage_sign_below": [ 1340 "next_to_storage_sign_up", 1341 ], 1342 "item_storage_sign_left": [ 1343 "next_to_storage_sign_right", 1344 ], 1345 "item_storage_sign_right": [ 1346 "next_to_storage_sign_left", 1347 ], 1348 "item_morning_market_sign_left": [ 1349 "next_to_morning_market_sign_right", 1350 ], 1351 "npc_kirk_above": [ 1352 "next_to_kirk_down", 1353 ], 1354 "npc_kirk_mainland_right": [ 1355 "next_to_kirk_mainland_left", 1356 ], 1357 "npc_kirk_mainland_below": [ 1358 "next_to_kirk_mainland_up", 1359 ], 1360 "npc_joe_left": [ 1361 "next_to_joe_right", 1362 ], 1363 "dialogue_box_upper_border": [ 1364 "speaking_to_kirk_village", 1365 "speaking_to_joe", 1366 "speaking_to_lukia", 1367 "speaking_to_lucus", 1368 "speaking_to_lyla", 1369 ], 1370 "item_secret_garden_sign_above": [ 1371 "next_to_secret_garden_sign_down", 1372 ], 1373 "item_secret_garden_sign_right": [ 1374 "next_to_secret_garden_sign_left", 1375 ], 1376 "item_turnip_seeds_above": [ 1377 "next_to_turnip_seeds_down", 1378 ], 1379 "item_turnip_seeds_below": [ 1380 "next_to_turnip_seeds_up", 1381 ], 1382 "item_potato_seeds_above": [ 1383 "next_to_potato_seeds_down", 1384 ], 1385 "item_potato_seeds_below": [ 1386 "next_to_potato_seeds_up", 1387 ], 1388 "npc_lukia_right": [ 1389 "next_to_lukia_left", 1390 ], 1391 "npc_lucus_above": [ 1392 "next_to_lucus_down", 1393 ], 1394 "npc_lucus_left": [ 1395 "next_to_lucus_right", 1396 ], 1397 "npc_lucus_right": [ 1398 "next_to_lucus_left", 1399 ], 1400 "npc_lyla_right": [ 1401 "next_to_lyla_left", 1402 ], 1403 "outside_chicken_coop": [ 1404 "outside_chicken_coop_left", 1405 "outside_chicken_coop_right", 1406 "outside_chicken_coop_up", 1407 ], 1408 "item_flower_vase_empty_1": [ 1409 "bought_flower_vase_1", 1410 ], 1411 "item_flower_vase_empty_2": [ 1412 "bought_flower_vase_2", 1413 ], 1414 "item_flower_vase_above": [ 1415 "next_to_vase_down", 1416 ], 1417 "item_flower_vase_below": [ 1418 "next_to_vase_up", 1419 ], 1420 "item_center_eggplant_above": [ 1421 "next_to_eggplant_down", 1422 "center_eggplant_harvested_down", 1423 ], 1424 "item_center_eggplant_left": [ 1425 "next_to_eggplant_right", 1426 "center_eggplant_harvested_right", 1427 ], 1428 "menu_box": [ 1429 "choose_may", 1430 ], 1431 "player_top_left": [ 1432 "display_player_status", 1433 ], 1434 "item_berry_above": [ 1435 "next_to_berry_down", 1436 "berry_picked_above", 1437 ], 1438 "sell_animal_section_1": [ 1439 "selling_animal_1", 1440 ], 1441 "sell_animal_section_2": [ 1442 "selling_animal_2", 1443 ], 1444 "item_sell_chicken_below": [ 1445 "next_to_sell_chicken_up", 1446 ], 1447 "item_sell_chicken_above": [ 1448 "next_to_sell_chicken_down", 1449 ], 1450 "item_center_turnip_below": [ 1451 "next_to_center_turnip_up", 1452 "center_turnip_harvested", 1453 ], 1454 "item_bookshelf_below": [ 1455 "next_to_bookshelf_up", 1456 ], 1457 "item_horse_saddle_empty_1": [ 1458 "bought_horse_saddle_1", 1459 ], 1460 "item_horse_saddle_empty_2": [ 1461 "bought_horse_saddle_2", 1462 ], 1463 "item_horse_saddle_above": [ 1464 "next_to_horse_saddle_down", 1465 ], 1466 "item_horse_saddle_below": [ 1467 "next_to_horse_saddle_up", 1468 ], 1469 "item_meal_set_empty_1": [ 1470 "bought_meal_set_1", 1471 ], 1472 "item_meal_set_empty_2": [ 1473 "bought_meal_set_2", 1474 ], 1475 "item_coffee_above": [ 1476 "next_to_coffee_down", 1477 ], 1478 "item_coffee_below": [ 1479 "next_to_coffee_up", 1480 ], 1481 "top_entrance": [ 1482 "village_entrance", 1483 ], 1484 "entrance": [ 1485 "village_ferry_entrance", 1486 "farm_entrance", 1487 "grassland_entrance", 1488 "forest_entrance", 1489 "cliff_entrance", 1490 "mountain_entrance", 1491 "shopping_mall_entrance", 1492 "farmers_union_entrance", 1493 "aquarium_entrance", 1494 "theatre_entrance", 1495 "hot_spring_entrance", 1496 "shopping_mall_second_floor", 1497 ], 1498 "item_tea_above": [ 1499 "next_to_tea_down", 1500 ], 1501 "item_tea_below": [ 1502 "next_to_tea_up", 1503 ], 1504 "item_asparagus_seeds_above": [ 1505 "next_to_asparagus_seeds_down", 1506 ], 1507 "item_asparagus_seeds_below": [ 1508 "next_to_asparagus_seeds_up", 1509 ], 1510 "item_right_cow_stall_block": [ 1511 "filled_right_cow_stall_block", 1512 ], 1513 "item_right_cow_stall_block_below": [ 1514 "next_to_right_cow_stall_block_up", 1515 ], 1516 "item_right_cow_stall_block_left": [ 1517 "next_to_right_cow_stall_block_right", 1518 ], 1519 "item_cow_stall_block_2": [ 1520 "filled_cow_stall_block_right", 1521 ], 1522 "item_ferry_sign_above": [ 1523 "next_to_ferry_sign_down", 1524 ], 1525 "item_ferry_sign_left": [ 1526 "next_to_ferry_sign_right", 1527 ], 1528 "item_fireplace_below": [ 1529 "next_to_fireplace_up", 1530 ], 1531 "outside_hot_spring": [ 1532 "outside_hot_spring_left", 1533 "outside_hot_spring_right", 1534 "outside_hot_spring_up", 1535 ], 1536 } 1537 super().__init__( 1538 pyboy, 1539 variant="harvest_moon_3", 1540 parameters=parameters, 1541 override_regions=override_regions, 1542 override_multi_target_regions=override_multi_target_regions, 1543 override_multi_targets=override_multi_targets, 1544 ) 1545 1546 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 1547 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1548 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1549 self.DIALOGUE_TYPES, captured 1550 ): 1551 return True 1552 return False 1553 1554 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1555 box = self.capture_named_region( 1556 current_frame=current_screen, name="dialogue_box_bottom" 1557 ) 1558 perc_lt_255 = np.mean(box < 255) 1559 if perc_lt_255 < 0.082: # Empirical threshold 1560 return True 1561 return False 1562 1563 def is_in_menu(self, current_screen: np.ndarray) -> bool: 1564 return self.named_region_matches_target(current_screen, "menu_top_right") 1565 1566 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 1567 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1568 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1569 self.DIALOGUE_TYPES, captured 1570 ): 1571 return True 1572 return False 1573 1574 def get_agent_state(self, current_screen: np.ndarray) -> AgentState: 1575 if self.is_in_menu(current_screen): 1576 return AgentState.IN_MENU 1577 if self.is_in_dialogue(current_screen): 1578 return AgentState.IN_DIALOGUE 1579 return AgentState.FREE_ROAM
Game state parser for all Harvest Moon GBC-based games.
1136 def __init__(self, pyboy, parameters): 1137 override_regions = [ 1138 ("menu_top_right", 153, 0, 6, 6), 1139 ] 1140 override_multi_target_regions = [ 1141 ("dialogue_bottom_right", 153, 135, 10, 10), 1142 ("screen_bottom", 0, 95, 160, 40), 1143 ("dialogue_box_bottom", 0, 98, 160, 45), 1144 ("item_secret_garden_sign_above", 60, 55, 20, 40), 1145 ("item_secret_garden_sign_right", 50, 55, 35, 25), 1146 ("item_turnip_seeds_above", 30, 55, 17, 41), 1147 ("item_turnip_seeds_below", 30, 40, 17, 39), 1148 ("item_potato_seeds_above", 63, 55, 17, 41), 1149 ("item_potato_seeds_below", 63, 40, 17, 39), 1150 ("screen_top_half", 0, 0, 160, 65), 1151 ("screen_bottom_half", 0, 75, 160, 65), 1152 ("item_storage_sign_below", 70, 40, 20, 40), 1153 ("item_storage_sign_left", 70, 55, 35, 25), 1154 ("item_storage_sign_right", 55, 55, 30, 25), 1155 ("item_morning_market_sign_left", 128, 55, 31, 27), 1156 ("npc_kirk_above", 65, 55, 25, 40), 1157 ("npc_kirk_mainland_right", 55, 45, 30, 25), 1158 ("npc_kirk_mainland_below", 70, 40, 15, 40), 1159 ("npc_joe_left", 125, 55, 34, 25), 1160 ("npc_lukia_right", 38, 55, 34, 25), 1161 ("dialogue_box_upper_border", 0, 96, 160, 8), 1162 ("npc_lucus_above", 70, 55, 19, 40), 1163 ("npc_lucus_left", 70, 55, 34, 25), 1164 ("npc_lucus_right", 55, 55, 34, 25), 1165 ("npc_lyla_right", 54, 55, 34, 25), 1166 ("item_meal_set_empty_1", 80, 40, 30, 15), 1167 ("item_meal_set_empty_2", 80, 80, 30, 15), 1168 ("item_coffee_above", 72, 55, 15, 39), 1169 ("item_coffee_below", 72, 40, 13, 30), 1170 ("entrance", 40, 65, 80, 80), 1171 ("top_entrance", 45, 0, 70, 40), 1172 ("outside_chicken_coop", 45, 40, 45, 35), 1173 ("outside_hot_spring", 45, 40, 45, 35), 1174 ("item_tea_above", 70, 55, 17, 41), 1175 ("item_tea_below", 70, 40, 17, 39), 1176 ("item_asparagus_seeds_above", 72, 55, 17, 41), 1177 ("item_asparagus_seeds_below", 72, 40, 17, 39), 1178 ("item_right_cow_stall_block", 115, 25, 45, 25), 1179 ("item_right_cow_stall_block_below", 115, 25, 45, 50), 1180 ("item_right_cow_stall_block_left", 95, 35, 55, 35), 1181 ("item_cow_stall_block_2", 112, 35, 38, 35), 1182 ("item_ferry_sign_above", 70, 60, 16, 45), 1183 ("item_ferry_sign_left", 70, 60, 30, 28), 1184 ("item_fireplace_below", 105, 40, 15, 40), 1185 ("item_rock_left", 95, 55, 30, 25), 1186 ("item_target_potato_below", 56, 32, 48, 47), 1187 ("item_center_spotato_above", 56, 60, 47, 50), 1188 ("item_center_watermelon_above", 30, 25, 49, 54), 1189 ("npc_kate_left", 50, 58, 28, 19), 1190 ("npc_kate_right", 63, 55, 33, 23), 1191 ("npc_kate_below", 63, 39, 16, 40), 1192 ("item_weed_left", 70, 0, 50, 45), 1193 ("item_cherry_left", 95, 50, 30, 38), 1194 ("item_fodder_set_below", 113, 40, 14, 40), 1195 ("item_horse_medicine_below", 97, 40, 14, 40), 1196 ("item_chicken_silo_left1", 96, 50, 30, 30), 1197 ("item_chicken_silo_left2", 96, 65, 30, 30), 1198 ("item_chicken_silo_above", 110, 50, 20, 40), 1199 ("item_topmost_chicken_stall_block", 115, 36, 35, 29), 1200 ("item_next_to_topmost_chicken_stall_block", 97, 36, 53, 29), 1201 ("item_fodder_set", 97, 40, 30, 5), 1202 ("item_horse_medicine", 97, 40, 30, 5), 1203 ("item_next_to_hatching_box", 7, 62, 36, 38), 1204 ("item_hatching_box", 7, 62, 23, 38), 1205 ("item_stairs", 40, 0, 95, 80), 1206 ("item_flower_vase_empty_1", 0, 80, 50, 15), 1207 ("item_flower_vase_empty_2", 0, 40, 50, 5), 1208 ("item_flower_vase_above", 32, 56, 16, 40), 1209 ("item_flower_vase_below", 32, 40, 16, 40), 1210 ("item_horse_saddle_empty_1", 78, 80, 80, 15), 1211 ("item_horse_saddle_empty_2", 78, 40, 80, 15), 1212 ("item_horse_saddle_above", 72, 55, 24, 41), 1213 ("item_horse_saddle_below", 78, 40, 17, 39), 1214 ("item_center_eggplant_above", 52, 15, 51, 64), 1215 ("item_center_eggplant_left", 70, 32, 48, 48), 1216 ("menu_box", 106, 0, 53, 122), 1217 ("player_top_left", 0, 0, 35, 40), 1218 ("item_berry_above", 0, 50, 35, 45), 1219 ("sell_animal_section_1", 62, 80, 83, 16), 1220 ("sell_animal_section_2", 62, 40, 83, 16), 1221 ("item_sell_chicken_below", 80, 40, 15, 40), 1222 ("item_sell_chicken_above", 78, 56, 17, 39), 1223 ("item_center_turnip_below", 56, 32, 48, 47), 1224 ("item_bookshelf_below", 125, 32, 25, 48), 1225 ] 1226 override_multi_targets = { 1227 "dialogue_bottom_right": [ 1228 "normal_dialogue", 1229 "mainland_dialogue", 1230 ], 1231 "dialogue_box_bottom": [ 1232 "reading_secret_garden_sign", 1233 "reading_storage_sign", 1234 "reading_morning_market_sign", 1235 "reading_ferry_sign", 1236 "found_secret_savings", 1237 "select_tea", 1238 "select_asparagus_seeds", 1239 "select_coffee", 1240 "select_turnip_seeds", 1241 "select_turnip_seeds_portion", 1242 "select_potato_seeds", 1243 "select_potato_seeds_portion", 1244 "bought_turnip_seeds", 1245 "bought_potato_seeds", 1246 "select_meal_set", 1247 "speaking_to_kate", 1248 "farm_label", 1249 "village_label", 1250 "grassland_label", 1251 "forest_label", 1252 "cliff_label", 1253 "mountain_label", 1254 "shopping_mall_label", 1255 "farmers_union_label", 1256 "aquarium_label", 1257 "theatre_label", 1258 "selected_fodder_set", 1259 "selected_horse_medicine", 1260 "bought_from_farmers_union", 1261 "bought_from_flower_shop", 1262 "animal_sold", 1263 "finish_animal_ch2", 1264 ], 1265 "item_rock_left": [ 1266 "next_to_rock_right", 1267 "rock_cleared", 1268 ], 1269 "item_target_potato_below": [ 1270 "next_to_target_potato_up", 1271 "target_potato_harvested", 1272 ], 1273 "item_center_spotato_above": [ 1274 "next_to_spotato_down", 1275 "center_spotato_watered", 1276 ], 1277 "item_center_watermelon_above": [ 1278 "next_to_center_watermelon_down", 1279 "center_watermelon_watered", 1280 ], 1281 "npc_kate_left": [ 1282 "next_to_kate_right", 1283 ], 1284 "npc_kate_right": [ 1285 "next_to_kate_left", 1286 ], 1287 "npc_kate_below": [ 1288 "next_to_kate_up", 1289 ], 1290 "item_weed_left": [ 1291 "next_to_weed_right", 1292 "weed_removed", 1293 ], 1294 "item_cherry_left": [ 1295 "next_to_cherry_right", 1296 "cherry_picked", 1297 ], 1298 "item_chicken_silo_left1": [ 1299 "next_to_chicken_silo_right1", 1300 "got_fodder_from_chicken_silo_right1", 1301 ], 1302 "item_chicken_silo_left2": [ 1303 "next_to_chicken_silo_right2", 1304 "got_fodder_from_chicken_silo_right2", 1305 ], 1306 "item_chicken_silo_above": [ 1307 "next_to_chicken_silo_down", 1308 "got_fodder_from_chicken_silo_down", 1309 ], 1310 "item_topmost_chicken_stall_block": [ 1311 "filled_topmost_chicken_stall_block", 1312 ], 1313 "item_next_to_topmost_chicken_stall_block": [ 1314 "next_to_topmost_chicken_stall_block", 1315 ], 1316 "item_next_to_hatching_box": [ 1317 "next_to_hatching_box", 1318 ], 1319 "item_hatching_box": [ 1320 "dropped_egg_into_hatching_box", 1321 ], 1322 "item_stairs": [ 1323 "next_to_stairs_1", 1324 "next_to_stairs_2", 1325 "next_to_stairs_3", 1326 ], 1327 "item_fodder_set_below": [ 1328 "next_to_fodder_set_up", 1329 ], 1330 "item_horse_medicine_below": [ 1331 "next_to_horse_medicine_up", 1332 ], 1333 "item_fodder_set": [ 1334 "picked_fodder_set", 1335 ], 1336 "item_horse_medicine": [ 1337 "picked_horse_medicine", 1338 ], 1339 "item_storage_sign_below": [ 1340 "next_to_storage_sign_up", 1341 ], 1342 "item_storage_sign_left": [ 1343 "next_to_storage_sign_right", 1344 ], 1345 "item_storage_sign_right": [ 1346 "next_to_storage_sign_left", 1347 ], 1348 "item_morning_market_sign_left": [ 1349 "next_to_morning_market_sign_right", 1350 ], 1351 "npc_kirk_above": [ 1352 "next_to_kirk_down", 1353 ], 1354 "npc_kirk_mainland_right": [ 1355 "next_to_kirk_mainland_left", 1356 ], 1357 "npc_kirk_mainland_below": [ 1358 "next_to_kirk_mainland_up", 1359 ], 1360 "npc_joe_left": [ 1361 "next_to_joe_right", 1362 ], 1363 "dialogue_box_upper_border": [ 1364 "speaking_to_kirk_village", 1365 "speaking_to_joe", 1366 "speaking_to_lukia", 1367 "speaking_to_lucus", 1368 "speaking_to_lyla", 1369 ], 1370 "item_secret_garden_sign_above": [ 1371 "next_to_secret_garden_sign_down", 1372 ], 1373 "item_secret_garden_sign_right": [ 1374 "next_to_secret_garden_sign_left", 1375 ], 1376 "item_turnip_seeds_above": [ 1377 "next_to_turnip_seeds_down", 1378 ], 1379 "item_turnip_seeds_below": [ 1380 "next_to_turnip_seeds_up", 1381 ], 1382 "item_potato_seeds_above": [ 1383 "next_to_potato_seeds_down", 1384 ], 1385 "item_potato_seeds_below": [ 1386 "next_to_potato_seeds_up", 1387 ], 1388 "npc_lukia_right": [ 1389 "next_to_lukia_left", 1390 ], 1391 "npc_lucus_above": [ 1392 "next_to_lucus_down", 1393 ], 1394 "npc_lucus_left": [ 1395 "next_to_lucus_right", 1396 ], 1397 "npc_lucus_right": [ 1398 "next_to_lucus_left", 1399 ], 1400 "npc_lyla_right": [ 1401 "next_to_lyla_left", 1402 ], 1403 "outside_chicken_coop": [ 1404 "outside_chicken_coop_left", 1405 "outside_chicken_coop_right", 1406 "outside_chicken_coop_up", 1407 ], 1408 "item_flower_vase_empty_1": [ 1409 "bought_flower_vase_1", 1410 ], 1411 "item_flower_vase_empty_2": [ 1412 "bought_flower_vase_2", 1413 ], 1414 "item_flower_vase_above": [ 1415 "next_to_vase_down", 1416 ], 1417 "item_flower_vase_below": [ 1418 "next_to_vase_up", 1419 ], 1420 "item_center_eggplant_above": [ 1421 "next_to_eggplant_down", 1422 "center_eggplant_harvested_down", 1423 ], 1424 "item_center_eggplant_left": [ 1425 "next_to_eggplant_right", 1426 "center_eggplant_harvested_right", 1427 ], 1428 "menu_box": [ 1429 "choose_may", 1430 ], 1431 "player_top_left": [ 1432 "display_player_status", 1433 ], 1434 "item_berry_above": [ 1435 "next_to_berry_down", 1436 "berry_picked_above", 1437 ], 1438 "sell_animal_section_1": [ 1439 "selling_animal_1", 1440 ], 1441 "sell_animal_section_2": [ 1442 "selling_animal_2", 1443 ], 1444 "item_sell_chicken_below": [ 1445 "next_to_sell_chicken_up", 1446 ], 1447 "item_sell_chicken_above": [ 1448 "next_to_sell_chicken_down", 1449 ], 1450 "item_center_turnip_below": [ 1451 "next_to_center_turnip_up", 1452 "center_turnip_harvested", 1453 ], 1454 "item_bookshelf_below": [ 1455 "next_to_bookshelf_up", 1456 ], 1457 "item_horse_saddle_empty_1": [ 1458 "bought_horse_saddle_1", 1459 ], 1460 "item_horse_saddle_empty_2": [ 1461 "bought_horse_saddle_2", 1462 ], 1463 "item_horse_saddle_above": [ 1464 "next_to_horse_saddle_down", 1465 ], 1466 "item_horse_saddle_below": [ 1467 "next_to_horse_saddle_up", 1468 ], 1469 "item_meal_set_empty_1": [ 1470 "bought_meal_set_1", 1471 ], 1472 "item_meal_set_empty_2": [ 1473 "bought_meal_set_2", 1474 ], 1475 "item_coffee_above": [ 1476 "next_to_coffee_down", 1477 ], 1478 "item_coffee_below": [ 1479 "next_to_coffee_up", 1480 ], 1481 "top_entrance": [ 1482 "village_entrance", 1483 ], 1484 "entrance": [ 1485 "village_ferry_entrance", 1486 "farm_entrance", 1487 "grassland_entrance", 1488 "forest_entrance", 1489 "cliff_entrance", 1490 "mountain_entrance", 1491 "shopping_mall_entrance", 1492 "farmers_union_entrance", 1493 "aquarium_entrance", 1494 "theatre_entrance", 1495 "hot_spring_entrance", 1496 "shopping_mall_second_floor", 1497 ], 1498 "item_tea_above": [ 1499 "next_to_tea_down", 1500 ], 1501 "item_tea_below": [ 1502 "next_to_tea_up", 1503 ], 1504 "item_asparagus_seeds_above": [ 1505 "next_to_asparagus_seeds_down", 1506 ], 1507 "item_asparagus_seeds_below": [ 1508 "next_to_asparagus_seeds_up", 1509 ], 1510 "item_right_cow_stall_block": [ 1511 "filled_right_cow_stall_block", 1512 ], 1513 "item_right_cow_stall_block_below": [ 1514 "next_to_right_cow_stall_block_up", 1515 ], 1516 "item_right_cow_stall_block_left": [ 1517 "next_to_right_cow_stall_block_right", 1518 ], 1519 "item_cow_stall_block_2": [ 1520 "filled_cow_stall_block_right", 1521 ], 1522 "item_ferry_sign_above": [ 1523 "next_to_ferry_sign_down", 1524 ], 1525 "item_ferry_sign_left": [ 1526 "next_to_ferry_sign_right", 1527 ], 1528 "item_fireplace_below": [ 1529 "next_to_fireplace_up", 1530 ], 1531 "outside_hot_spring": [ 1532 "outside_hot_spring_left", 1533 "outside_hot_spring_right", 1534 "outside_hot_spring_up", 1535 ], 1536 } 1537 super().__init__( 1538 pyboy, 1539 variant="harvest_moon_3", 1540 parameters=parameters, 1541 override_regions=override_regions, 1542 override_multi_target_regions=override_multi_target_regions, 1543 override_multi_targets=override_multi_targets, 1544 )
Initializes the HarvestMoonStateParser.
Arguments:
- pyboy (PyBoy): The PyBoy emulator instance.
- parameters (dict): Configuration parameters for the emulator.
- additional_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional named screen regions to include.
- additional_multi_target_named_screen_region_details (List[Tuple[str, int, int, int, int]]): Parameters associated with additional multi-target named screen regions to include.
- override_multi_targets (Dict[str, List[str]]): Dictionary mapping region names to lists of additional target names for multi-target regions.
1546 def dialogue_box_open(self, current_screen: np.ndarray) -> bool: 1547 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1548 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1549 self.DIALOGUE_TYPES, captured 1550 ): 1551 return True 1552 return False
1554 def dialogue_box_empty(self, current_screen: np.ndarray) -> bool: 1555 box = self.capture_named_region( 1556 current_frame=current_screen, name="dialogue_box_bottom" 1557 ) 1558 perc_lt_255 = np.mean(box < 255) 1559 if perc_lt_255 < 0.082: # Empirical threshold 1560 return True 1561 return False
1566 def is_in_dialogue(self, current_screen: np.ndarray) -> bool: 1567 captured = self.capture_named_region(current_screen, "dialogue_bottom_right") 1568 if self.named_screen_regions["dialogue_bottom_right"].matches_any_multi_target( 1569 self.DIALOGUE_TYPES, captured 1570 ): 1571 return True 1572 return False
Inherited Members
- HarvestMoonStateParser
- COMMON_REGIONS
- COMMON_MULTI_TARGET_REGIONS
- COMMON_MULTI_TARGETS
- variant
- rom_data_path
- gameboy_worlds.emulation.parser.StateParser
- named_screen_regions
- image_references
- bit_count
- read_m
- read_bits
- read_bit
- read_m_bit
- get_raised_flags
- get_current_frame
- capture_box
- capture_square_centered
- draw_box
- draw_square_centered
- capture_named_region
- compare_named_region_against_target
- named_region_matches_target
- compare_named_region_against_multi_target
- named_region_matches_multi_target
- draw_named_region
- draw_grid_overlay
- capture_grid_cells
- reform_image
- get_quadrant_frame
- get_image_reference