socha 2.2.1__tar.gz → 2.2.2__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 (67) hide show
  1. {socha-2.2.1 → socha-2.2.2}/Cargo.lock +25 -25
  2. {socha-2.2.1 → socha-2.2.2}/Cargo.toml +1 -1
  3. {socha-2.2.1 → socha-2.2.2}/PKG-INFO +6 -2
  4. {socha-2.2.1 → socha-2.2.2}/README.md +5 -1
  5. {socha-2.2.1 → socha-2.2.2}/pyproject.toml +1 -1
  6. {socha-2.2.1 → socha-2.2.2}/python/socha/_socha.pyi +62 -9
  7. {socha-2.2.1 → socha-2.2.2}/python/socha/api/networking/game_client.py +28 -25
  8. {socha-2.2.1 → socha-2.2.2}/python/socha/api/networking/utils.py +24 -41
  9. {socha-2.2.1 → socha-2.2.2}/python/socha/utils/package_builder.py +1 -0
  10. {socha-2.2.1 → socha-2.2.2}/src/plugin/board.rs +74 -78
  11. socha-2.2.2/src/plugin/game_state.rs +751 -0
  12. socha-2.2.2/src/plugin/test/game_state.rs +393 -0
  13. socha-2.2.2/src/plugin/test.rs +1 -0
  14. {socha-2.2.1 → socha-2.2.2}/src/plugin.rs +1 -0
  15. socha-2.2.1/src/plugin/game_state.rs +0 -1166
  16. {socha-2.2.1 → socha-2.2.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  17. {socha-2.2.1 → socha-2.2.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  18. {socha-2.2.1 → socha-2.2.2}/.github/dependabot.yml +0 -0
  19. {socha-2.2.1 → socha-2.2.2}/.github/pull_request_template.md +0 -0
  20. {socha-2.2.1 → socha-2.2.2}/.github/workflows/cd.yml +0 -0
  21. {socha-2.2.1 → socha-2.2.2}/.github/workflows/ci.yaml +0 -0
  22. {socha-2.2.1 → socha-2.2.2}/.github/workflows/convert.yml +0 -0
  23. {socha-2.2.1 → socha-2.2.2}/.gitignore +0 -0
  24. {socha-2.2.1 → socha-2.2.2}/.readthedocs.yaml +0 -0
  25. {socha-2.2.1 → socha-2.2.2}/CODE_OF_CONDUCT.md +0 -0
  26. {socha-2.2.1 → socha-2.2.2}/CONTRIBUTING.md +0 -0
  27. {socha-2.2.1 → socha-2.2.2}/LICENSE +0 -0
  28. {socha-2.2.1 → socha-2.2.2}/docs/Makefile +0 -0
  29. {socha-2.2.1 → socha-2.2.2}/docs/appending +0 -0
  30. {socha-2.2.1 → socha-2.2.2}/docs/conf.py +0 -0
  31. {socha-2.2.1 → socha-2.2.2}/docs/index.rst +0 -0
  32. {socha-2.2.1 → socha-2.2.2}/docs/make.bat +0 -0
  33. {socha-2.2.1 → socha-2.2.2}/docs/modules.rst +0 -0
  34. {socha-2.2.1 → socha-2.2.2}/docs/requirements.txt +0 -0
  35. {socha-2.2.1 → socha-2.2.2}/python/socha/__init__.py +0 -0
  36. {socha-2.2.1 → socha-2.2.2}/python/socha/api/__init__.py +0 -0
  37. {socha-2.2.1 → socha-2.2.2}/python/socha/api/networking/__init__.py +0 -0
  38. {socha-2.2.1 → socha-2.2.2}/python/socha/api/networking/network_socket.py +0 -0
  39. {socha-2.2.1 → socha-2.2.2}/python/socha/api/networking/xml_protocol_interface.py +0 -0
  40. {socha-2.2.1 → socha-2.2.2}/python/socha/api/protocol/__init__.py +0 -0
  41. {socha-2.2.1 → socha-2.2.2}/python/socha/api/protocol/protocol.py +0 -0
  42. {socha-2.2.1 → socha-2.2.2}/python/socha/api/protocol/protocol_packet.py +0 -0
  43. {socha-2.2.1 → socha-2.2.2}/python/socha/api/protocol/room_message.py +0 -0
  44. {socha-2.2.1 → socha-2.2.2}/python/socha/py.typed +0 -0
  45. {socha-2.2.1 → socha-2.2.2}/python/socha/starter.py +0 -0
  46. {socha-2.2.1 → socha-2.2.2}/requirements.txt +0 -0
  47. {socha-2.2.1 → socha-2.2.2}/src/lib.rs +0 -0
  48. {socha-2.2.1 → socha-2.2.2}/src/plugin/actions/accelerate.rs +0 -0
  49. {socha-2.2.1 → socha-2.2.2}/src/plugin/actions/advance.rs +0 -0
  50. {socha-2.2.1 → socha-2.2.2}/src/plugin/actions/push.rs +0 -0
  51. {socha-2.2.1 → socha-2.2.2}/src/plugin/actions/turn.rs +0 -0
  52. {socha-2.2.1 → socha-2.2.2}/src/plugin/actions.rs +0 -0
  53. {socha-2.2.1 → socha-2.2.2}/src/plugin/constants.rs +0 -0
  54. {socha-2.2.1 → socha-2.2.2}/src/plugin/coordinate.rs +0 -0
  55. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/acceleration_errors.rs +0 -0
  56. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/advance_errors.rs +0 -0
  57. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/invalid_move_exception.rs +0 -0
  58. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/movement_error.rs +0 -0
  59. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/push_error.rs +0 -0
  60. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors/turn_error.rs +0 -0
  61. {socha-2.2.1 → socha-2.2.2}/src/plugin/errors.rs +0 -0
  62. {socha-2.2.1 → socha-2.2.2}/src/plugin/field.rs +0 -0
  63. {socha-2.2.1 → socha-2.2.2}/src/plugin/move.rs +0 -0
  64. {socha-2.2.1 → socha-2.2.2}/src/plugin/segment.rs +0 -0
  65. {socha-2.2.1 → socha-2.2.2}/src/plugin/ship.rs +0 -0
  66. {socha-2.2.1 → socha-2.2.2}/start.sh +0 -0
  67. {socha-2.2.1 → socha-2.2.2}/tests/test_network.py +0 -0
@@ -4,7 +4,7 @@ version = 3
4
4
 
5
5
  [[package]]
6
6
  name = "_socha"
7
- version = "2.2.1"
7
+ version = "2.2.2"
8
8
  dependencies = [
9
9
  "libm",
10
10
  "libmath",
@@ -27,15 +27,15 @@ dependencies = [
27
27
 
28
28
  [[package]]
29
29
  name = "arc-swap"
30
- version = "1.7.0"
30
+ version = "1.7.1"
31
31
  source = "registry+https://github.com/rust-lang/crates.io-index"
32
- checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f"
32
+ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
33
33
 
34
34
  [[package]]
35
35
  name = "autocfg"
36
- version = "1.1.0"
36
+ version = "1.2.0"
37
37
  source = "registry+https://github.com/rust-lang/crates.io-index"
38
- checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
38
+ checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
39
39
 
40
40
  [[package]]
41
41
  name = "bitflags"
@@ -63,9 +63,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
63
63
 
64
64
  [[package]]
65
65
  name = "indoc"
66
- version = "2.0.4"
66
+ version = "2.0.5"
67
67
  source = "registry+https://github.com/rust-lang/crates.io-index"
68
- checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
68
+ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
69
69
 
70
70
  [[package]]
71
71
  name = "libc"
@@ -106,15 +106,15 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
106
106
 
107
107
  [[package]]
108
108
  name = "memchr"
109
- version = "2.7.1"
109
+ version = "2.7.2"
110
110
  source = "registry+https://github.com/rust-lang/crates.io-index"
111
- checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
111
+ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
112
112
 
113
113
  [[package]]
114
114
  name = "memoffset"
115
- version = "0.9.0"
115
+ version = "0.9.1"
116
116
  source = "registry+https://github.com/rust-lang/crates.io-index"
117
- checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
117
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
118
118
  dependencies = [
119
119
  "autocfg",
120
120
  ]
@@ -156,9 +156,9 @@ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
156
156
 
157
157
  [[package]]
158
158
  name = "proc-macro2"
159
- version = "1.0.79"
159
+ version = "1.0.81"
160
160
  source = "registry+https://github.com/rust-lang/crates.io-index"
161
- checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
161
+ checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
162
162
  dependencies = [
163
163
  "unicode-ident",
164
164
  ]
@@ -221,7 +221,7 @@ dependencies = [
221
221
  "proc-macro2",
222
222
  "pyo3-macros-backend",
223
223
  "quote",
224
- "syn 2.0.53",
224
+ "syn 2.0.59",
225
225
  ]
226
226
 
227
227
  [[package]]
@@ -234,14 +234,14 @@ dependencies = [
234
234
  "proc-macro2",
235
235
  "pyo3-build-config",
236
236
  "quote",
237
- "syn 2.0.53",
237
+ "syn 2.0.59",
238
238
  ]
239
239
 
240
240
  [[package]]
241
241
  name = "quote"
242
- version = "1.0.35"
242
+ version = "1.0.36"
243
243
  source = "registry+https://github.com/rust-lang/crates.io-index"
244
- checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
244
+ checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
245
245
  dependencies = [
246
246
  "proc-macro2",
247
247
  ]
@@ -304,9 +304,9 @@ dependencies = [
304
304
 
305
305
  [[package]]
306
306
  name = "regex"
307
- version = "1.10.3"
307
+ version = "1.10.4"
308
308
  source = "registry+https://github.com/rust-lang/crates.io-index"
309
- checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
309
+ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
310
310
  dependencies = [
311
311
  "aho-corasick",
312
312
  "memchr",
@@ -327,9 +327,9 @@ dependencies = [
327
327
 
328
328
  [[package]]
329
329
  name = "regex-syntax"
330
- version = "0.8.2"
330
+ version = "0.8.3"
331
331
  source = "registry+https://github.com/rust-lang/crates.io-index"
332
- checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
332
+ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
333
333
 
334
334
  [[package]]
335
335
  name = "scopeguard"
@@ -356,9 +356,9 @@ dependencies = [
356
356
 
357
357
  [[package]]
358
358
  name = "syn"
359
- version = "2.0.53"
359
+ version = "2.0.59"
360
360
  source = "registry+https://github.com/rust-lang/crates.io-index"
361
- checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
361
+ checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a"
362
362
  dependencies = [
363
363
  "proc-macro2",
364
364
  "quote",
@@ -464,9 +464,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
464
464
 
465
465
  [[package]]
466
466
  name = "xml-rs"
467
- version = "0.8.19"
467
+ version = "0.8.20"
468
468
  source = "registry+https://github.com/rust-lang/crates.io-index"
469
- checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a"
469
+ checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193"
470
470
 
471
471
  [[package]]
472
472
  name = "yaserde"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "_socha"
3
- version = "2.2.1"
3
+ version = "2.2.2"
4
4
  edition = "2021"
5
5
 
6
6
  [lib]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: socha
3
- Version: 2.2.1
3
+ Version: 2.2.2
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Operating System :: MacOS
6
6
  Classifier: Operating System :: Microsoft :: Windows
@@ -200,6 +200,10 @@ you can of course pass start arguments.
200
200
 
201
201
  ## Preparing Your Player for the Competition
202
202
 
203
+ > Please note that the competition system runs on a Linux system with an `x86_64` architecture.
204
+ > To use your client on the competition system, you will need to download the socha package
205
+ > built for the `manylinux2014_x86_64` platform and the Python version `310`.
206
+
203
207
  To ensure that your player is usable for the competition system,
204
208
  you need to download all the dependencies that your client uses
205
209
  because the system will run on a docker container without access to the internet and sudo permission.
@@ -217,7 +221,7 @@ If you want to do it manually, follow the steps below to download the dependenci
217
221
  1. Open your terminal or console wherever you want to create your directory that you will upload.
218
222
  2. Type `mkdir my_player` to create a new directory named `my_player`. You can name yours whatever you want.
219
223
  3. Enter the directory using `cd my_player`.
220
- 4. Run the command: `pip download socha xsdata==22.7 -d dependencies` in the directory.
224
+ 4. Run the command: `pip download socha --only-binary=:all: --platform manylinux2014_x86_64 --python-version 310 -d dependencies` in the directory.
221
225
  This command downloads the dependencies you need into the folder `dependencies`.
222
226
  5. Ensure to add all your dependencies that your client uses.
223
227
  6. After the download, create a last directory using `mkdir .pip_cache`.
@@ -176,6 +176,10 @@ you can of course pass start arguments.
176
176
 
177
177
  ## Preparing Your Player for the Competition
178
178
 
179
+ > Please note that the competition system runs on a Linux system with an `x86_64` architecture.
180
+ > To use your client on the competition system, you will need to download the socha package
181
+ > built for the `manylinux2014_x86_64` platform and the Python version `310`.
182
+
179
183
  To ensure that your player is usable for the competition system,
180
184
  you need to download all the dependencies that your client uses
181
185
  because the system will run on a docker container without access to the internet and sudo permission.
@@ -193,7 +197,7 @@ If you want to do it manually, follow the steps below to download the dependenci
193
197
  1. Open your terminal or console wherever you want to create your directory that you will upload.
194
198
  2. Type `mkdir my_player` to create a new directory named `my_player`. You can name yours whatever you want.
195
199
  3. Enter the directory using `cd my_player`.
196
- 4. Run the command: `pip download socha xsdata==22.7 -d dependencies` in the directory.
200
+ 4. Run the command: `pip download socha --only-binary=:all: --platform manylinux2014_x86_64 --python-version 310 -d dependencies` in the directory.
197
201
  This command downloads the dependencies you need into the folder `dependencies`.
198
202
  5. Ensure to add all your dependencies that your client uses.
199
203
  6. After the download, create a last directory using `mkdir .pip_cache`.
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "socha"
7
- version = "2.2.1"
7
+ version = "2.2.2"
8
8
  authors = [{ name = "maxblan", email = "stu222782@mail.uni-kiel.de" }]
9
9
  description = "This is the package for the Software-Challenge Germany 2024. This Season the game will be 'Mississippi Queen'."
10
10
  readme = "README.md"
@@ -1,5 +1,6 @@
1
1
  from typing import Any, List, Optional, Set, Tuple
2
2
 
3
+
3
4
  class PluginConstants:
4
5
  ROUND_LIMIT: int
5
6
  START_COAL: int
@@ -19,6 +20,7 @@ class PluginConstants:
19
20
  MAX_ISLANDS: int
20
21
  MIN_ISLANDS: int
21
22
 
23
+
22
24
  class CartesianCoordinate:
23
25
  x: int
24
26
  y: int
@@ -28,6 +30,7 @@ class CartesianCoordinate:
28
30
  def to_index(self) -> Optional[int]: ...
29
31
  def from_index(index: int) -> CartesianCoordinate: ...
30
32
 
33
+
31
34
  class CubeCoordinates:
32
35
  q: int
33
36
  r: int
@@ -46,6 +49,7 @@ class CubeCoordinates:
46
49
  def distance_to(self, other: CubeCoordinates) -> int: ...
47
50
  def turn_count_to(self, target: CubeDirection) -> int: ...
48
51
 
52
+
49
53
  class CubeDirection:
50
54
  Right: int
51
55
  DownRight: int
@@ -62,15 +66,19 @@ class CubeDirection:
62
66
  def rotated_by(self, turns: int) -> CubeDirection: ...
63
67
  def ordinal(self) -> int: ...
64
68
 
69
+
65
70
  class Move:
66
71
  actions: List[Accelerate | Advance | Push | Turn]
67
72
 
68
- def __init__(self, actions: List[Accelerate | Advance | Push | Turn]) -> None: ...
73
+ def __init__(self, actions: List[Accelerate |
74
+ Advance | Push | Turn]) -> None: ...
75
+
69
76
 
70
77
  class TeamEnum:
71
78
  One: int
72
79
  Two: int
73
80
 
81
+
74
82
  class Ship:
75
83
  team: TeamEnum
76
84
  position: CubeCoordinates
@@ -99,9 +107,12 @@ class Ship:
99
107
  def accelerate_by(self, diff: int) -> None: ...
100
108
  def read_resolve(self) -> None: ...
101
109
  def resolve_direction(self, reverse: bool) -> None: ...
102
- def update_position(self, distance: int, advance_info: AdvanceInfo) -> None: ...
110
+ def update_position(self, distance: int,
111
+ advance_info: AdvanceInfo) -> None: ...
112
+
103
113
  def __str__(self) -> str: ...
104
114
 
115
+
105
116
  class AccelerationProblem:
106
117
  ZeroAcc: Any
107
118
  AboveMaxSpeed: Any
@@ -111,6 +122,7 @@ class AccelerationProblem:
111
122
 
112
123
  def message(self) -> str: ...
113
124
 
125
+
114
126
  class Accelerate:
115
127
  acc: int
116
128
 
@@ -118,6 +130,7 @@ class Accelerate:
118
130
  def perform(self, state: Any) -> Ship | BaseException: ...
119
131
  def __str__(self) -> str: ...
120
132
 
133
+
121
134
  class AdvanceProblem:
122
135
  MovementPointsMissing: Any
123
136
  InsufficientPush: Any
@@ -128,12 +141,14 @@ class AdvanceProblem:
128
141
 
129
142
  def message(self) -> str: ...
130
143
 
144
+
131
145
  class Advance:
132
146
  distance: int
133
147
 
134
148
  def __init__(self, distance: int) -> None: ...
135
149
  def perform(self, state: GameState) -> Ship | BaseException: ...
136
150
 
151
+
137
152
  class PushProblem:
138
153
  MovementPointsMissing: Any
139
154
  SameFieldPush: Any
@@ -144,11 +159,14 @@ class PushProblem:
144
159
 
145
160
  def message(self) -> str: ...
146
161
 
162
+
147
163
  class Push:
148
164
  direction: CubeDirection
149
165
 
150
166
  def __init__(self, direction: CubeDirection) -> None: ...
151
- def perform(self, state: GameState) -> Tuple[Ship, Ship] | BaseException: ...
167
+ def perform(self, state: GameState) -> Tuple[Ship,
168
+ Ship] | BaseException: ...
169
+
152
170
 
153
171
  class TurnProblem:
154
172
  RotationOnSandbankNotAllowed: Any
@@ -157,6 +175,7 @@ class TurnProblem:
157
175
 
158
176
  def message(self) -> str: ...
159
177
 
178
+
160
179
  class Turn:
161
180
  direction: CubeDirection
162
181
 
@@ -164,10 +183,14 @@ class Turn:
164
183
  def perform(self, state: GameState) -> Ship | BaseException: ...
165
184
  def coal_cost(self, ship: Ship) -> int: ...
166
185
 
186
+
167
187
  class Passenger:
168
188
  direction: CubeDirection
169
189
  passenger: int
170
190
 
191
+ def __init__(direction: CubeDirection, passenger: int) -> None: ...
192
+
193
+
171
194
  class FieldType:
172
195
  Water: 0
173
196
  Island: 1
@@ -175,14 +198,18 @@ class FieldType:
175
198
  Goal: 3
176
199
  Sandbank: 4
177
200
 
201
+
178
202
  class Field:
179
203
  field_type: FieldType
180
204
  passenger: Optional[Passenger]
181
205
 
182
- def __init__(field_type: FieldType, passenger: Optional[Passenger]) -> None: ...
206
+ def __init__(field_type: FieldType,
207
+ passenger: Optional[Passenger]) -> None: ...
208
+
183
209
  def is_empty(self: Field) -> bool: ...
184
210
  def is_field_type(self: Field, field_type: FieldType) -> bool: ...
185
211
 
212
+
186
213
  class Segment:
187
214
  direction: CubeDirection
188
215
  center: CubeCoordinates
@@ -197,12 +224,17 @@ class Segment:
197
224
  def tip(self) -> CubeCoordinates: ...
198
225
  def get(self, coordinates: CubeCoordinates) -> Optional[Field]: ...
199
226
  def set(self, coordinates: CubeCoordinates, field: Field) -> None: ...
200
- def local_to_global(self, coordinates: CubeCoordinates) -> CubeCoordinates: ...
201
- def global_to_local(self, coordinates: CubeCoordinates) -> CubeCoordinates: ...
227
+
228
+ def local_to_global(
229
+ self, coordinates: CubeCoordinates) -> CubeCoordinates: ...
230
+ def global_to_local(
231
+ self, coordinates: CubeCoordinates) -> CubeCoordinates: ...
232
+
202
233
  def contains(self, coordinates: CubeCoordinates) -> bool: ...
203
234
  def array_coords(self, coords: CubeCoordinates) -> CartesianCoordinate: ...
204
235
  def cube_coords(self, coords: CartesianCoordinate) -> CubeCoordinates: ...
205
236
 
237
+
206
238
  class Board:
207
239
  segments: List[Segment]
208
240
  next_direction: CubeDirection
@@ -211,29 +243,39 @@ class Board:
211
243
  self, segments: List[Segment], next_direction: CubeDirection
212
244
  ) -> None: ...
213
245
  def get_segment(self, index: int) -> Optional[Segment]: ...
246
+
214
247
  def segment_with_index_at(
215
248
  self, coords: CubeCoordinates
216
249
  ) -> Optional[tuple[int, Segment]]: ...
217
250
  def get(self, coords: CubeCoordinates) -> Optional[Field]: ...
218
251
  def does_field_have_stream(self, coords: CubeCoordinates) -> bool: ...
252
+
219
253
  def get_field_in_direction(
220
254
  self, direction: CubeDirection, coords: CubeCoordinates
221
255
  ) -> Optional[Field]: ...
256
+
222
257
  def set_field_in_direction(
223
258
  self, direction: CubeDirection, coords: CubeCoordinates, field: Field
224
259
  ) -> None: ...
260
+
225
261
  def get_coordinate_by_index(
226
262
  self, segment_index: int, x_index: int, y_index: int
227
263
  ) -> CubeCoordinates: ...
264
+
228
265
  def segment_distance(
229
266
  self, coordinate1: CubeCoordinates, coordinate2: CubeCoordinates
230
267
  ) -> int: ...
231
268
  def segment_index(self, coordinate: CubeCoordinates) -> Optional[int]: ...
232
- def find_segment(self, coordinate: CubeCoordinates) -> Optional[Segment]: ...
233
- def neighboring_fields(self, coords: CubeCoordinates) -> List[Optional[Field]]: ...
269
+
270
+ def find_segment(
271
+ self, coordinate: CubeCoordinates) -> Optional[Segment]: ...
272
+ def neighboring_fields(
273
+ self, coords: CubeCoordinates) -> List[Optional[Field]]: ...
274
+
234
275
  def effective_speed(self, ship: Ship) -> int: ...
235
276
  def is_sandbank(self, coords: CubeCoordinates) -> bool: ...
236
277
  def pickup_passenger(self, state: GameState) -> GameState: ...
278
+
237
279
  def pickup_passenger_at_position(self, pos: CubeCoordinates) -> Optional[Field]:
238
280
  """
239
281
  Picks up a passenger at the specified position using the CubeCoordinates.
@@ -272,12 +314,16 @@ class Board:
272
314
  board.find_nearest_field_types(CubeCoordinates(0, 0), FieldType.Water)
273
315
  ```
274
316
  """
317
+
318
+ def pretty_print(self) -> None: ...
319
+
275
320
 
276
321
  class TeamPoints:
277
322
  ship_points: int
278
323
  coal_points: int
279
324
  finish_points: int
280
325
 
326
+
281
327
  class AdvanceInfo:
282
328
  costs: int
283
329
  problem: AdvanceProblem
@@ -286,6 +332,7 @@ class AdvanceInfo:
286
332
  def advances(self, distance: Optional[int]) -> List[Advance]: ...
287
333
  def distance(self) -> int: ...
288
334
 
335
+
289
336
  class GameState:
290
337
  board: Board
291
338
  turn: int
@@ -304,6 +351,7 @@ class GameState:
304
351
  def determine_ahead_team(self) -> Ship: ...
305
352
  def calculate_points(self, ship: Ship) -> int: ...
306
353
  def is_current_ship_on_current(self) -> bool: ...
354
+
307
355
  def perform_action(
308
356
  self, action: Accelerate | Advance | Push | Turn
309
357
  ) -> GameState: ...
@@ -318,6 +366,7 @@ class GameState:
318
366
  def ship_points(self, ship: Ship) -> int: ...
319
367
  def must_push(self) -> bool: ...
320
368
  def check_ship_advance_limit(self, ship: Ship) -> AdvanceInfo: ...
369
+
321
370
  def calculate_advance_info(
322
371
  self, start: CubeCoordinates, direction: CubeDirection, max_movement_points: int
323
372
  ) -> AdvanceInfo: ...
@@ -327,6 +376,7 @@ class GameState:
327
376
  def possible_advances(self) -> List[Advance]: ...
328
377
  def sandbank_advances_for(self, ship: Ship) -> Optional[List[Advance]]: ...
329
378
  def possible_moves(self) -> List[Move]: ...
379
+
330
380
  def possible_action_comb(
331
381
  self,
332
382
  current_state: GameState,
@@ -334,10 +384,13 @@ class GameState:
334
384
  depth: int,
335
385
  max_depth: int,
336
386
  ) -> List[List[Accelerate | Advance | Push | Turn]]: ...
387
+
337
388
  def possible_actions(
338
389
  self, rank: int
339
390
  ) -> List[Accelerate | Advance | Push | Turn]: ...
340
- def coal_for_action(self, action: Accelerate | Advance | Push | Turn) -> int: ...
391
+ def coal_for_action(self, action: Accelerate |
392
+ Advance | Push | Turn) -> int: ...
393
+
341
394
  def can_move(self) -> bool: ...
342
395
  def is_over(self) -> bool: ...
343
396
  def is_winner(self, ship: Ship) -> bool: ...
@@ -12,8 +12,7 @@ from typing import List, Union
12
12
  from socha._socha import GameState, Move
13
13
  from socha.api.networking.utils import (
14
14
  handle_move,
15
- if_last_game_state,
16
- if_not_last_game_state,
15
+ message_to_state,
17
16
  )
18
17
  from socha.api.networking.xml_protocol_interface import XMLProtocolInterface
19
18
  from socha.api.protocol.protocol import (
@@ -190,7 +189,8 @@ class GameClient(XMLProtocolInterface):
190
189
  logging.info(
191
190
  f"Creating game with {player_1}, {player_2} and game type '{game_type}'"
192
191
  )
193
- self.send(Prepare(game_type=game_type, pause=pause, slot=[player_1, player_2]))
192
+ self.send(Prepare(game_type=game_type,
193
+ pause=pause, slot=[player_1, player_2]))
194
194
 
195
195
  def observe(self, room_id: str):
196
196
  logging.info(f"Observing game room '{room_id}'")
@@ -224,10 +224,12 @@ class GameClient(XMLProtocolInterface):
224
224
  """
225
225
 
226
226
  if isinstance(message, Joined):
227
- logging.log(15, f"Game joined received with room id '{message.room_id}'")
227
+ logging.log(
228
+ 15, f"Game joined received with room id '{message.room_id}'")
228
229
  self._game_handler.on_game_joined(room_id=message.room_id)
229
230
  elif isinstance(message, Left):
230
- logging.log(15, f"Game left received with room id '{message.room_id}'")
231
+ logging.log(
232
+ 15, f"Game left received with room id '{message.room_id}'")
231
233
  self._game_handler.on_game_left()
232
234
  elif isinstance(message, Prepared):
233
235
  logging.log(
@@ -239,8 +241,10 @@ class GameClient(XMLProtocolInterface):
239
241
  reservations=message.reservation,
240
242
  )
241
243
  elif isinstance(message, Observed):
242
- logging.log(15, f"Game observing received with room id '{message.room_id}'")
243
- self._game_handler.on_observed(game_client=self, room_id=message.room_id)
244
+ logging.log(
245
+ 15, f"Game observing received with room id '{message.room_id}'")
246
+ self._game_handler.on_observed(
247
+ game_client=self, room_id=message.room_id)
244
248
  elif isinstance(message, Room) and not self.headless:
245
249
  room_id = message.room_id
246
250
 
@@ -251,17 +255,20 @@ class GameClient(XMLProtocolInterface):
251
255
  self._game_handler.on_error(str(message))
252
256
  self.stop()
253
257
  elif isinstance(message.data.class_binding, MoveRequest):
254
- logging.log(15, f"Move request received for room id '{room_id}'")
258
+ logging.log(
259
+ 15, f"Move request received for room id '{room_id}'")
255
260
  self._on_move_request(room_id)
256
261
  elif isinstance(message.data.class_binding, State):
257
262
  logging.log(15, f"State received for room id '{room_id}'")
258
263
  self._on_state(message)
259
264
  elif isinstance(message.data.class_binding, Result):
260
265
  logging.log(15, f"Result received for room id '{room_id}'")
261
- self._game_handler.history[-1].append(message.data.class_binding)
266
+ self._game_handler.history[-1].append(
267
+ message.data.class_binding)
262
268
  self._game_handler.on_game_over(message.data.class_binding)
263
269
  else:
264
- logging.log(15, f"Room message received for room id '{room_id}'")
270
+ logging.log(
271
+ 15, f"Room message received for room id '{room_id}'")
265
272
  self._game_handler.on_room_message(message.data.class_binding)
266
273
  else:
267
274
  room_id = message.room_id
@@ -281,17 +288,9 @@ class GameClient(XMLProtocolInterface):
281
288
  logging.error(f"{move_response} is not a valid move.")
282
289
 
283
290
  def _on_state(self, message):
284
- last_game_state = None
285
- for item in self._game_handler.history[-1][::-1]:
286
- if isinstance(item, GameState):
287
- last_game_state = item
288
- break
289
- if last_game_state:
290
- _game_state = if_last_game_state(message, last_game_state)
291
- else:
292
- _game_state = if_not_last_game_state(message)
293
- self._game_handler.history[-1].append(_game_state)
294
- self._game_handler.on_update(_game_state)
291
+ _state = message_to_state(message)
292
+ self._game_handler.history[-1].append(_state)
293
+ self._game_handler.on_update(_state)
295
294
 
296
295
  def start(self):
297
296
  """
@@ -329,9 +328,11 @@ class GameClient(XMLProtocolInterface):
329
328
  )
330
329
  self._game_handler.while_disconnected(player_client=self)
331
330
  if self.auto_reconnect:
332
- logging.info("The server left. Client tries to reconnect to the server.")
331
+ logging.info(
332
+ "The server left. Client tries to reconnect to the server.")
333
333
  for _ in range(3):
334
- logging.info("Try to establish a connection with the server...")
334
+ logging.info(
335
+ "Try to establish a connection with the server...")
335
336
  try:
336
337
  self.connect()
337
338
  if self.network_interface.connected:
@@ -375,8 +376,10 @@ class GameClient(XMLProtocolInterface):
375
376
  while_waiting.start()
376
377
  gc.collect()
377
378
  elif self.running:
378
- logging.error(f"Received a object of unknown class: {response}")
379
- raise NotImplementedError("Received object of unknown class.")
379
+ logging.error(
380
+ f"Received a object of unknown class: {response}")
381
+ raise NotImplementedError(
382
+ "Received object of unknown class.")
380
383
  else:
381
384
  self._game_handler.while_disconnected(player_client=self)
382
385