algobattle-base 4.3.2__tar.gz → 4.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/PKG-INFO +2 -4
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/battle.py +48 -49
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/cli.py +105 -97
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/match.py +31 -30
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/problem.py +16 -26
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/program.py +49 -51
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/__init__.py +5 -5
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/types.py +43 -53
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/util.py +11 -16
- algobattle_base-4.3.4/pyproject.toml +156 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/test_battles.py +7 -4
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/test_docker.py +16 -3
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/test_match.py +7 -6
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/test_types.py +2 -2
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/test_util.py +4 -4
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/problem.py +2 -1
- algobattle_base-4.3.2/pyproject.toml +0 -63
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/LICENSE +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/README.md +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/__init__.py +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/py.typed +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/c/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/c/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/c/src/CMakeLists.txt +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/c/src/main.c +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/cpp/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/cpp/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/cpp/src/CMakeLists.txt +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/cpp/src/main.cpp +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/csharp/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/csharp/Program.cs +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/csharp/{{program.capitalize()}}.csproj +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/go/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/go/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/go/go.mod.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/go/main.go +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/java/.dockerignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/java/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/java/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/java/pom.xml.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/java/src/main/java/com/{{team_normalized}}/{{program.capitalize()}}.java.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/javascript/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/javascript/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/javascript/package-lock.json.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/javascript/package.json.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/javascript/{{program}}.mjs.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/plain/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/problem.py.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/python/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/python/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/python/pyproject.toml.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/python/{{program}}.py.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/rust/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/rust/Cargo.toml.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/rust/Dockerfile.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/rust/src/main.rs.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/.gitignore +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/package-lock.json.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/package.json.jinja +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/src/main.ts +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/algobattle/templates/typescript/tsconfig.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/README.md +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/__init__.py +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/configs/empty.toml +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/configs/teams.toml +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/configs/teams_incorrect.toml +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/configs/test.toml +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/README.md +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/__init__.py +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/build_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/build_timeout/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator/instance.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_execution_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_semantics_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_semantics_error/instance.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_syntax_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_syntax_error/instance.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_timeout/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/generator_timeout/instance.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver/solution.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_execution_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_semantics_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_semantics_error/solution.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_syntax_error/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_syntax_error/solution.json +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_timeout/Dockerfile +0 -0
- {algobattle_base-4.3.2 → algobattle_base-4.3.4}/tests/testsproblem/solver_timeout/solution.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: algobattle-base
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.4
|
|
4
4
|
Summary: The Algobattle lab course package.
|
|
5
5
|
Author: Imogen Hergeth, Jan Dreier, Henri Lotze
|
|
6
6
|
License: MIT
|
|
@@ -22,9 +22,7 @@ Requires-Dist: typing-extensions>=4.15.0
|
|
|
22
22
|
Requires-Dist: tomlkit>=0.13.3
|
|
23
23
|
Requires-Dist: jinja2>=3.1.6
|
|
24
24
|
Provides-Extra: dev
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist: flake8>=6.1.0; extra == "dev"
|
|
27
|
-
Requires-Dist: flake8-docstrings>=1.7.0; extra == "dev"
|
|
25
|
+
Requires-Dist: ruff>=0.13.2; extra == "dev"
|
|
28
26
|
Requires-Dist: mkdocs>=1.5.3; extra == "dev"
|
|
29
27
|
Requires-Dist: mkdocs-material>=9.5.3; extra == "dev"
|
|
30
28
|
Requires-Dist: pymdown-extensions>=10.7; extra == "dev"
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
This module contains the :class:`Battle` class, which speciefies how each type of battle is fought and scored,
|
|
4
4
|
some basic battle types, and related classed.
|
|
5
5
|
"""
|
|
6
|
+
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from collections.abc import Iterable
|
|
6
9
|
from dataclasses import dataclass, field
|
|
7
10
|
from enum import StrEnum
|
|
8
11
|
from importlib.metadata import entry_points
|
|
9
|
-
from abc import abstractmethod
|
|
10
12
|
from inspect import isclass
|
|
11
13
|
from itertools import count
|
|
12
14
|
from pathlib import Path
|
|
@@ -16,7 +18,6 @@ from typing import (
|
|
|
16
18
|
Annotated,
|
|
17
19
|
Any,
|
|
18
20
|
ClassVar,
|
|
19
|
-
Iterable,
|
|
20
21
|
Literal,
|
|
21
22
|
ParamSpec,
|
|
22
23
|
Protocol,
|
|
@@ -26,9 +27,8 @@ from typing import (
|
|
|
26
27
|
Unpack,
|
|
27
28
|
overload,
|
|
28
29
|
)
|
|
29
|
-
from typing_extensions import TypedDict
|
|
30
|
-
from annotated_types import Ge
|
|
31
30
|
|
|
31
|
+
from annotated_types import Ge
|
|
32
32
|
from pydantic import (
|
|
33
33
|
ConfigDict,
|
|
34
34
|
Field,
|
|
@@ -39,11 +39,10 @@ from pydantic import (
|
|
|
39
39
|
ValidatorFunctionWrapHandler,
|
|
40
40
|
)
|
|
41
41
|
from pydantic_core import CoreSchema
|
|
42
|
-
from pydantic_core.core_schema import
|
|
43
|
-
|
|
44
|
-
with_info_wrap_validator_function,
|
|
45
|
-
)
|
|
42
|
+
from pydantic_core.core_schema import tagged_union_schema, with_info_wrap_validator_function
|
|
43
|
+
from typing_extensions import TypedDict
|
|
46
44
|
|
|
45
|
+
from algobattle.problem import InstanceModel, Problem, SolutionModel
|
|
47
46
|
from algobattle.program import (
|
|
48
47
|
Generator,
|
|
49
48
|
GeneratorResult,
|
|
@@ -53,15 +52,7 @@ from algobattle.program import (
|
|
|
53
52
|
Solver,
|
|
54
53
|
SolverResult,
|
|
55
54
|
)
|
|
56
|
-
from algobattle.
|
|
57
|
-
from algobattle.util import (
|
|
58
|
-
Encodable,
|
|
59
|
-
EncodableModel,
|
|
60
|
-
ExceptionInfo,
|
|
61
|
-
BaseModel,
|
|
62
|
-
Role,
|
|
63
|
-
)
|
|
64
|
-
|
|
55
|
+
from algobattle.util import BaseModel, Encodable, EncodableModel, ExceptionInfo, Role
|
|
65
56
|
|
|
66
57
|
_BattleConfig: TypeAlias = Any
|
|
67
58
|
"""Type alias used to generate correct typings when subclassing :class:`Battle`.
|
|
@@ -73,7 +64,7 @@ the new battle type directly.
|
|
|
73
64
|
"""
|
|
74
65
|
T = TypeVar("T")
|
|
75
66
|
P = ParamSpec("P")
|
|
76
|
-
|
|
67
|
+
_type = type
|
|
77
68
|
|
|
78
69
|
|
|
79
70
|
class ProgramLogConfigTime(StrEnum):
|
|
@@ -91,7 +82,7 @@ class ProgramLogConfigLocation(StrEnum):
|
|
|
91
82
|
inline = "inline"
|
|
92
83
|
|
|
93
84
|
|
|
94
|
-
class ProgramLogConfigView(Protocol):
|
|
85
|
+
class ProgramLogConfigView(Protocol):
|
|
95
86
|
when: ProgramLogConfigTime = ProgramLogConfigTime.error
|
|
96
87
|
output: ProgramLogConfigLocation = ProgramLogConfigLocation.inline
|
|
97
88
|
|
|
@@ -100,7 +91,7 @@ class ProgramRunInfo(BaseModel):
|
|
|
100
91
|
"""Data about a program's execution."""
|
|
101
92
|
|
|
102
93
|
runtime: float = 0
|
|
103
|
-
overriden: RunConfigOverride = Field(default_factory=
|
|
94
|
+
overriden: RunConfigOverride = Field(default_factory=RunConfigOverride, validate_default=True)
|
|
104
95
|
error: ExceptionInfo | None = None
|
|
105
96
|
battle_data: SerializeAsAny[EncodableModel] | None = None
|
|
106
97
|
instance: SerializeAsAny[InstanceModel] | None = None
|
|
@@ -177,7 +168,7 @@ class FightUi(ProgramUi, Protocol):
|
|
|
177
168
|
"""Informs the ui that the fight has finished running and has been added to the battle's `.fight_results`."""
|
|
178
169
|
|
|
179
170
|
|
|
180
|
-
class RunKwargs(TypedDict, total=False):
|
|
171
|
+
class RunKwargs(TypedDict, total=False, closed=True):
|
|
181
172
|
"""The keyword arguments used by the FightHandler.run family of functions."""
|
|
182
173
|
|
|
183
174
|
timeout_generator: float | None
|
|
@@ -211,8 +202,7 @@ class FightHandler:
|
|
|
211
202
|
*,
|
|
212
203
|
with_results: Literal[False] = False,
|
|
213
204
|
**kwargs: Unpack[RunKwargs],
|
|
214
|
-
) -> Fight:
|
|
215
|
-
...
|
|
205
|
+
) -> Fight: ...
|
|
216
206
|
|
|
217
207
|
@overload
|
|
218
208
|
async def run(
|
|
@@ -221,8 +211,7 @@ class FightHandler:
|
|
|
221
211
|
*,
|
|
222
212
|
with_results: Literal[True],
|
|
223
213
|
**kwargs: Unpack[RunKwargs],
|
|
224
|
-
) -> tuple[Fight, GeneratorResult, SolverResult | None]:
|
|
225
|
-
...
|
|
214
|
+
) -> tuple[Fight, GeneratorResult, SolverResult | None]: ...
|
|
226
215
|
|
|
227
216
|
async def run(
|
|
228
217
|
self,
|
|
@@ -260,12 +249,7 @@ class FightHandler:
|
|
|
260
249
|
The resulting info about the executed fight, and the results if the flag has been set.
|
|
261
250
|
"""
|
|
262
251
|
gen_result, sol_result = await self.run_raw(max_size=max_size, **kwargs)
|
|
263
|
-
|
|
264
|
-
score = 1
|
|
265
|
-
elif sol_result is None or sol_result.solution is None:
|
|
266
|
-
score = 0
|
|
267
|
-
else:
|
|
268
|
-
score = self.calculate_score(gen_result, sol_result)
|
|
252
|
+
score = self.calculate_score(gen_result, sol_result)
|
|
269
253
|
fight = Fight.from_results(
|
|
270
254
|
score=score,
|
|
271
255
|
max_size=max_size,
|
|
@@ -331,7 +315,7 @@ class FightHandler:
|
|
|
331
315
|
)
|
|
332
316
|
return gen_result, sol_result
|
|
333
317
|
|
|
334
|
-
def calculate_score(self, gen_result: GeneratorResult, sol_result: SolverResult) -> float:
|
|
318
|
+
def calculate_score(self, gen_result: GeneratorResult, sol_result: SolverResult | None) -> float:
|
|
335
319
|
"""Calculates the score achieved by the solver in this fight.
|
|
336
320
|
|
|
337
321
|
Both results need to contain all instance and/or solution data required.
|
|
@@ -343,9 +327,25 @@ class FightHandler:
|
|
|
343
327
|
Returns:
|
|
344
328
|
A number in [0, 1] with higher numbers meaning the solver performed better.
|
|
345
329
|
"""
|
|
346
|
-
|
|
347
|
-
|
|
330
|
+
# We first need to check whether the generator somehow failed. This can happen in three cases:
|
|
331
|
+
# it doesn't produce an instance, it creates an invalid instance or it doesn't create a needed solution
|
|
332
|
+
# note that gen_result.instance and gen_result.error will both contain data if the generator outputted an
|
|
333
|
+
# invalid instance and/or solution
|
|
334
|
+
if (
|
|
335
|
+
gen_result.instance is None
|
|
336
|
+
or gen_result.error is not None
|
|
337
|
+
or (self.problem.with_solution and gen_result.solution is None)
|
|
338
|
+
):
|
|
339
|
+
return 1
|
|
340
|
+
# sol_result is None only if the generator failed, which needs to be caught by the above check
|
|
341
|
+
assert sol_result is not None
|
|
342
|
+
# The solver failed if it didn't output a solution or the solution contains some error
|
|
343
|
+
if sol_result.solution is None or sol_result.error is not None:
|
|
344
|
+
return 0
|
|
345
|
+
|
|
348
346
|
if self.problem.with_solution:
|
|
347
|
+
# we need this assert since type checkers can't see the dependency between self.problem.with_solution
|
|
348
|
+
# and gen_result.solution that is created by the last check in the first "if"
|
|
349
349
|
assert gen_result.solution is not None
|
|
350
350
|
score = self.problem.score(
|
|
351
351
|
gen_result.instance, solver_solution=sol_result.solution, generator_solution=gen_result.solution
|
|
@@ -394,7 +394,7 @@ class Battle(BaseModel):
|
|
|
394
394
|
"""Type of battle that will be used."""
|
|
395
395
|
|
|
396
396
|
@classmethod
|
|
397
|
-
def __get_pydantic_core_schema__(cls, source:
|
|
397
|
+
def __get_pydantic_core_schema__(cls, source: _type, handler: GetCoreSchemaHandler) -> CoreSchema:
|
|
398
398
|
# there's two bugs we need to catch:
|
|
399
399
|
# 1. this function is called during the pydantic BaseModel metaclass's __new__, so the BattleConfig class
|
|
400
400
|
# won't be ready at that point and be missing in the namespace
|
|
@@ -446,7 +446,7 @@ class Battle(BaseModel):
|
|
|
446
446
|
installed = ", ".join(b.name() for b in Battle._battle_types.values())
|
|
447
447
|
raise ValueError(
|
|
448
448
|
f"The specified battle type '{passed}' is not installed. Installed types are: {installed}"
|
|
449
|
-
)
|
|
449
|
+
) from e
|
|
450
450
|
|
|
451
451
|
return with_info_wrap_validator_function(check_installed, subclass_schema)
|
|
452
452
|
|
|
@@ -459,8 +459,7 @@ class Battle(BaseModel):
|
|
|
459
459
|
|
|
460
460
|
if TYPE_CHECKING:
|
|
461
461
|
# to hint that we're gonna fill this with arbitrary data belonging to some supposed battle type
|
|
462
|
-
def __getattr__(self,
|
|
463
|
-
...
|
|
462
|
+
def __getattr__(self, attr: str, /) -> Any: ...
|
|
464
463
|
|
|
465
464
|
class UiData(BaseModel):
|
|
466
465
|
"""Object containing custom diplay data.
|
|
@@ -560,7 +559,7 @@ class Iterated(Battle):
|
|
|
560
559
|
exit after that many failures, or `"unlimited"` to never exit early.
|
|
561
560
|
"""
|
|
562
561
|
|
|
563
|
-
class UiData(Battle.UiData):
|
|
562
|
+
class UiData(Battle.UiData):
|
|
564
563
|
reached: list[int]
|
|
565
564
|
cap: int
|
|
566
565
|
note: str
|
|
@@ -620,7 +619,7 @@ class Iterated(Battle):
|
|
|
620
619
|
return 0 if len(self.results) == 0 else sum(self.results) / len(self.results)
|
|
621
620
|
|
|
622
621
|
@staticmethod
|
|
623
|
-
def format_score(score: float) -> str:
|
|
622
|
+
def format_score(score: float) -> str:
|
|
624
623
|
return str(int(score))
|
|
625
624
|
|
|
626
625
|
|
|
@@ -637,7 +636,7 @@ class Averaged(Battle):
|
|
|
637
636
|
num_fights: int = 10
|
|
638
637
|
"""Number of iterations in each round."""
|
|
639
638
|
|
|
640
|
-
class UiData(Battle.UiData):
|
|
639
|
+
class UiData(Battle.UiData):
|
|
641
640
|
round: int
|
|
642
641
|
|
|
643
642
|
async def run_battle(self, fight: FightHandler, config: Config, min_size: int, ui: BattleUi) -> None:
|
|
@@ -659,7 +658,7 @@ class Averaged(Battle):
|
|
|
659
658
|
return sum(f.score for f in self.fights) / len(self.fights)
|
|
660
659
|
|
|
661
660
|
@staticmethod
|
|
662
|
-
def format_score(score: float) -> str:
|
|
661
|
+
def format_score(score: float) -> str:
|
|
663
662
|
return format(score, ".0%")
|
|
664
663
|
|
|
665
664
|
|
|
@@ -681,7 +680,7 @@ class FightHistory(Encodable):
|
|
|
681
680
|
gen_sols: set[Role]
|
|
682
681
|
sol_sols: set[Role]
|
|
683
682
|
|
|
684
|
-
def encode(self, target: Path, role: Role) -> None:
|
|
683
|
+
def encode(self, target: Path, role: Role) -> None:
|
|
685
684
|
target.mkdir()
|
|
686
685
|
for i, fight in enumerate(self.history):
|
|
687
686
|
fight_dir = target / str(i)
|
|
@@ -715,16 +714,16 @@ class Improving(Battle):
|
|
|
715
714
|
"""Number of fights that will be fought."""
|
|
716
715
|
weighting: Annotated[float, Ge(0)] = 1.1
|
|
717
716
|
"""How much each successive fight should be weighted more than the previous."""
|
|
718
|
-
scores: set[Role] = {Role.generator, Role.solver}
|
|
717
|
+
scores: set[Role] = {Role.generator, Role.solver} # noqa: RUF012
|
|
719
718
|
"""Who to show each fight's scores to."""
|
|
720
|
-
instances: set[Role] = {Role.generator, Role.solver}
|
|
719
|
+
instances: set[Role] = {Role.generator, Role.solver} # noqa: RUF012
|
|
721
720
|
"""Who to show the instances to."""
|
|
722
|
-
generator_solutions: set[Role] = {Role.generator}
|
|
721
|
+
generator_solutions: set[Role] = {Role.generator} # noqa: RUF012
|
|
723
722
|
"""Who to show the generator's solutions to, if the problem requires them."""
|
|
724
|
-
solver_solutions: set[Role] = {Role.solver}
|
|
723
|
+
solver_solutions: set[Role] = {Role.solver} # noqa: RUF012
|
|
725
724
|
"""Who to show the solver's solutions to."""
|
|
726
725
|
|
|
727
|
-
class UiData(Battle.UiData):
|
|
726
|
+
class UiData(Battle.UiData):
|
|
728
727
|
round: int
|
|
729
728
|
|
|
730
729
|
async def run_battle(self, fight: FightHandler, config: Config, min_size: int, ui: BattleUi) -> None:
|
|
@@ -760,5 +759,5 @@ class Improving(Battle):
|
|
|
760
759
|
return total / quotient
|
|
761
760
|
|
|
762
761
|
@staticmethod
|
|
763
|
-
def format_score(score: float) -> str:
|
|
762
|
+
def format_score(score: float) -> str:
|
|
764
763
|
return format(score, ".0%")
|