implement Range option type
This commit is contained in:
		
							parent
							
								
									4b5ac3f926
								
							
						
					
					
						commit
						adda0eff4a
					
				
							
								
								
									
										8
									
								
								Main.py
								
								
								
								
							
							
						
						
									
										8
									
								
								Main.py
								
								
								
								
							|  | @ -94,12 +94,8 @@ def main(args, seed=None): | |||
|     world.compassshuffle = args.compassshuffle.copy() | ||||
|     world.keyshuffle = args.keyshuffle.copy() | ||||
|     world.bigkeyshuffle = args.bigkeyshuffle.copy() | ||||
|     world.crystals_needed_for_ganon = { | ||||
|         player: world.random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int( | ||||
|             args.crystals_ganon[player]) for player in range(1, world.players + 1)} | ||||
|     world.crystals_needed_for_gt = { | ||||
|         player: world.random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) | ||||
|         for player in range(1, world.players + 1)} | ||||
|     world.crystals_needed_for_ganon = args.crystals_ganon.copy() | ||||
|     world.crystals_needed_for_gt = args.crystals_gt.copy() | ||||
|     world.open_pyramid = args.open_pyramid.copy() | ||||
|     world.boss_shuffle = args.shufflebosses.copy() | ||||
|     world.enemy_shuffle = args.enemy_shuffle.copy() | ||||
|  |  | |||
							
								
								
									
										16
									
								
								Mystery.py
								
								
								
								
							
							
						
						
									
										16
									
								
								Mystery.py
								
								
								
								
							|  | @ -632,14 +632,12 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): | |||
|     # fast ganon + ganon at hole | ||||
|     ret.open_pyramid = get_choice('open_pyramid', weights, 'goal') | ||||
| 
 | ||||
|     ret.crystals_gt = prefer_int(get_choice('tower_open', weights)) | ||||
| 
 | ||||
|     ret.crystals_ganon = prefer_int(get_choice('ganon_open', weights)) | ||||
|     ret.crystals_gt = Options.Crystals.from_any(get_choice('tower_open', weights)).value | ||||
|     ret.crystals_ganon = Options.Crystals.from_any(get_choice('ganon_open', weights)).value | ||||
| 
 | ||||
|     extra_pieces = get_choice('triforce_pieces_mode', weights, 'available') | ||||
| 
 | ||||
|     ret.triforce_pieces_required = int(get_choice('triforce_pieces_required', weights, 20)) | ||||
|     ret.triforce_pieces_required = min(max(1, int(ret.triforce_pieces_required)), 90) | ||||
|     ret.triforce_pieces_required = Options.TriforcePieces.from_any(get_choice('triforce_pieces_required', weights)).value | ||||
| 
 | ||||
|     # sum a percentage to required | ||||
|     if extra_pieces == 'percentage': | ||||
|  | @ -647,7 +645,7 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): | |||
|         ret.triforce_pieces_available = int(round(ret.triforce_pieces_required * percentage, 0)) | ||||
|     # vanilla mode (specify how many pieces are) | ||||
|     elif extra_pieces == 'available': | ||||
|         ret.triforce_pieces_available = int(get_choice('triforce_pieces_available', weights, 30)) | ||||
|         ret.triforce_pieces_available = Options.TriforcePieces.from_any(get_choice('triforce_pieces_available', weights)).value | ||||
|     # required pieces + fixed extra | ||||
|     elif extra_pieces == 'extra': | ||||
|         extra_pieces = max(0, int(get_choice('triforce_pieces_extra', weights, 10))) | ||||
|  | @ -655,11 +653,7 @@ def roll_alttp_settings(ret: argparse.Namespace, weights, plando_options): | |||
| 
 | ||||
|     # change minimum to required pieces to avoid problems | ||||
|     ret.triforce_pieces_available = min(max(ret.triforce_pieces_required, int(ret.triforce_pieces_available)), 90) | ||||
|     shuffle_slots = get_choice('shop_shuffle_slots', weights, '0') | ||||
|     if str(shuffle_slots).lower() == "random": | ||||
|         ret.shop_shuffle_slots = random.randint(0, 30) | ||||
|     else: | ||||
|         ret.shop_shuffle_slots = int(shuffle_slots) | ||||
|     ret.shop_shuffle_slots = Options.TriforcePieces.from_any(get_choice('shop_shuffle_slots', weights)).value | ||||
| 
 | ||||
|     ret.shop_shuffle = get_choice('shop_shuffle', weights, '') | ||||
|     if not ret.shop_shuffle: | ||||
|  |  | |||
							
								
								
									
										45
									
								
								Options.py
								
								
								
								
							
							
						
						
									
										45
									
								
								Options.py
								
								
								
								
							|  | @ -1,5 +1,6 @@ | |||
| from __future__ import annotations | ||||
| import typing | ||||
| import random | ||||
| 
 | ||||
| 
 | ||||
| class AssembleOptions(type): | ||||
|  | @ -108,6 +109,29 @@ class Choice(Option): | |||
|             return cls(data) | ||||
|         return cls.from_text(str(data)) | ||||
| 
 | ||||
| class Range(Option): | ||||
|     range_start = 0 | ||||
|     range_end = 1 | ||||
|     def __init__(self, value: typing.Union[str, int]): | ||||
|         self.value: typing.Union[str, int] = value | ||||
| 
 | ||||
|     @classmethod | ||||
|     def from_text(cls, text: str) -> Range: | ||||
|         if text.lower() == "random": | ||||
|             return cls(random.randint(cls.range_start, cls.range_end)) | ||||
|         number = int(text) | ||||
|         if number < cls.range_start: | ||||
|             raise Exception(f"{number} is lower than minimum {cls.range_start} for option {cls.__name__}") | ||||
|         elif number > cls.range_end: | ||||
|             raise Exception(f"{number} is higher than maximum {cls.range_end} for option {cls.__name__}") | ||||
|         else: | ||||
|             return cls(number) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def from_any(cls, data: typing.Any) -> Range: | ||||
|         if type(data) == int: | ||||
|             return cls(data) | ||||
|         return cls.from_text(str(data)) | ||||
| 
 | ||||
| class OptionNameSet(Option): | ||||
|     default = frozenset() | ||||
|  | @ -173,18 +197,17 @@ class Accessibility(Choice): | |||
|     option_beatable = 2 | ||||
| 
 | ||||
| 
 | ||||
| class Crystals(Choice): | ||||
|     # can't use IntEnum since there's also random | ||||
|     option_0 = 0 | ||||
|     option_1 = 1 | ||||
|     option_2 = 2 | ||||
|     option_3 = 3 | ||||
|     option_4 = 4 | ||||
|     option_5 = 5 | ||||
|     option_6 = 6 | ||||
|     option_7 = 7 | ||||
|     option_random = -1 | ||||
| class Crystals(Range): | ||||
|     range_start = 0 | ||||
|     range_end = 7 | ||||
| 
 | ||||
| class TriforcePieces(Range): | ||||
|     range_start = 1 | ||||
|     range_end = 90 | ||||
| 
 | ||||
| class ShopShuffleSlots(Range): | ||||
|     range_start = 0 | ||||
|     range_end = 30 | ||||
| 
 | ||||
| class WorldState(Choice): | ||||
|     option_standard = 1 | ||||
|  |  | |||
|  | @ -206,11 +206,10 @@ def parse_arguments(argv, no_defaults=False): | |||
|                              0-7:    Number of crystals needed | ||||
|                              ''') | ||||
|     parser.add_argument('--crystals_gt', default=defval('7'), const='7', nargs='?', | ||||
|                         choices=['random', '0', '1', '2', '3', '4', '5', '6', '7'], | ||||
|                         choices=['0', '1', '2', '3', '4', '5', '6', '7'], | ||||
|                         help='''\ | ||||
|                              How many crystals are needed to open GT. For inverted mode | ||||
|                              this applies to the castle tower door instead. (default: %(default)s) | ||||
|                              Random: Picks a random value between 0 and 7 (inclusive). | ||||
|                              0-7:    Number of crystals needed | ||||
|                              ''') | ||||
|     parser.add_argument('--open_pyramid', default=defval('auto'), help='''\ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue