Core: create the per world random object in the world constructor (#2083)
* Core: create the per world random object in the world constructor * remove the check that multiworld exists * add a deprecation warning to per_slot_randoms * move random import and fix conflicts * assert worlds don't exist before setting the multiworld seed * fix the dlcq and sdv tests * actually use the seed
This commit is contained in:
parent
b8c24def8d
commit
2e1a5b0e3b
|
@ -85,7 +85,7 @@ class MultiWorld():
|
|||
game: Dict[int, str]
|
||||
|
||||
random: random.Random
|
||||
per_slot_randoms: Dict[int, random.Random]
|
||||
per_slot_randoms: Utils.DeprecateDict[int, random.Random]
|
||||
"""Deprecated. Please use `self.random` instead."""
|
||||
|
||||
class AttributeProxy():
|
||||
|
@ -217,7 +217,8 @@ class MultiWorld():
|
|||
set_player_attr('game', "A Link to the Past")
|
||||
set_player_attr('completion_condition', lambda state: True)
|
||||
self.worlds = {}
|
||||
self.per_slot_randoms = {}
|
||||
self.per_slot_randoms = Utils.DeprecateDict("Using per_slot_randoms is now deprecated. Please use the "
|
||||
"world's random object instead (usually self.random)")
|
||||
self.plando_options = PlandoOptions.none
|
||||
|
||||
def get_all_ids(self) -> Tuple[int, ...]:
|
||||
|
@ -251,14 +252,13 @@ class MultiWorld():
|
|||
return {group_id for group_id, group in self.groups.items() if player in group["players"]}
|
||||
|
||||
def set_seed(self, seed: Optional[int] = None, secure: bool = False, name: Optional[str] = None):
|
||||
assert not self.worlds, "seed needs to be initialized before Worlds"
|
||||
self.seed = get_seed(seed)
|
||||
if secure:
|
||||
self.secure()
|
||||
else:
|
||||
self.random.seed(self.seed)
|
||||
self.seed_name = name if name else str(self.seed)
|
||||
self.per_slot_randoms = {player: random.Random(self.random.getrandbits(64)) for player in
|
||||
range(1, self.players + 1)}
|
||||
|
||||
def set_options(self, args: Namespace) -> None:
|
||||
# TODO - remove this section once all worlds use options dataclasses
|
||||
|
@ -275,7 +275,6 @@ class MultiWorld():
|
|||
for player in self.player_ids:
|
||||
world_type = AutoWorld.AutoWorldRegister.world_types[self.game[player]]
|
||||
self.worlds[player] = world_type(self, player)
|
||||
self.worlds[player].random = self.per_slot_randoms[player]
|
||||
options_dataclass: typing.Type[Options.PerGameCommonOptions] = world_type.options_dataclass
|
||||
self.worlds[player].options = options_dataclass(**{option_key: getattr(args, option_key)[player]
|
||||
for option_key in options_dataclass.type_hints})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from argparse import Namespace
|
||||
from typing import Type, Tuple
|
||||
from typing import Optional, Tuple, Type
|
||||
|
||||
from BaseClasses import MultiWorld, CollectionState
|
||||
from worlds.AutoWorld import call_all, World
|
||||
|
@ -7,18 +7,21 @@ from worlds.AutoWorld import call_all, World
|
|||
gen_steps = ("generate_early", "create_regions", "create_items", "set_rules", "generate_basic", "pre_fill")
|
||||
|
||||
|
||||
def setup_solo_multiworld(world_type: Type[World], steps: Tuple[str, ...] = gen_steps) -> MultiWorld:
|
||||
def setup_solo_multiworld(
|
||||
world_type: Type[World], steps: Tuple[str, ...] = gen_steps, seed: Optional[int] = None
|
||||
) -> MultiWorld:
|
||||
"""
|
||||
Creates a multiworld with a single player of `world_type`, sets default options, and calls provided gen steps.
|
||||
|
||||
:param world_type: Type of the world to generate a multiworld for
|
||||
:param steps: The gen steps that should be called on the generated multiworld before returning. Default calls
|
||||
steps through pre_fill
|
||||
:param seed: The seed to be used when creating this multiworld
|
||||
"""
|
||||
multiworld = MultiWorld(1)
|
||||
multiworld.game[1] = world_type.game
|
||||
multiworld.player_name = {1: "Tester"}
|
||||
multiworld.set_seed()
|
||||
multiworld.set_seed(seed)
|
||||
multiworld.state = CollectionState(multiworld)
|
||||
args = Namespace()
|
||||
for name, option in world_type.options_dataclass.type_hints.items():
|
||||
|
|
|
@ -13,6 +13,7 @@ from worlds.generic.Rules import CollectionRule, add_item_rule, locality_rules,
|
|||
|
||||
def generate_multiworld(players: int = 1) -> MultiWorld:
|
||||
multiworld = MultiWorld(players)
|
||||
multiworld.set_seed(0)
|
||||
multiworld.player_name = {}
|
||||
multiworld.state = CollectionState(multiworld)
|
||||
for i in range(players):
|
||||
|
@ -32,8 +33,6 @@ def generate_multiworld(players: int = 1) -> MultiWorld:
|
|||
world.options = world.options_dataclass(**{option_key: getattr(multiworld, option_key)[player_id]
|
||||
for option_key in world.options_dataclass.type_hints})
|
||||
|
||||
multiworld.set_seed(0)
|
||||
|
||||
return multiworld
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import hashlib
|
||||
import logging
|
||||
import pathlib
|
||||
import random
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
@ -299,6 +300,8 @@ class World(metaclass=AutoWorldRegister):
|
|||
assert multiworld is not None
|
||||
self.multiworld = multiworld
|
||||
self.player = player
|
||||
self.random = random.Random(multiworld.random.getrandbits(64))
|
||||
multiworld.per_slot_randoms[player] = self.random
|
||||
|
||||
def __getattr__(self, item: str) -> Any:
|
||||
if item == "settings":
|
||||
|
|
|
@ -37,8 +37,7 @@ def setup_dlc_quest_solo_multiworld(test_options=None, seed=None, _cache: Dict[F
|
|||
if frozen_options in _cache:
|
||||
return _cache[frozen_options]
|
||||
|
||||
multiworld = setup_base_solo_multiworld(DLCqworld, ())
|
||||
multiworld.set_seed(seed)
|
||||
multiworld = setup_base_solo_multiworld(DLCqworld, (), seed=seed)
|
||||
# print(f"Seed: {multiworld.seed}") # Uncomment to print the seed for every test
|
||||
args = Namespace()
|
||||
for name, option in DLCqworld.options_dataclass.type_hints.items():
|
||||
|
|
|
@ -124,8 +124,7 @@ def setup_solo_multiworld(test_options=None, seed=None,
|
|||
if frozen_options in _cache:
|
||||
return _cache[frozen_options]
|
||||
|
||||
multiworld = setup_base_solo_multiworld(StardewValleyWorld, ())
|
||||
multiworld.set_seed(seed)
|
||||
multiworld = setup_base_solo_multiworld(StardewValleyWorld, (), seed=seed)
|
||||
# print(f"Seed: {multiworld.seed}") # Uncomment to print the seed for every test
|
||||
args = Namespace()
|
||||
for name, option in StardewValleyWorld.options_dataclass.type_hints.items():
|
||||
|
|
Loading…
Reference in New Issue