Example #1
0
async def _create_description(generator_params: GeneratorParameters,
                              status_update: Callable[[str], None],
                              attempts: int,
                              ) -> LayoutDescription:
    """
    :param generator_params:
    :param status_update:
    :return:
    """
    rng = Random(generator_params.as_bytes)

    presets = [
        generator_params.get_preset(i)
        for i in range(generator_params.player_count)
    ]

    retrying = tenacity.AsyncRetrying(
        stop=tenacity.stop_after_attempt(attempts),
        retry=tenacity.retry_if_exception_type(UnableToGenerate),
        reraise=True
    )

    filler_results = await retrying(_create_pools_and_fill, rng, presets, status_update)

    all_patches = _distribute_remaining_items(rng, filler_results.player_results)
    return LayoutDescription.create_new(
        generator_parameters=generator_params,
        all_patches=all_patches,
        item_order=filler_results.action_log,
    )
Example #2
0
async def generate_and_validate_description(
    generator_params: GeneratorParameters,
    status_update: Optional[Callable[[str], None]],
    validate_after_generation: bool,
    timeout: Optional[int] = 600,
    attempts: int = 15,
) -> LayoutDescription:
    """
    Creates a LayoutDescription for the given Permalink.
    :param generator_params:
    :param status_update:
    :param validate_after_generation:
    :param timeout: Abort generation after this many seconds.
    :param attempts: Attempt this many generations.
    :return:
    """
    if status_update is None:
        status_update = id

    try:
        result = await _create_description(
            generator_params=generator_params,
            status_update=status_update,
            attempts=attempts,
        )
    except UnableToGenerate as e:
        raise GenerationFailure(
            "Could not generate a game with the given settings",
            generator_params=generator_params,
            source=e) from e

    if validate_after_generation and generator_params.player_count == 1:
        final_state_async = resolver.resolve(
            configuration=generator_params.get_preset(0).configuration,
            patches=result.all_patches[0],
            status_update=status_update,
        )
        try:
            final_state_by_resolve = await asyncio.wait_for(
                final_state_async, timeout)
        except asyncio.TimeoutError as e:
            raise GenerationFailure(
                "Timeout reached when validating possibility",
                generator_params=generator_params,
                source=e) from e

        if final_state_by_resolve is None:
            raise GenerationFailure(
                "Generated game was considered impossible by the solver",
                generator_params=generator_params,
                source=ImpossibleForSolver())

    return result