algorhino-anemone 0.1.2__tar.gz → 0.1.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.
Files changed (89) hide show
  1. {algorhino_anemone-0.1.2/src/algorhino_anemone.egg-info → algorhino_anemone-0.1.4}/PKG-INFO +3 -3
  2. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/pyproject.toml +16 -9
  3. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4/src/algorhino_anemone.egg-info}/PKG-INFO +3 -3
  4. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/algorhino_anemone.egg-info/requires.txt +2 -2
  5. algorhino_anemone-0.1.4/src/anemone/basics.py +23 -0
  6. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/factory.py +4 -2
  7. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_direct_evaluation/node_direct_evaluator.py +1 -1
  8. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_tree_evaluation/node_minmax_evaluation.py +5 -4
  9. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_tree_evaluation/node_tree_evaluation.py +4 -4
  10. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_factory/algorithm_node_factory.py +3 -1
  11. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/algorithm_node/algorithm_node.py +3 -3
  12. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/itree_node.py +1 -1
  13. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/tree_node.py +1 -1
  14. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/recommender_rule/recommender_rule.py +2 -10
  15. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_and_value_branch_selector.py +5 -6
  16. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_exploration.py +13 -10
  17. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_manager/tree_manager.py +2 -2
  18. algorhino_anemone-0.1.2/src/anemone/basics.py +0 -36
  19. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/LICENSE +0 -0
  20. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/README.md +0 -0
  21. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/setup.cfg +0 -0
  22. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/algorhino_anemone.egg-info/SOURCES.txt +0 -0
  23. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/algorhino_anemone.egg-info/dependency_links.txt +0 -0
  24. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/algorhino_anemone.egg-info/top_level.txt +0 -0
  25. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/__init__.py +0 -0
  26. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/__init__.py +0 -0
  27. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/index_manager/__init__.py +0 -0
  28. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/index_manager/factory.py +0 -0
  29. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/index_manager/node_exploration_manager.py +0 -0
  30. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/node_indices/__init__.py +0 -0
  31. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/node_indices/factory.py +0 -0
  32. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/node_indices/index_data.py +0 -0
  33. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/indices/node_indices/index_types.py +0 -0
  34. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nn/torch_evaluator.py +0 -0
  35. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/__init__.py +0 -0
  36. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_direct_evaluation/__init__.py +0 -0
  37. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_direct_evaluation/factory.py +0 -0
  38. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_evaluation/node_tree_evaluation/node_tree_evaluation_factory.py +0 -0
  39. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_factory/__init__.py +0 -0
  40. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_factory/base.py +0 -0
  41. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/__init__.py +0 -0
  42. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/branch_explorer.py +0 -0
  43. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/factory.py +0 -0
  44. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/node_selector.py +0 -0
  45. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/node_selector_args.py +0 -0
  46. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/node_selector_types.py +0 -0
  47. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/notations_and_statics.py +0 -0
  48. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/opening_instructions.py +0 -0
  49. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/recurzipf/__init__.py +0 -0
  50. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/recurzipf/recur_zipf_base.py +0 -0
  51. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/sequool/__init__.py +0 -0
  52. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/sequool/factory.py +0 -0
  53. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/sequool/sequool.py +0 -0
  54. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/uniform/__init__.py +0 -0
  55. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/node_selector/uniform/uniform.py +0 -0
  56. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/__init__.py +0 -0
  57. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/algorithm_node/__init__.py +0 -0
  58. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/tree_traversal.py +0 -0
  59. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/nodes/utils.py +0 -0
  60. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/progress_monitor/__init__.py +0 -0
  61. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/progress_monitor/progress_monitor.py +0 -0
  62. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/recommender_rule/__init__.py +0 -0
  63. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/search_factory/__init__.py +0 -0
  64. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/search_factory/search_factory.py +0 -0
  65. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/state_transition.py +0 -0
  66. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_manager/__init__.py +0 -0
  67. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_manager/algorithm_node_tree_manager.py +0 -0
  68. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_manager/factory.py +0 -0
  69. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/tree_manager/tree_expander.py +0 -0
  70. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/trees/__init__.py +0 -0
  71. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/trees/descendants.py +0 -0
  72. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/trees/factory.py +0 -0
  73. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/trees/tree.py +0 -0
  74. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/trees/tree_visualization.py +0 -0
  75. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/__init__.py +0 -0
  76. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/algorithm_node_updater.py +0 -0
  77. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/factory.py +0 -0
  78. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/index_block.py +0 -0
  79. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/index_updater.py +0 -0
  80. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/minmax_evaluation_updater.py +0 -0
  81. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/updates_file.py +0 -0
  82. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/updates/value_block.py +0 -0
  83. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/comparable.py +0 -0
  84. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/dataclass.py +0 -0
  85. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/dict_of_numbered_dict_with_pointer_on_max.py +0 -0
  86. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/logger.py +0 -0
  87. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/my_value_sorted_dict.py +0 -0
  88. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/src/anemone/utils/small_tools.py +0 -0
  89. {algorhino_anemone-0.1.2 → algorhino_anemone-0.1.4}/tests/test_indices.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: algorhino-anemone
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: anemone searches trees
5
5
  Author-email: Victor Gabillon <victorgabillon@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.13
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: valanga
16
- Requires-Dist: atomheart
15
+ Requires-Dist: valanga>=0.1.4
16
+ Requires-Dist: atomheart>=0.1.2
17
17
  Requires-Dist: rich
18
18
  Requires-Dist: sortedcollections>=2.1.0
19
19
  Requires-Dist: graphviz
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "algorhino-anemone"
8
- version = "0.1.2"
8
+ version = "0.1.4"
9
9
  description = "anemone searches trees"
10
10
  keywords = ["tree", "search"]
11
11
  classifiers = [
@@ -14,9 +14,8 @@ classifiers = [
14
14
  ]
15
15
  requires-python = ">=3.13"
16
16
  dependencies = [
17
- "valanga",
18
- "atomheart",
19
-
17
+ "valanga>=0.1.4",
18
+ "atomheart>=0.1.2",
20
19
  "rich",
21
20
  "sortedcollections>=2.1.0",
22
21
  "graphviz",
@@ -236,9 +235,17 @@ extraPaths = ["src"]
236
235
 
237
236
  [tool.tox]
238
237
  min_version = "4.32.0"
239
- env_list = ["py313", "lint", "typecheck"]
238
+ env_list = ["py313", "lint", "typecheck", "build"]
240
239
  isolated_build = true
241
240
 
241
+ [tool.tox.env.build]
242
+ deps = ["build", "twine"]
243
+ commands = [
244
+ ["python", "-m", "build"],
245
+ ["python", "-m", "twine", "check", "dist/*"],
246
+ ]
247
+
248
+
242
249
  [tool.tox.env_run_base]
243
250
  base_python = ["python3.13"]
244
251
 
@@ -258,8 +265,8 @@ description = "ruff + pylint (fast, no package build/install)"
258
265
  package = "skip"
259
266
  deps = [
260
267
  # runtime deps needed for pylint imports (match [project].dependencies)
261
- "valanga",
262
- "atomheart",
268
+ "valanga>=0.1.4",
269
+ "atomheart>=0.1.2",
263
270
  "rich",
264
271
  "sortedcollections>=2.1.0",
265
272
  "graphviz",
@@ -283,8 +290,8 @@ description = "mypy + pyright (fast, no package build/install)"
283
290
  package = "skip"
284
291
  deps = [
285
292
  # runtime deps for import resolution
286
- "valanga",
287
- "atomheart",
293
+ "valanga>=0.1.4",
294
+ "atomheart>=0.1.2",
288
295
  "rich",
289
296
  "sortedcollections>=2.1.0",
290
297
  "graphviz",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: algorhino-anemone
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: anemone searches trees
5
5
  Author-email: Victor Gabillon <victorgabillon@gmail.com>
6
6
  License-Expression: GPL-3.0-only
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
12
12
  Requires-Python: >=3.13
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
- Requires-Dist: valanga
16
- Requires-Dist: atomheart
15
+ Requires-Dist: valanga>=0.1.4
16
+ Requires-Dist: atomheart>=0.1.2
17
17
  Requires-Dist: rich
18
18
  Requires-Dist: sortedcollections>=2.1.0
19
19
  Requires-Dist: graphviz
@@ -1,5 +1,5 @@
1
- valanga
2
- atomheart
1
+ valanga>=0.1.4
2
+ atomheart>=0.1.2
3
3
  rich
4
4
  sortedcollections>=2.1.0
5
5
  graphviz
@@ -0,0 +1,23 @@
1
+ """Basic types and protocols for Anemone."""
2
+
3
+ from typing import Annotated, Protocol
4
+
5
+ from valanga import Color, HasTurn, State
6
+
7
+ type Seed = Annotated[int, "seed"]
8
+ type TreeDepth = Annotated[int, "Depth level of a node in a tree structure"]
9
+
10
+
11
+ class StateWithTurn(State, HasTurn, Protocol):
12
+ """A `valanga.State` that also exposes turn information."""
13
+
14
+ ...
15
+
16
+
17
+ class HasBlackAndWhiteTurn(Protocol):
18
+ """Protocol for state that has black and white turns."""
19
+
20
+ @property
21
+ def turn(self) -> Color:
22
+ """Return the current player's turn color."""
23
+ ...
@@ -56,7 +56,8 @@ def create_tree_and_value_branch_selector[StateT: TurnState](
56
56
  args: TreeAndValuePlayerArgs,
57
57
  random_generator: Random,
58
58
  master_state_evaluator: MasterStateEvaluator,
59
- state_representation_factory: RepresentationFactory[ContentRepresentation] | None,
59
+ state_representation_factory: RepresentationFactory[StateT, ContentRepresentation]
60
+ | None,
60
61
  queue_progress_player: Queue[IsDataclass] | None,
61
62
  ) -> TreeAndValueBranchSelector[StateT]:
62
63
  """Convenience constructor using the default minmax tree evaluation.
@@ -85,7 +86,8 @@ def create_tree_and_value_branch_selector_with_tree_eval_factory[StateT: TurnSta
85
86
  args: TreeAndValuePlayerArgs,
86
87
  random_generator: Random,
87
88
  master_state_evaluator: MasterStateEvaluator,
88
- state_representation_factory: RepresentationFactory[ContentRepresentation] | None,
89
+ state_representation_factory: RepresentationFactory[StateT, ContentRepresentation]
90
+ | None,
89
91
  node_tree_evaluation_factory: NodeTreeEvaluationFactory[StateT],
90
92
  queue_progress_player: Queue[IsDataclass] | None,
91
93
  ) -> TreeAndValueBranchSelector[StateT]:
@@ -89,7 +89,7 @@ class MasterStateEvaluator(Protocol):
89
89
  class NodeDirectEvaluator[StateT: State = State]:
90
90
  """
91
91
  The NodeEvaluator class is responsible for evaluating the value of nodes in a tree structure.
92
- It uses a board evaluator and a syzygy evaluator to calculate the value of the nodes.
92
+ It uses a state evaluator and a syzygy evaluator to calculate the value of the nodes.
93
93
  """
94
94
 
95
95
  master_state_evaluator: MasterStateEvaluator
@@ -21,12 +21,12 @@ from random import choice
21
21
  from typing import Any, Protocol, Self, runtime_checkable
22
22
 
23
23
  from valanga import (
24
- BoardEvaluation,
25
24
  BranchKey,
26
25
  Color,
27
26
  FloatyStateEvaluation,
28
27
  ForcedOutcome,
29
28
  OverEvent,
29
+ StateEvaluation,
30
30
  TurnState,
31
31
  )
32
32
 
@@ -140,7 +140,7 @@ class NodeMinmaxEvaluation[
140
140
  return self.value_white_minmax
141
141
 
142
142
  def set_evaluation(self, evaluation: float) -> None:
143
- """sets the evaluation from the board evaluator
143
+ """Set the evaluation from the state evaluator.
144
144
 
145
145
  Args:
146
146
  evaluation (float): The evaluation value to be set.
@@ -874,8 +874,9 @@ class NodeMinmaxEvaluation[
874
874
  best_branches.append(branch_key)
875
875
  return best_branches
876
876
 
877
- def evaluate(self) -> BoardEvaluation:
878
- """Build a BoardEvaluation from current minmax state."""
877
+ def evaluate(self) -> StateEvaluation:
878
+ """Build a StateEvaluation from current minmax state."""
879
+
879
880
  if self.over_event.is_over():
880
881
  return ForcedOutcome(
881
882
  outcome=self.over_event,
@@ -1,10 +1,10 @@
1
1
  from typing import TYPE_CHECKING, Protocol, Self
2
2
 
3
3
  from valanga import (
4
- BoardEvaluation,
5
4
  BranchKey,
6
5
  OverEvent,
7
6
  State,
7
+ StateEvaluation,
8
8
  )
9
9
 
10
10
  type BranchSortValue = tuple[float, int, int]
@@ -43,7 +43,7 @@ class NodeTreeEvaluation[StateT: State = State](Protocol):
43
43
  value_white_minmax: float | None = None
44
44
 
45
45
  def set_evaluation(self, evaluation: float) -> None:
46
- """sets the evaluation from the board evaluator
46
+ """Set the evaluation from the state evaluator.
47
47
 
48
48
  Args:
49
49
  evaluation (float): The evaluation value to be set.
@@ -90,8 +90,8 @@ class NodeTreeEvaluation[StateT: State = State](Protocol):
90
90
  """Update terminal state based on updated branches."""
91
91
  ...
92
92
 
93
- def evaluate(self) -> BoardEvaluation:
94
- """Return a board evaluation for this node."""
93
+ def evaluate(self) -> StateEvaluation:
94
+ """Return a state evaluation for this node."""
95
95
  ...
96
96
 
97
97
  def description_tree_visualizer_branch(self, child: "ITreeNode[StateT]") -> str:
@@ -37,7 +37,9 @@ class AlgorithmNodeFactory[StateT: State = State]:
37
37
  """
38
38
 
39
39
  tree_node_factory: TreeNodeFactory[AlgorithmNode[StateT], StateT]
40
- state_representation_factory: RepresentationFactory | None
40
+ state_representation_factory: (
41
+ RepresentationFactory[StateT, ContentRepresentation] | None
42
+ )
41
43
  node_tree_evaluation_factory: NodeTreeEvaluationFactory[StateT]
42
44
  exploration_index_data_create: node_indices.ExplorationIndexDataFactory[
43
45
  AlgorithmNode[StateT], StateT
@@ -57,7 +57,7 @@ class AlgorithmNode[StateT: State = State]:
57
57
  tree_node (TreeNode): The tree node that is wrapped.
58
58
  tree_evaluation (NodeTreeEvaluation): The object computing the value.
59
59
  exploration_index_data (NodeExplorationData | None): The object storing the information to help the algorithm decide the next nodes to explore.
60
- state_representation (StateRepresentation | None): The board representation.
60
+ state_representation (ContentRepresentation | None): The state representation used for evaluation.
61
61
  """
62
62
  self.tree_node = tree_node
63
63
  self.tree_evaluation = tree_evaluation
@@ -145,9 +145,9 @@ class AlgorithmNode[StateT: State = State]:
145
145
  )
146
146
 
147
147
  @property
148
- def all_branches_keys(self) -> BranchKeyGeneratorP:
148
+ def all_branches_keys(self) -> BranchKeyGeneratorP[BranchKey]:
149
149
  """
150
- Returns a generator that yields the branch keys for the current board state.
150
+ Returns a generator that yields the branch keys for the current state.
151
151
 
152
152
  Returns:
153
153
  BranchKeyGenerator: A generator that yields the branch keys.
@@ -108,7 +108,7 @@ class ITreeNode[StateT: State = State](Protocol):
108
108
  """
109
109
 
110
110
  @property
111
- def all_branches_keys(self) -> BranchKeyGeneratorP:
111
+ def all_branches_keys(self) -> BranchKeyGeneratorP[BranchKey]:
112
112
  """
113
113
  Get the available branch keys of the node.
114
114
 
@@ -152,7 +152,7 @@ class TreeNode[
152
152
  return not self.parent_nodes
153
153
 
154
154
  @property
155
- def all_branches_keys(self) -> BranchKeyGeneratorP:
155
+ def all_branches_keys(self) -> BranchKeyGeneratorP[BranchKey]:
156
156
  """
157
157
  Returns a generator that yields the branch keys for the current state.
158
158
 
@@ -16,9 +16,10 @@ Example usage:
16
16
  from dataclasses import dataclass
17
17
  from enum import Enum
18
18
  from random import Random
19
- from typing import Literal, Mapping, Protocol
19
+ from typing import Literal, Protocol
20
20
 
21
21
  from valanga import BranchKey, State
22
+ from valanga.policy import BranchPolicy
22
23
 
23
24
  from anemone.nodes.algorithm_node.algorithm_node import (
24
25
  AlgorithmNode,
@@ -26,15 +27,6 @@ from anemone.nodes.algorithm_node.algorithm_node import (
26
27
  from anemone.utils.small_tools import softmax
27
28
 
28
29
 
29
- @dataclass(frozen=True, slots=True)
30
- class BranchPolicy:
31
- """
32
- Represents a probability distribution over branches.
33
- """
34
-
35
- probs: Mapping[BranchKey, float] # should sum to ~1.0
36
-
37
-
38
30
  def sample_from_policy(policy: BranchPolicy, rng: Random) -> BranchKey:
39
31
  """Sample a branch key from a probability policy using a RNG."""
40
32
  branches = list(policy.probs.keys())
@@ -5,8 +5,9 @@ from queue import Queue
5
5
  from random import Random
6
6
 
7
7
  from valanga import TurnState
8
+ from valanga.policy import Recommendation
8
9
 
9
- from anemone.basics import BranchRecommendation, Seed
10
+ from anemone.basics import Seed
10
11
  from anemone.progress_monitor.progress_monitor import (
11
12
  AllStoppingCriterionArgs,
12
13
  )
@@ -43,14 +44,12 @@ class TreeAndValueBranchSelector[StateT: TurnState = TurnState]:
43
44
  recommend_branch_after_exploration: recommender_rule.AllRecommendFunctionsArgs
44
45
  queue_progress_player: Queue[IsDataclass] | None
45
46
 
46
- def select_branch(
47
- self, state: StateT, selection_seed: Seed
48
- ) -> BranchRecommendation:
47
+ def select_branch(self, state: StateT, selection_seed: Seed) -> Recommendation:
49
48
  """
50
49
  Selects the best branch based on the tree and value strategy.
51
50
 
52
51
  Args:
53
- - board: The current board state.
52
+ - state: The current state to explore.
54
53
  - selection_seed: The seed used for randomization during branch selection.
55
54
 
56
55
  Returns:
@@ -59,7 +58,7 @@ class TreeAndValueBranchSelector[StateT: TurnState = TurnState]:
59
58
  tree_exploration: TreeExploration = self.create_tree_exploration(state=state)
60
59
  self.random_generator.seed(selection_seed)
61
60
 
62
- branch_recommendation: BranchRecommendation = tree_exploration.explore(
61
+ branch_recommendation: Recommendation = tree_exploration.explore(
63
62
  random_generator=self.random_generator
64
63
  ).branch_recommendation
65
64
 
@@ -20,9 +20,10 @@ from queue import Queue
20
20
  from random import Random
21
21
  from typing import TYPE_CHECKING, Any, Callable
22
22
 
23
- from valanga import BoardEvaluation, BranchKey, PlayerProgressMessage, State, TurnState
23
+ from valanga import BranchKey, PlayerProgressMessage, State, StateEvaluation, TurnState
24
+ from valanga.game import BranchName
25
+ from valanga.policy import Recommendation
24
26
 
25
- from anemone.basics import BranchRecommendation
26
27
  from anemone.nodes.algorithm_node.algorithm_node import AlgorithmNode
27
28
  from anemone.progress_monitor.progress_monitor import (
28
29
  AllStoppingCriterionArgs,
@@ -39,7 +40,7 @@ from . import tree_manager as tree_man
39
40
  from .trees.factory import ValueTreeFactory
40
41
 
41
42
  if TYPE_CHECKING:
42
- from anemone.recommender_rule.recommender_rule import BranchPolicy
43
+ from valanga.policy import BranchPolicy
43
44
 
44
45
 
45
46
  @dataclass
@@ -48,21 +49,22 @@ class TreeExplorationResult[NodeT: AlgorithmNode[Any] = AlgorithmNode[Any]]:
48
49
  Tree Exploration Result holds the result of a tree exploration.
49
50
  """
50
51
 
51
- branch_recommendation: BranchRecommendation
52
+ branch_recommendation: Recommendation
52
53
  tree: trees.Tree[NodeT]
53
54
 
54
55
 
55
56
  def compute_child_evals[StateT: State](
56
57
  root: AlgorithmNode[StateT],
57
- ) -> dict[BranchKey, BoardEvaluation]:
58
+ ) -> dict[BranchName, StateEvaluation]:
58
59
  """Compute evaluations for each existing child branch."""
59
- evals: dict[BranchKey, BoardEvaluation] = {}
60
+ evals: dict[BranchName, StateEvaluation] = {}
60
61
  for bk, child in root.branches_children.items():
61
62
  if child is None:
62
63
  continue
63
64
 
64
65
  # Use whatever your canonical per-node evaluation is:
65
- evals[bk] = child.tree_evaluation.evaluate()
66
+ bk_name = root.state.branch_name_from_key(bk)
67
+ evals[bk_name] = child.tree_evaluation.evaluate()
66
68
  return evals
67
69
 
68
70
 
@@ -188,15 +190,16 @@ class TreeExploration[NodeT: AlgorithmNode[Any] = AlgorithmNode[Any]]:
188
190
  policy, random_generator
189
191
  )
190
192
 
193
+ best_branch_name = self.tree.root_node.state.branch_name_from_key(best_branch)
191
194
  self.tree_manager.print_best_line(
192
195
  tree=self.tree
193
196
  ) # todo maybe almost best chosen line no?
194
197
 
195
- branch_recommendation = BranchRecommendation(
196
- branch_key=best_branch,
198
+ branch_recommendation = Recommendation(
199
+ recommended_name=best_branch_name,
197
200
  evaluation=self.tree.root_node.tree_evaluation.evaluate(),
198
201
  policy=policy,
199
- child_evals=compute_child_evals(self.tree.root_node),
202
+ branch_evals=compute_child_evals(self.tree.root_node),
200
203
  )
201
204
 
202
205
  tree_exploration_result: TreeExplorationResult[NodeT] = TreeExplorationResult(
@@ -70,7 +70,7 @@ class TreeManager[
70
70
  Returns:
71
71
  The tree expansion object.
72
72
  """
73
- # The parent board is copied, we only copy the stack (history of previous board) if the depth is smaller than 2
73
+ # The parent state is copied; we only copy the stack (history of previous states) if the depth is smaller than 2.
74
74
  # Having the stack information allows checking for draw by repetition.
75
75
  # To limit computation we limit copying it all the time. The resulting policy will only be aware of immediate
76
76
  # risk of draw by repetition
@@ -117,7 +117,7 @@ class TreeManager[
117
117
  The tree expansion object.
118
118
  """
119
119
 
120
- # Creation of the child node. If the board already exited in another node, that node is returned as child_node.
120
+ # Creation of the child node. If the state already existed in another node, that node is returned as child_node.
121
121
  tree_depth: int = parent_node.tree_depth + 1
122
122
  state_tag: StateTag = state.tag
123
123
 
@@ -1,36 +0,0 @@
1
- """Basic types and protocols for Anemone."""
2
-
3
- from dataclasses import dataclass
4
- from typing import Annotated, Mapping, Protocol
5
-
6
- from valanga import BoardEvaluation, BranchKey, Color, HasTurn, State
7
-
8
- from anemone.recommender_rule.recommender_rule import BranchPolicy
9
-
10
- type Seed = Annotated[int, "seed"]
11
- type TreeDepth = Annotated[int, "Depth level of a node in a tree structure"]
12
-
13
-
14
- class StateWithTurn(State, HasTurn, Protocol):
15
- """A `valanga.State` that also exposes turn information."""
16
-
17
- ...
18
-
19
-
20
- @dataclass(frozen=True, slots=True)
21
- class BranchRecommendation:
22
- """A recommendation for a specific branch in a tree node."""
23
-
24
- branch_key: BranchKey
25
- evaluation: BoardEvaluation | None = None
26
- policy: BranchPolicy | None = None
27
- child_evals: Mapping[BranchKey, BoardEvaluation] | None = None
28
-
29
-
30
- class HasBlackAndWhiteTurn(Protocol):
31
- """Protocol for state that has black and white turns."""
32
-
33
- @property
34
- def turn(self) -> Color:
35
- """Return the current player's turn color."""
36
- ...