valanga 0.1.11__tar.gz → 0.1.14__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.
- {valanga-0.1.11 → valanga-0.1.14}/PKG-INFO +4 -4
- {valanga-0.1.11 → valanga-0.1.14}/pyproject.toml +15 -10
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/evaluations.py +7 -11
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/game.py +30 -21
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/over_event.py +51 -30
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/policy.py +20 -9
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/progress_messsage.py +3 -5
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/representation_factory.py +15 -12
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/represention_for_evaluation.py +9 -7
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga.egg-info/PKG-INFO +4 -4
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga.egg-info/requires.txt +3 -3
- {valanga-0.1.11 → valanga-0.1.14}/tests/test_over_event.py +11 -0
- {valanga-0.1.11 → valanga-0.1.14}/tests/test_placeholder.py +2 -2
- {valanga-0.1.11 → valanga-0.1.14}/tests/test_representation_factory.py +9 -0
- {valanga-0.1.11 → valanga-0.1.14}/LICENSE +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/README.md +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/setup.cfg +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/__init__.py +12 -12
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/evaluator_types.py +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga/py.typed +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga.egg-info/SOURCES.txt +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga.egg-info/dependency_links.txt +0 -0
- {valanga-0.1.11 → valanga-0.1.14}/src/valanga.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: valanga
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: Shared types and utilities for evaluation
|
|
5
5
|
Author-email: Victor Gabillon <victorgabillon@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -684,11 +684,11 @@ Requires-Python: >=3.13
|
|
|
684
684
|
Description-Content-Type: text/markdown
|
|
685
685
|
License-File: LICENSE
|
|
686
686
|
Provides-Extra: test
|
|
687
|
-
Requires-Dist: pytest>=
|
|
687
|
+
Requires-Dist: pytest>=9.0.2; extra == "test"
|
|
688
688
|
Requires-Dist: coverage; extra == "test"
|
|
689
689
|
Requires-Dist: pytest-cov>=6.0.0; extra == "test"
|
|
690
690
|
Provides-Extra: lint
|
|
691
|
-
Requires-Dist: ruff>=0.
|
|
691
|
+
Requires-Dist: ruff>=0.15.0; extra == "lint"
|
|
692
692
|
Requires-Dist: pylint>=4.0.4; extra == "lint"
|
|
693
693
|
Provides-Extra: typecheck
|
|
694
694
|
Requires-Dist: mypy>=1.19.1; extra == "typecheck"
|
|
@@ -696,7 +696,7 @@ Requires-Dist: pyright[nodejs]>=1.1.408; extra == "typecheck"
|
|
|
696
696
|
Provides-Extra: dev
|
|
697
697
|
Requires-Dist: tox>=4.32.0; extra == "dev"
|
|
698
698
|
Requires-Dist: types-PyYAML>=6.0.12.12; extra == "dev"
|
|
699
|
-
Requires-Dist: ruff>=0.
|
|
699
|
+
Requires-Dist: ruff>=0.15.0; extra == "dev"
|
|
700
700
|
Requires-Dist: pylint>=4.0.4; extra == "dev"
|
|
701
701
|
Requires-Dist: black>=25.12.0; extra == "dev"
|
|
702
702
|
Requires-Dist: mypy>=1.19.1; extra == "dev"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["setuptools>=80.
|
|
2
|
+
requires = ["setuptools>=80.10.2", "wheel"]
|
|
3
3
|
build-backend = "setuptools.build_meta"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "valanga"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.14"
|
|
8
8
|
description = "Shared types and utilities for evaluation"
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
10
|
dependencies = []
|
|
@@ -20,13 +20,13 @@ classifiers = [
|
|
|
20
20
|
[project.optional-dependencies]
|
|
21
21
|
test = [
|
|
22
22
|
# Testing dependencies
|
|
23
|
-
"pytest>=
|
|
23
|
+
"pytest>=9.0.2",
|
|
24
24
|
"coverage",
|
|
25
25
|
"pytest-cov>=6.0.0"
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
lint = [
|
|
29
|
-
"ruff>=0.
|
|
29
|
+
"ruff>=0.15.0",
|
|
30
30
|
"pylint>=4.0.4",
|
|
31
31
|
]
|
|
32
32
|
|
|
@@ -42,7 +42,7 @@ dev = [
|
|
|
42
42
|
"types-PyYAML>=6.0.12.12",
|
|
43
43
|
|
|
44
44
|
# Linting & formatting
|
|
45
|
-
"ruff>=0.
|
|
45
|
+
"ruff>=0.15.0",
|
|
46
46
|
"pylint>=4.0.4",
|
|
47
47
|
"black>=25.12.0",
|
|
48
48
|
|
|
@@ -120,13 +120,18 @@ line-length = 88
|
|
|
120
120
|
target-version = "py313"
|
|
121
121
|
|
|
122
122
|
# Enable import sorting (alphabetical + group order)
|
|
123
|
-
lint.select = ["I", "F", "E", "B", "TCH"
|
|
123
|
+
lint.select = ["I", "F", "E", "B", "TCH","UP","SIM",
|
|
124
|
+
"C4", "RUF", "PL","RET","ARG","ANN", "PERF", "TRY","LOG","RSE",
|
|
125
|
+
"D","ISC","PIE","ERA","TD"] # I = imports, F = pyflakes, E = pycodestyle, TCH = type-checking, B = black
|
|
124
126
|
|
|
125
127
|
# Allow auto-fixing for imports and type-checking imports
|
|
126
|
-
lint.fixable = ["I", "TCH", "F401"]
|
|
128
|
+
lint.fixable = ["I", "TCH", "F401", "RUF","PL","D"]
|
|
127
129
|
|
|
128
130
|
# Ignore rules you don't care about
|
|
129
|
-
lint.ignore = [ "E501"
|
|
131
|
+
lint.ignore = [ "E501",
|
|
132
|
+
"D203", # incompatible with D211
|
|
133
|
+
"D213", # incompatible with D212
|
|
134
|
+
]
|
|
130
135
|
|
|
131
136
|
# Optional: add your first-party package to extend the known group
|
|
132
137
|
[tool.ruff.lint.per-file-ignores]
|
|
@@ -186,10 +191,10 @@ commands = [["pytest", "{posargs}"]]
|
|
|
186
191
|
[tool.tox.env.lint]
|
|
187
192
|
description = "ruff + pylint (fast, no package install)"
|
|
188
193
|
package = "skip"
|
|
189
|
-
deps = ["ruff>=0.
|
|
194
|
+
deps = ["ruff>=0.15.0", "pylint>=4.0.4"]
|
|
190
195
|
set_env = { PYTHONPATH = "{toxinidir}/src" }
|
|
191
196
|
commands = [
|
|
192
|
-
["python", "-m", "ruff", "check", "src"
|
|
197
|
+
["python", "-m", "ruff", "check", "src"],
|
|
193
198
|
["python", "-m", "ruff", "format", "--check", "src", "tests"],
|
|
194
199
|
["python", "-m", "pylint", "src/valanga"],
|
|
195
200
|
]
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Evaluation-related classes and types.
|
|
3
|
-
"""
|
|
1
|
+
"""Evaluation-related classes and types."""
|
|
4
2
|
|
|
5
3
|
from dataclasses import dataclass
|
|
6
4
|
from typing import Protocol
|
|
@@ -13,8 +11,8 @@ from .represention_for_evaluation import ContentRepresentation
|
|
|
13
11
|
|
|
14
12
|
|
|
15
13
|
class EvalItem[StateT: State](Protocol):
|
|
16
|
-
"""
|
|
17
|
-
|
|
14
|
+
"""Define the protocol for an evaluation item.
|
|
15
|
+
|
|
18
16
|
An evaluation item is something that has a state and optionally a representation of that state.
|
|
19
17
|
"""
|
|
20
18
|
|
|
@@ -33,9 +31,7 @@ class EvalItem[StateT: State](Protocol):
|
|
|
33
31
|
|
|
34
32
|
@dataclass
|
|
35
33
|
class ForcedOutcome:
|
|
36
|
-
"""
|
|
37
|
-
The class
|
|
38
|
-
"""
|
|
34
|
+
"""The class."""
|
|
39
35
|
|
|
40
36
|
# The forced outcome with optimal play by both sides.
|
|
41
37
|
outcome: OverEvent
|
|
@@ -46,13 +42,13 @@ class ForcedOutcome:
|
|
|
46
42
|
|
|
47
43
|
@dataclass
|
|
48
44
|
class FloatyStateEvaluation:
|
|
49
|
-
"""
|
|
50
|
-
|
|
45
|
+
"""Define what is an evaluation of a board.
|
|
46
|
+
|
|
51
47
|
By convention is it always evaluated from the view point of the white side.
|
|
52
48
|
"""
|
|
53
49
|
|
|
54
50
|
# The evaluation value for the white side when the outcome is not certain. Typically, a float.
|
|
55
|
-
#
|
|
51
|
+
# TODO(victor): can we remove the None option? see issue #642
|
|
56
52
|
value_white: float | None
|
|
57
53
|
|
|
58
54
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Common types and utilities representing game objects shared by multiple libraries.
|
|
3
|
-
"""
|
|
1
|
+
"""Common types and utilities representing game objects shared by multiple libraries."""
|
|
4
2
|
|
|
5
|
-
from collections.abc import Hashable
|
|
3
|
+
from collections.abc import Hashable, Iterator, Sequence
|
|
6
4
|
from dataclasses import dataclass, field
|
|
7
5
|
from enum import Enum
|
|
8
|
-
from typing import Annotated, Any,
|
|
6
|
+
from typing import Annotated, Any, Protocol, Self, TypeVar
|
|
9
7
|
|
|
10
8
|
type Seed = Annotated[int, "seed"]
|
|
11
9
|
|
|
@@ -33,34 +31,36 @@ class BranchKeyGeneratorP(Protocol[T_co]):
|
|
|
33
31
|
|
|
34
32
|
@property
|
|
35
33
|
def all_generated_keys(self) -> Sequence[T_co] | None:
|
|
36
|
-
"""
|
|
34
|
+
"""Return all generated branch keys if available, otherwise None."""
|
|
37
35
|
...
|
|
38
36
|
|
|
39
37
|
def __iter__(self) -> Iterator[T_co]:
|
|
40
|
-
"""
|
|
38
|
+
"""Return an iterator over the branch keys."""
|
|
41
39
|
...
|
|
42
40
|
|
|
43
41
|
def __next__(self) -> T_co:
|
|
44
|
-
"""
|
|
42
|
+
"""Return the next branch key."""
|
|
45
43
|
...
|
|
46
44
|
|
|
47
45
|
def more_than_one(self) -> bool:
|
|
48
|
-
"""
|
|
46
|
+
"""Check if there is more than one branch available.
|
|
49
47
|
|
|
50
48
|
Returns:
|
|
51
49
|
bool: True if there is more than one branch, False otherwise.
|
|
50
|
+
|
|
52
51
|
"""
|
|
53
52
|
...
|
|
54
53
|
|
|
55
54
|
def get_all(self) -> Sequence[T_co]:
|
|
56
|
-
"""
|
|
55
|
+
"""Return a list of all branch keys."""
|
|
57
56
|
...
|
|
58
57
|
|
|
59
58
|
def copy_with_reset(self) -> Self:
|
|
60
|
-
"""
|
|
59
|
+
"""Create a copy of the legal move generator with an optional reset of generated moves.
|
|
61
60
|
|
|
62
61
|
Returns:
|
|
63
62
|
Self: A new instance of the legal move generator with the specified generated moves.
|
|
63
|
+
|
|
64
64
|
"""
|
|
65
65
|
...
|
|
66
66
|
|
|
@@ -70,54 +70,59 @@ class State(Protocol):
|
|
|
70
70
|
|
|
71
71
|
@property
|
|
72
72
|
def tag(self) -> StateTag:
|
|
73
|
-
"""
|
|
73
|
+
"""Return the tag of the content.
|
|
74
74
|
|
|
75
75
|
Returns:
|
|
76
76
|
StateTag: The tag of the content.
|
|
77
|
+
|
|
77
78
|
"""
|
|
78
79
|
...
|
|
79
80
|
|
|
80
81
|
@property
|
|
81
82
|
def branch_keys(self) -> BranchKeyGeneratorP[BranchKey]:
|
|
82
|
-
"""
|
|
83
|
+
"""Return the branch keys associated with the content.
|
|
83
84
|
|
|
84
85
|
Returns:
|
|
85
86
|
BranchKeyGeneratorP: The branch keys associated with the content.
|
|
87
|
+
|
|
86
88
|
"""
|
|
87
89
|
...
|
|
88
90
|
|
|
89
91
|
def branch_name_from_key(self, key: BranchKey) -> str:
|
|
90
|
-
"""
|
|
92
|
+
"""Return the branch name corresponding to the given branch key.
|
|
91
93
|
|
|
92
94
|
Args:
|
|
93
95
|
key (BranchKey): The branch key.
|
|
94
96
|
|
|
95
97
|
Returns:
|
|
96
98
|
str: The branch name corresponding to the given branch key.
|
|
99
|
+
|
|
97
100
|
"""
|
|
98
101
|
...
|
|
99
102
|
|
|
100
103
|
def branch_key_from_name(self, name: str) -> BranchKey:
|
|
101
|
-
"""
|
|
104
|
+
"""Return the branch key corresponding to the given branch name.
|
|
102
105
|
|
|
103
106
|
Args:
|
|
104
107
|
name (str): The branch name.
|
|
108
|
+
|
|
105
109
|
Returns:
|
|
106
110
|
BranchKey: The branch key corresponding to the given branch name.
|
|
111
|
+
|
|
107
112
|
"""
|
|
108
113
|
...
|
|
109
114
|
|
|
110
115
|
def is_game_over(self) -> bool:
|
|
111
|
-
"""
|
|
116
|
+
"""Check if the game represented by the content is over.
|
|
112
117
|
|
|
113
118
|
Returns:
|
|
114
119
|
bool: True if the game is over, False otherwise.
|
|
120
|
+
|
|
115
121
|
"""
|
|
116
122
|
...
|
|
117
123
|
|
|
118
124
|
def copy(self, stack: bool, deep_copy_legal_moves: bool = True) -> Self:
|
|
119
|
-
"""
|
|
120
|
-
Create a copy of the current board.
|
|
125
|
+
"""Create a copy of the current board.
|
|
121
126
|
|
|
122
127
|
Args:
|
|
123
128
|
stack (bool): Whether to copy the previous action stack as well. Important in some games.
|
|
@@ -125,25 +130,28 @@ class State(Protocol):
|
|
|
125
130
|
|
|
126
131
|
Returns:
|
|
127
132
|
BoardChi: A new instance of the BoardChi class with the copied board.
|
|
133
|
+
|
|
128
134
|
"""
|
|
129
135
|
...
|
|
130
136
|
|
|
131
137
|
def step(self, branch_key: BranchKey) -> StateModifications | None:
|
|
132
|
-
"""
|
|
138
|
+
"""Advance the state by applying the action corresponding to the given branch key.
|
|
133
139
|
|
|
134
140
|
Args:
|
|
135
141
|
branch_key (BranchKey): The branch key representing the action to be applied.
|
|
136
142
|
|
|
137
143
|
Returns:
|
|
138
144
|
StateModifications | None: The modifications to the state after applying the action, or None if the action is invalid.
|
|
145
|
+
|
|
139
146
|
"""
|
|
140
147
|
...
|
|
141
148
|
|
|
142
149
|
def pprint(self) -> str:
|
|
143
|
-
"""
|
|
150
|
+
"""Return a pretty-printed string representation of the content.
|
|
144
151
|
|
|
145
152
|
Returns:
|
|
146
153
|
str: A pretty-printed string representation of the content.
|
|
154
|
+
|
|
147
155
|
"""
|
|
148
156
|
...
|
|
149
157
|
|
|
@@ -185,10 +193,11 @@ class HasTurn(Protocol):
|
|
|
185
193
|
|
|
186
194
|
@property
|
|
187
195
|
def turn(self) -> Color:
|
|
188
|
-
"""
|
|
196
|
+
"""Return the tag of the content.
|
|
189
197
|
|
|
190
198
|
Returns:
|
|
191
199
|
ContentTag: The tag of the content.
|
|
200
|
+
|
|
192
201
|
"""
|
|
193
202
|
...
|
|
194
203
|
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Module for handling game over events.
|
|
3
|
-
"""
|
|
1
|
+
"""Module for handling game over events."""
|
|
4
2
|
|
|
5
3
|
from dataclasses import dataclass
|
|
6
|
-
from enum import Enum
|
|
4
|
+
from enum import Enum, StrEnum
|
|
7
5
|
|
|
8
6
|
from .game import Color
|
|
9
7
|
|
|
10
8
|
|
|
9
|
+
class WinnerNotProperlyDefinedError(ValueError):
|
|
10
|
+
"""Winner is not properly defined."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class OverNotProperlyDefinedError(ValueError):
|
|
14
|
+
"""Over is not properly defined."""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class OverEventInvariantError(ValueError):
|
|
18
|
+
"""OverEvent reached an invalid state."""
|
|
19
|
+
|
|
20
|
+
|
|
11
21
|
class HowOver(Enum):
|
|
12
22
|
"""Represents the possible outcomes of a game.
|
|
13
23
|
|
|
@@ -15,6 +25,7 @@ class HowOver(Enum):
|
|
|
15
25
|
WIN (int): Indicates a win.
|
|
16
26
|
DRAW (int): Indicates a draw.
|
|
17
27
|
DO_NOT_KNOW_OVER (int): Indicates that the outcome is unknown.
|
|
28
|
+
|
|
18
29
|
"""
|
|
19
30
|
|
|
20
31
|
WIN = 1
|
|
@@ -37,6 +48,7 @@ class Winner(Enum):
|
|
|
37
48
|
is_none() -> bool: Checks if the winner is None.
|
|
38
49
|
is_white() -> bool: Checks if the winner is white.
|
|
39
50
|
is_black() -> bool: Checks if the winner is black.
|
|
51
|
+
|
|
40
52
|
"""
|
|
41
53
|
|
|
42
54
|
WHITE = Color.WHITE
|
|
@@ -48,6 +60,7 @@ class Winner(Enum):
|
|
|
48
60
|
|
|
49
61
|
Returns:
|
|
50
62
|
bool: True if the winner is NO_KNOWN_WINNER, False otherwise.
|
|
63
|
+
|
|
51
64
|
"""
|
|
52
65
|
return self is Winner.NO_KNOWN_WINNER
|
|
53
66
|
|
|
@@ -56,12 +69,10 @@ class Winner(Enum):
|
|
|
56
69
|
|
|
57
70
|
Returns:
|
|
58
71
|
bool: True if the winner is white, False otherwise.
|
|
72
|
+
|
|
59
73
|
"""
|
|
60
74
|
is_white_bool: bool
|
|
61
|
-
if not self.is_none()
|
|
62
|
-
is_white_bool = self is Winner.WHITE
|
|
63
|
-
else:
|
|
64
|
-
is_white_bool = False
|
|
75
|
+
is_white_bool = self is Winner.WHITE if not self.is_none() else False
|
|
65
76
|
return is_white_bool
|
|
66
77
|
|
|
67
78
|
def is_black(self) -> bool:
|
|
@@ -69,17 +80,15 @@ class Winner(Enum):
|
|
|
69
80
|
|
|
70
81
|
Returns:
|
|
71
82
|
bool: True if the winner is black, False otherwise.
|
|
83
|
+
|
|
72
84
|
"""
|
|
73
85
|
is_black_bool: bool
|
|
74
86
|
|
|
75
|
-
if not self.is_none()
|
|
76
|
-
is_black_bool = self is Winner.BLACK
|
|
77
|
-
else:
|
|
78
|
-
is_black_bool = False
|
|
87
|
+
is_black_bool = self is Winner.BLACK if not self.is_none() else False
|
|
79
88
|
return is_black_bool
|
|
80
89
|
|
|
81
90
|
|
|
82
|
-
class OverTags(
|
|
91
|
+
class OverTags(StrEnum):
|
|
83
92
|
"""Represents the possible tags for game over events.
|
|
84
93
|
|
|
85
94
|
Attributes:
|
|
@@ -87,6 +96,7 @@ class OverTags(str, Enum):
|
|
|
87
96
|
TAG_WIN_BLACK (str): Tag indicating a win for the black player.
|
|
88
97
|
TAG_DRAW (str): Tag indicating a draw.
|
|
89
98
|
TAG_DO_NOT_KNOW (str): Tag indicating an unknown outcome.
|
|
99
|
+
|
|
90
100
|
"""
|
|
91
101
|
|
|
92
102
|
TAG_WIN_WHITE = "Win-Wh"
|
|
@@ -119,6 +129,7 @@ class OverEvent:
|
|
|
119
129
|
is_winner: Checks if the specified player is the winner.
|
|
120
130
|
print_info: Prints information about the `OverEvent` object.
|
|
121
131
|
test: Performs tests on the `OverEvent` object.
|
|
132
|
+
|
|
122
133
|
"""
|
|
123
134
|
|
|
124
135
|
how_over: HowOver = HowOver.DO_NOT_KNOW_OVER
|
|
@@ -126,6 +137,7 @@ class OverEvent:
|
|
|
126
137
|
termination: Enum | None = None # Optional termination reason
|
|
127
138
|
|
|
128
139
|
def __post_init__(self) -> None:
|
|
140
|
+
"""Validate the initial over event state."""
|
|
129
141
|
assert self.how_over in HowOver
|
|
130
142
|
assert self.who_is_winner in Winner
|
|
131
143
|
|
|
@@ -142,24 +154,27 @@ class OverEvent:
|
|
|
142
154
|
termination: Enum | None,
|
|
143
155
|
who_is_winner: Winner = Winner.NO_KNOWN_WINNER,
|
|
144
156
|
) -> None:
|
|
145
|
-
"""
|
|
157
|
+
"""Set the `how_over` and `who_is_winner` attributes.
|
|
146
158
|
|
|
147
159
|
Args:
|
|
148
160
|
how_over (HowOver): The way the game ended.
|
|
161
|
+
termination (Enum | None): Optional termination reason.
|
|
149
162
|
who_is_winner (Winner, optional): The winner of the game. Defaults to `Winner.NO_KNOWN_WINNER`.
|
|
163
|
+
|
|
150
164
|
"""
|
|
151
165
|
self.how_over = how_over
|
|
152
166
|
self.who_is_winner = who_is_winner
|
|
153
167
|
self.termination = termination
|
|
154
168
|
|
|
155
169
|
def get_over_tag(self) -> OverTags:
|
|
156
|
-
"""
|
|
170
|
+
"""Return a tag string used in databases.
|
|
157
171
|
|
|
158
172
|
Returns:
|
|
159
173
|
OverTags: The tag string representing the game outcome.
|
|
160
174
|
|
|
161
175
|
Raises:
|
|
162
176
|
Exception: If the winner is not properly defined.
|
|
177
|
+
|
|
163
178
|
"""
|
|
164
179
|
over_tag: OverTags
|
|
165
180
|
if self.how_over == HowOver.WIN:
|
|
@@ -168,49 +183,53 @@ class OverEvent:
|
|
|
168
183
|
elif self.who_is_winner.is_black():
|
|
169
184
|
over_tag = OverTags.TAG_WIN_BLACK
|
|
170
185
|
else:
|
|
171
|
-
raise
|
|
186
|
+
raise WinnerNotProperlyDefinedError
|
|
172
187
|
elif self.how_over == HowOver.DRAW:
|
|
173
188
|
over_tag = OverTags.TAG_DRAW
|
|
174
189
|
elif self.how_over == HowOver.DO_NOT_KNOW_OVER:
|
|
175
190
|
over_tag = OverTags.TAG_DO_NOT_KNOW
|
|
176
191
|
else:
|
|
177
|
-
raise
|
|
192
|
+
raise OverNotProperlyDefinedError
|
|
178
193
|
return over_tag
|
|
179
194
|
|
|
180
195
|
def __bool__(self) -> None:
|
|
181
|
-
"""
|
|
196
|
+
"""Raise an exception.
|
|
182
197
|
|
|
183
198
|
Raises:
|
|
184
199
|
Exception: Always raises an exception.
|
|
200
|
+
|
|
185
201
|
"""
|
|
186
|
-
raise
|
|
202
|
+
raise OverEventInvariantError
|
|
187
203
|
|
|
188
204
|
def is_over(self) -> bool:
|
|
189
|
-
"""
|
|
205
|
+
"""Check if the game is over.
|
|
190
206
|
|
|
191
207
|
Returns:
|
|
192
208
|
bool: True if the game is over, False otherwise.
|
|
209
|
+
|
|
193
210
|
"""
|
|
194
211
|
return self.how_over in {HowOver.WIN, HowOver.DRAW}
|
|
195
212
|
|
|
196
213
|
def is_win(self) -> bool:
|
|
197
|
-
"""
|
|
214
|
+
"""Check if the game ended with a win.
|
|
198
215
|
|
|
199
216
|
Returns:
|
|
200
217
|
bool: True if the game ended with a win, False otherwise.
|
|
218
|
+
|
|
201
219
|
"""
|
|
202
220
|
return self.how_over == HowOver.WIN
|
|
203
221
|
|
|
204
222
|
def is_draw(self) -> bool:
|
|
205
|
-
"""
|
|
223
|
+
"""Check if the game ended with a draw.
|
|
206
224
|
|
|
207
225
|
Returns:
|
|
208
226
|
bool: True if the game ended with a draw, False otherwise.
|
|
227
|
+
|
|
209
228
|
"""
|
|
210
229
|
return self.how_over == HowOver.DRAW
|
|
211
230
|
|
|
212
231
|
def is_winner(self, player: Color) -> bool:
|
|
213
|
-
"""
|
|
232
|
+
"""Check if the specified player is the winner.
|
|
214
233
|
|
|
215
234
|
Args:
|
|
216
235
|
player (chess.Color): The player to check.
|
|
@@ -220,23 +239,25 @@ class OverEvent:
|
|
|
220
239
|
|
|
221
240
|
Raises:
|
|
222
241
|
AssertionError: If the `player` argument is not a valid value from the `chess.Color` enum.
|
|
242
|
+
|
|
223
243
|
"""
|
|
224
244
|
assert player in {Color.WHITE, Color.BLACK}
|
|
225
245
|
|
|
226
246
|
is_winner: bool
|
|
227
247
|
if self.how_over == HowOver.WIN:
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
248
|
+
winner_color = {
|
|
249
|
+
Winner.WHITE: Color.WHITE,
|
|
250
|
+
Winner.BLACK: Color.BLACK,
|
|
251
|
+
}.get(self.who_is_winner)
|
|
252
|
+
|
|
253
|
+
is_winner = player == winner_color
|
|
254
|
+
|
|
234
255
|
else:
|
|
235
256
|
is_winner = False
|
|
236
257
|
return is_winner
|
|
237
258
|
|
|
238
259
|
def print_info(self) -> None:
|
|
239
|
-
"""
|
|
260
|
+
"""Print information about the `OverEvent` object."""
|
|
240
261
|
print(
|
|
241
262
|
"over_event:",
|
|
242
263
|
"how_over:",
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Policy-related classes and protocols for branch selection in game trees.
|
|
3
|
-
"""
|
|
1
|
+
"""Policy-related classes and protocols for branch selection in game trees."""
|
|
4
2
|
|
|
3
|
+
from collections.abc import Callable, Mapping
|
|
5
4
|
from dataclasses import dataclass
|
|
6
|
-
from typing import
|
|
5
|
+
from typing import Protocol, TypeVar
|
|
7
6
|
|
|
8
7
|
from valanga.evaluations import StateEvaluation
|
|
9
8
|
from valanga.game import BranchKey, BranchName, Seed, State
|
|
10
9
|
|
|
10
|
+
NotifyProgressCallable = Callable[[int], None] | None
|
|
11
|
+
|
|
11
12
|
|
|
12
13
|
@dataclass(frozen=True, slots=True)
|
|
13
14
|
class BranchPolicy:
|
|
14
|
-
"""
|
|
15
|
-
Represents a probability distribution over branches.
|
|
16
|
-
"""
|
|
15
|
+
"""Represents a probability distribution over branches."""
|
|
17
16
|
|
|
18
17
|
probs: Mapping[BranchKey, float] # should sum to ~1.0
|
|
19
18
|
|
|
@@ -28,15 +27,27 @@ class Recommendation:
|
|
|
28
27
|
branch_evals: Mapping[BranchName, StateEvaluation] | None = None
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
StateT_contra = TypeVar("StateT_contra", bound=State, contravariant=True)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class BranchSelector(Protocol[StateT_contra]):
|
|
32
34
|
"""Protocol for a branch selector."""
|
|
33
35
|
|
|
34
|
-
def recommend(
|
|
36
|
+
def recommend(
|
|
37
|
+
self,
|
|
38
|
+
state: StateT_contra,
|
|
39
|
+
seed: Seed,
|
|
40
|
+
notify_progress: NotifyProgressCallable | None = None,
|
|
41
|
+
) -> Recommendation:
|
|
35
42
|
"""Given a state and a seed, recommends a branch to take.
|
|
43
|
+
|
|
36
44
|
Args:
|
|
37
45
|
state (State): The current state of the game.
|
|
38
46
|
seed (Seed): A seed for any randomness involved in the selection.
|
|
47
|
+
notify_progress (NotifyProgressCallable | None): Optional callback for progress updates.
|
|
48
|
+
|
|
39
49
|
Returns:
|
|
40
50
|
Recommendation: The recommended branch to take.
|
|
51
|
+
|
|
41
52
|
"""
|
|
42
53
|
...
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Module for the ProgressMessage class.
|
|
3
|
-
"""
|
|
1
|
+
"""Module for the ProgressMessage class."""
|
|
4
2
|
|
|
5
3
|
from dataclasses import dataclass
|
|
6
4
|
|
|
@@ -9,11 +7,11 @@ from .game import Color
|
|
|
9
7
|
|
|
10
8
|
@dataclass
|
|
11
9
|
class PlayerProgressMessage:
|
|
12
|
-
"""
|
|
13
|
-
Represents a message containing evaluation information.
|
|
10
|
+
"""Represents a message containing evaluation information.
|
|
14
11
|
|
|
15
12
|
Attributes:
|
|
16
13
|
evaluation_stock (Any): The evaluation for the stock.
|
|
14
|
+
|
|
17
15
|
"""
|
|
18
16
|
|
|
19
17
|
progress_percent: int | None
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Factory for creating content representations from game states and state modifications.
|
|
3
|
-
"""
|
|
1
|
+
"""Factory for creating content representations from game states and state modifications."""
|
|
4
2
|
|
|
5
3
|
from dataclasses import dataclass
|
|
6
4
|
from typing import Protocol
|
|
@@ -11,32 +9,34 @@ from .game import State
|
|
|
11
9
|
|
|
12
10
|
|
|
13
11
|
class CreateFromState[StateT: State, EvalIn](Protocol):
|
|
14
|
-
"""
|
|
15
|
-
Protocol for creating a state representation from a state.
|
|
16
|
-
"""
|
|
12
|
+
"""Protocol for creating a state representation from a state."""
|
|
17
13
|
|
|
18
|
-
def __call__(self, state: StateT) -> ContentRepresentation[StateT, EvalIn]:
|
|
14
|
+
def __call__(self, state: StateT) -> ContentRepresentation[StateT, EvalIn]:
|
|
15
|
+
"""Create a content representation from a state."""
|
|
16
|
+
...
|
|
19
17
|
|
|
20
18
|
|
|
21
19
|
class CreateFromStateAndModifications[StateT: State, EvalIn, StateModT](Protocol):
|
|
22
|
-
"""
|
|
23
|
-
Protocol for creating a state representation from a state and modifications.
|
|
24
|
-
"""
|
|
20
|
+
"""Protocol for creating a state representation from a state and modifications."""
|
|
25
21
|
|
|
26
22
|
def __call__(
|
|
27
23
|
self,
|
|
28
24
|
state: StateT,
|
|
29
25
|
state_modifications: StateModT,
|
|
30
26
|
previous_state_representation: ContentRepresentation[StateT, EvalIn],
|
|
31
|
-
) -> ContentRepresentation[StateT, EvalIn]:
|
|
27
|
+
) -> ContentRepresentation[StateT, EvalIn]:
|
|
28
|
+
"""Create a content representation from state modifications."""
|
|
29
|
+
...
|
|
32
30
|
|
|
33
31
|
|
|
34
32
|
@dataclass
|
|
35
33
|
class RepresentationFactory[StateT: State, EvalIn, StateModT]:
|
|
36
34
|
"""Factory for creating content representations from states and state modifications.
|
|
35
|
+
|
|
37
36
|
Attributes:
|
|
38
37
|
create_from_state: Function to create a content representation from a state.
|
|
39
38
|
create_from_state_and_modifications: Function to create a content representation from a state and state modifications.
|
|
39
|
+
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
42
|
create_from_state: CreateFromState[StateT, EvalIn]
|
|
@@ -50,13 +50,16 @@ class RepresentationFactory[StateT: State, EvalIn, StateModT]:
|
|
|
50
50
|
previous_state_representation: ContentRepresentation[StateT, EvalIn] | None,
|
|
51
51
|
modifications: StateModT | None,
|
|
52
52
|
) -> ContentRepresentation[StateT, EvalIn]:
|
|
53
|
-
"""
|
|
53
|
+
"""Create a content representation from a state transition.
|
|
54
|
+
|
|
54
55
|
Args:
|
|
55
56
|
state: The current state of the game.
|
|
56
57
|
previous_state_representation: The content representation of the previous state, or None if not available.
|
|
57
58
|
modifications: The modifications applied to the previous state to reach the current state, or None if not available.
|
|
59
|
+
|
|
58
60
|
Returns:
|
|
59
61
|
ContentRepresentation[StateT, EvalIn]: The content representation of the current state.
|
|
62
|
+
|
|
60
63
|
"""
|
|
61
64
|
if previous_state_representation is None or modifications is None:
|
|
62
65
|
return self.create_from_state(state)
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Contains the definition of the ContentRepresentation protocol for content representations used in evaluations.
|
|
3
|
-
"""
|
|
1
|
+
"""Contains the definition of the ContentRepresentation protocol for content representations used in evaluations."""
|
|
4
2
|
|
|
5
3
|
from typing import Protocol, TypeVar
|
|
6
4
|
|
|
@@ -16,19 +14,23 @@ EvalIn_co = TypeVar(
|
|
|
16
14
|
|
|
17
15
|
|
|
18
16
|
class ContentRepresentation[StateT_contra, EvalIn_co](Protocol):
|
|
19
|
-
"""
|
|
20
|
-
|
|
17
|
+
"""Define the interface for a content representation.
|
|
18
|
+
|
|
21
19
|
It is a function returning the proper input for evaluation by the content evaluator.
|
|
22
20
|
"""
|
|
23
21
|
|
|
24
22
|
def get_evaluator_input(self, state: StateT_contra) -> EvalIn_co:
|
|
25
|
-
"""
|
|
26
|
-
|
|
23
|
+
"""Return the evaluator input tensor for the content.
|
|
24
|
+
|
|
25
|
+
Content representations have generally a compressed view and complementary view
|
|
26
|
+
of state info so to avoid redundancy and have all the necessary info we also
|
|
27
|
+
give the state as input.
|
|
27
28
|
|
|
28
29
|
Args:
|
|
29
30
|
state: The current state of the game.
|
|
30
31
|
|
|
31
32
|
Returns:
|
|
32
33
|
The evaluator input tensor.
|
|
34
|
+
|
|
33
35
|
"""
|
|
34
36
|
...
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: valanga
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: Shared types and utilities for evaluation
|
|
5
5
|
Author-email: Victor Gabillon <victorgabillon@gmail.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -684,11 +684,11 @@ Requires-Python: >=3.13
|
|
|
684
684
|
Description-Content-Type: text/markdown
|
|
685
685
|
License-File: LICENSE
|
|
686
686
|
Provides-Extra: test
|
|
687
|
-
Requires-Dist: pytest>=
|
|
687
|
+
Requires-Dist: pytest>=9.0.2; extra == "test"
|
|
688
688
|
Requires-Dist: coverage; extra == "test"
|
|
689
689
|
Requires-Dist: pytest-cov>=6.0.0; extra == "test"
|
|
690
690
|
Provides-Extra: lint
|
|
691
|
-
Requires-Dist: ruff>=0.
|
|
691
|
+
Requires-Dist: ruff>=0.15.0; extra == "lint"
|
|
692
692
|
Requires-Dist: pylint>=4.0.4; extra == "lint"
|
|
693
693
|
Provides-Extra: typecheck
|
|
694
694
|
Requires-Dist: mypy>=1.19.1; extra == "typecheck"
|
|
@@ -696,7 +696,7 @@ Requires-Dist: pyright[nodejs]>=1.1.408; extra == "typecheck"
|
|
|
696
696
|
Provides-Extra: dev
|
|
697
697
|
Requires-Dist: tox>=4.32.0; extra == "dev"
|
|
698
698
|
Requires-Dist: types-PyYAML>=6.0.12.12; extra == "dev"
|
|
699
|
-
Requires-Dist: ruff>=0.
|
|
699
|
+
Requires-Dist: ruff>=0.15.0; extra == "dev"
|
|
700
700
|
Requires-Dist: pylint>=4.0.4; extra == "dev"
|
|
701
701
|
Requires-Dist: black>=25.12.0; extra == "dev"
|
|
702
702
|
Requires-Dist: mypy>=1.19.1; extra == "dev"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
[dev]
|
|
3
3
|
tox>=4.32.0
|
|
4
4
|
types-PyYAML>=6.0.12.12
|
|
5
|
-
ruff>=0.
|
|
5
|
+
ruff>=0.15.0
|
|
6
6
|
pylint>=4.0.4
|
|
7
7
|
black>=25.12.0
|
|
8
8
|
mypy>=1.19.1
|
|
@@ -15,11 +15,11 @@ sphinx-autodoc-typehints
|
|
|
15
15
|
pre-commit
|
|
16
16
|
|
|
17
17
|
[lint]
|
|
18
|
-
ruff>=0.
|
|
18
|
+
ruff>=0.15.0
|
|
19
19
|
pylint>=4.0.4
|
|
20
20
|
|
|
21
21
|
[test]
|
|
22
|
-
pytest>=
|
|
22
|
+
pytest>=9.0.2
|
|
23
23
|
coverage
|
|
24
24
|
pytest-cov>=6.0.0
|
|
25
25
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
"""Tests for valanga.over_event module."""
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
|
|
3
5
|
from valanga.game import Color
|
|
@@ -12,6 +14,7 @@ from valanga.over_event import HowOver, OverEvent, OverTags, Winner
|
|
|
12
14
|
],
|
|
13
15
|
)
|
|
14
16
|
def test_get_over_tag_win_outcomes(who, expected):
|
|
17
|
+
"""Test get_over_tag for win outcomes."""
|
|
15
18
|
event = OverEvent(how_over=HowOver.WIN, who_is_winner=who)
|
|
16
19
|
|
|
17
20
|
assert event.get_over_tag() == expected
|
|
@@ -22,6 +25,7 @@ def test_get_over_tag_win_outcomes(who, expected):
|
|
|
22
25
|
|
|
23
26
|
@pytest.mark.parametrize("winner", [Winner.WHITE, Winner.BLACK])
|
|
24
27
|
def test_is_winner_matches_color(winner):
|
|
28
|
+
"""Test is_winner method for different winners."""
|
|
25
29
|
event = OverEvent(how_over=HowOver.WIN, who_is_winner=winner)
|
|
26
30
|
|
|
27
31
|
assert event.is_winner(Color.WHITE) is (winner == Winner.WHITE)
|
|
@@ -36,6 +40,7 @@ def test_is_winner_matches_color(winner):
|
|
|
36
40
|
],
|
|
37
41
|
)
|
|
38
42
|
def test_get_over_tag_draw_and_unknown(how_over, winner, expected):
|
|
43
|
+
"""Test get_over_tag for draw and unknown outcomes."""
|
|
39
44
|
event = OverEvent(how_over=how_over, who_is_winner=winner)
|
|
40
45
|
|
|
41
46
|
assert event.get_over_tag() == expected
|
|
@@ -52,12 +57,14 @@ def test_get_over_tag_draw_and_unknown(how_over, winner, expected):
|
|
|
52
57
|
],
|
|
53
58
|
)
|
|
54
59
|
def test_post_init_validates_winner_configuration(how_over, who_is_winner):
|
|
60
|
+
"""Test that invalid configurations raise AssertionError."""
|
|
55
61
|
with pytest.raises(AssertionError):
|
|
56
62
|
OverEvent(how_over=how_over, who_is_winner=who_is_winner)
|
|
57
63
|
|
|
58
64
|
|
|
59
65
|
@pytest.mark.parametrize("player", [Color.WHITE, Color.BLACK])
|
|
60
66
|
def test_is_winner_requires_win(player):
|
|
67
|
+
"""Test that is_winner returns False when the game is a draw."""
|
|
61
68
|
event = OverEvent(how_over=HowOver.DRAW, who_is_winner=Winner.NO_KNOWN_WINNER)
|
|
62
69
|
|
|
63
70
|
assert event.is_winner(player) is False
|
|
@@ -71,6 +78,7 @@ def test_is_winner_requires_win(player):
|
|
|
71
78
|
],
|
|
72
79
|
)
|
|
73
80
|
def test_get_over_tag_invalid_configurations(how_over, expected_exception):
|
|
81
|
+
"""Test that get_over_tag raises ValueError for invalid configurations."""
|
|
74
82
|
event = OverEvent(how_over=HowOver.WIN, who_is_winner=Winner.WHITE)
|
|
75
83
|
event.how_over = how_over # mutate to bypass post-init validation
|
|
76
84
|
event.who_is_winner = Winner.NO_KNOWN_WINNER
|
|
@@ -87,12 +95,14 @@ def test_get_over_tag_invalid_configurations(how_over, expected_exception):
|
|
|
87
95
|
],
|
|
88
96
|
)
|
|
89
97
|
def test_test_method_for_wins(how_over, who_is_winner):
|
|
98
|
+
"""Test the test method for win outcomes."""
|
|
90
99
|
event = OverEvent(how_over=how_over, who_is_winner=who_is_winner)
|
|
91
100
|
|
|
92
101
|
event.test()
|
|
93
102
|
|
|
94
103
|
|
|
95
104
|
def test_test_method_invalid_draw_configuration():
|
|
105
|
+
"""Test that the test method raises AssertionError for invalid draw configuration."""
|
|
96
106
|
event = OverEvent(how_over=HowOver.DRAW, who_is_winner=Winner.NO_KNOWN_WINNER)
|
|
97
107
|
|
|
98
108
|
with pytest.raises(AssertionError):
|
|
@@ -100,6 +110,7 @@ def test_test_method_invalid_draw_configuration():
|
|
|
100
110
|
|
|
101
111
|
|
|
102
112
|
def test_bool_raises():
|
|
113
|
+
"""Test that __bool__ raises ValueError."""
|
|
103
114
|
event = OverEvent()
|
|
104
115
|
|
|
105
116
|
with pytest.raises(ValueError):
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
"""Docstring for tests.test_representation_factory."""
|
|
2
|
+
|
|
1
3
|
from collections import Counter
|
|
2
4
|
|
|
3
5
|
from valanga.representation_factory import RepresentationFactory
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
class DummyRepresentation:
|
|
9
|
+
"""A dummy representation class for testing purposes."""
|
|
10
|
+
|
|
7
11
|
pass
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
def test_create_from_transition_root_uses_full_creator():
|
|
15
|
+
"""At the root, create_from_state should be used even if modifications are None."""
|
|
11
16
|
calls = Counter()
|
|
12
17
|
|
|
13
18
|
def create_from_state(state):
|
|
19
|
+
"""Mock create_from_state function."""
|
|
14
20
|
calls["create_from_state"] += 1
|
|
15
21
|
return ("state", state)
|
|
16
22
|
|
|
@@ -27,6 +33,7 @@ def test_create_from_transition_root_uses_full_creator():
|
|
|
27
33
|
|
|
28
34
|
|
|
29
35
|
def test_create_from_transition_no_modifications_falls_back_to_state():
|
|
36
|
+
"""If no modifications are provided, create_from_state should be used."""
|
|
30
37
|
calls = Counter()
|
|
31
38
|
|
|
32
39
|
def create_from_state(state):
|
|
@@ -48,11 +55,13 @@ def test_create_from_transition_no_modifications_falls_back_to_state():
|
|
|
48
55
|
|
|
49
56
|
|
|
50
57
|
def test_create_from_transition_with_modifications():
|
|
58
|
+
"""If modifications are provided, create_from_state_and_modifications should be used."""
|
|
51
59
|
calls = Counter()
|
|
52
60
|
|
|
53
61
|
def create_from_state_and_modifications(
|
|
54
62
|
state, state_modifications, previous_state_representation
|
|
55
63
|
):
|
|
64
|
+
"""Mock create_from_state_and_modifications function."""
|
|
56
65
|
calls["create_from_state_and_modifications"] += 1
|
|
57
66
|
return (state, state_modifications, previous_state_representation)
|
|
58
67
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -20,23 +20,23 @@ from .representation_factory import RepresentationFactory
|
|
|
20
20
|
from .represention_for_evaluation import ContentRepresentation
|
|
21
21
|
|
|
22
22
|
__all__ = [
|
|
23
|
-
"ForcedOutcome",
|
|
24
|
-
"FloatyStateEvaluation",
|
|
25
|
-
"StateEvaluation",
|
|
26
|
-
"EvalItem",
|
|
27
|
-
"OverEvent",
|
|
28
|
-
"Color",
|
|
29
|
-
"WHITE",
|
|
30
23
|
"BLACK",
|
|
24
|
+
"WHITE",
|
|
25
|
+
"BranchKey",
|
|
26
|
+
"BranchKeyGeneratorP",
|
|
27
|
+
"Color",
|
|
31
28
|
"ColorIndex",
|
|
32
|
-
"HasTurn",
|
|
33
|
-
"TurnState",
|
|
34
29
|
"ContentRepresentation",
|
|
30
|
+
"EvalItem",
|
|
31
|
+
"FloatyStateEvaluation",
|
|
32
|
+
"ForcedOutcome",
|
|
33
|
+
"HasTurn",
|
|
34
|
+
"OverEvent",
|
|
35
|
+
"PlayerProgressMessage",
|
|
35
36
|
"RepresentationFactory",
|
|
36
37
|
"State",
|
|
38
|
+
"StateEvaluation",
|
|
37
39
|
"StateModifications",
|
|
38
|
-
"BranchKeyGeneratorP",
|
|
39
|
-
"BranchKey",
|
|
40
|
-
"PlayerProgressMessage",
|
|
41
40
|
"StateTag",
|
|
41
|
+
"TurnState",
|
|
42
42
|
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|