gammonview 3.2.0__tar.gz → 3.3.0__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 (302) hide show
  1. {gammonview-3.2.0 → gammonview-3.3.0}/CHANGELOG.md +18 -0
  2. {gammonview-3.2.0 → gammonview-3.3.0}/PKG-INFO +1 -1
  3. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/game_eval.py +34 -2
  4. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/luck.py +4 -0
  5. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/match.py +4 -1
  6. gammonview-3.3.0/gvformat-js/test/fixtures/ogxm2/annos-docs.json +1 -0
  7. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/annos-sha256.json +4 -4
  8. gammonview-3.3.0/gvformat-js/test/fixtures/ogxm2/blocks-docs.json +1 -0
  9. gammonview-3.3.0/gvformat-js/test/fixtures/ogxm2/blocks-sha256.json +42 -0
  10. gammonview-3.3.0/gvformat-js/test/fixtures/ogxm2/blocks.expected.json +1 -0
  11. gammonview-3.3.0/gvformat-js/test/fixtures/ogxm2/blocks.ogxm +0 -0
  12. gammonview-3.3.0/tests/golden/B4_SrGcsKAQmoTyHlgJCbM.fast.gva +1 -0
  13. gammonview-3.3.0/tests/golden/B4_SrGcsKAQmoTyHlgJCbM.fast.gvab +0 -0
  14. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/PROVENANCE.json +1 -1
  15. {gammonview-3.2.0 → gammonview-3.3.0}/tests/ogxm2_blocks_cases.py +31 -0
  16. gammonview-3.3.0/tests/test_money_rules.py +157 -0
  17. gammonview-3.2.0/gvformat-js/test/fixtures/ogxm2/annos-docs.json +0 -1
  18. gammonview-3.2.0/gvformat-js/test/fixtures/ogxm2/blocks-docs.json +0 -1
  19. gammonview-3.2.0/gvformat-js/test/fixtures/ogxm2/blocks-sha256.json +0 -42
  20. gammonview-3.2.0/gvformat-js/test/fixtures/ogxm2/blocks.expected.json +0 -1
  21. gammonview-3.2.0/gvformat-js/test/fixtures/ogxm2/blocks.ogxm +0 -0
  22. gammonview-3.2.0/tests/golden/B4_SrGcsKAQmoTyHlgJCbM.fast.gva +0 -1
  23. gammonview-3.2.0/tests/golden/B4_SrGcsKAQmoTyHlgJCbM.fast.gvab +0 -0
  24. {gammonview-3.2.0 → gammonview-3.3.0}/.gitattributes +0 -0
  25. {gammonview-3.2.0 → gammonview-3.3.0}/.github/workflows/ci.yml +0 -0
  26. {gammonview-3.2.0 → gammonview-3.3.0}/.github/workflows/engine.yml +0 -0
  27. {gammonview-3.2.0 → gammonview-3.3.0}/.github/workflows/publish.yml +0 -0
  28. {gammonview-3.2.0 → gammonview-3.3.0}/.gitignore +0 -0
  29. {gammonview-3.2.0 → gammonview-3.3.0}/.python-version +0 -0
  30. {gammonview-3.2.0 → gammonview-3.3.0}/CLAUDE.md +0 -0
  31. {gammonview-3.2.0 → gammonview-3.3.0}/CONTRIBUTING.md +0 -0
  32. {gammonview-3.2.0 → gammonview-3.3.0}/LICENSE +0 -0
  33. {gammonview-3.2.0 → gammonview-3.3.0}/README.md +0 -0
  34. {gammonview-3.2.0 → gammonview-3.3.0}/THIRD-PARTY-NOTICES.md +0 -0
  35. {gammonview-3.2.0 → gammonview-3.3.0}/assets/logo.png +0 -0
  36. {gammonview-3.2.0 → gammonview-3.3.0}/docs/CLI.md +0 -0
  37. {gammonview-3.2.0 → gammonview-3.3.0}/docs/METHODOLOGY.md +0 -0
  38. {gammonview-3.2.0 → gammonview-3.3.0}/docs/OGXM_COMPUTED_FIELDS.md +0 -0
  39. {gammonview-3.2.0 → gammonview-3.3.0}/docs/OGXM_JSON_SPEC_GAMMONVIEW.md +0 -0
  40. {gammonview-3.2.0 → gammonview-3.3.0}/docs/OGXM_V2_PROFILE.md +0 -0
  41. {gammonview-3.2.0 → gammonview-3.3.0}/docs/PRESET_ACCURACY.md +0 -0
  42. {gammonview-3.2.0 → gammonview-3.3.0}/docs/upstream-bgsage.md +0 -0
  43. {gammonview-3.2.0 → gammonview-3.3.0}/docs/v1/OGXM_FORMAT_SPEC_GAMMONVIEW.md +0 -0
  44. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/2026-09-16-checker-mid-tier.md +0 -0
  45. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/2026-09-17-checker-mid-tier-followup.md +0 -0
  46. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/2026-09-19-cross-machine-costs.md +0 -0
  47. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/2026-09-20-corpus-rerun.md +0 -0
  48. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/2026-10-21-wc2-corpus.md +0 -0
  49. {gammonview-3.2.0 → gammonview-3.3.0}/experiments/bench.py +0 -0
  50. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/__init__.py +0 -0
  51. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/batch.py +0 -0
  52. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/checker_eval.py +0 -0
  53. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/compare_gva.py +0 -0
  54. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/loader.py +0 -0
  55. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/ogxm_reconstructor.py +0 -0
  56. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/parentwatch.py +0 -0
  57. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/position.py +0 -0
  58. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/presets.py +0 -0
  59. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/progress.py +0 -0
  60. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/reconstruct_mat.py +0 -0
  61. {gammonview-3.2.0 → gammonview-3.3.0}/gvanalysis/share.py +0 -0
  62. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/__init__.py +0 -0
  63. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/basefill.py +0 -0
  64. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/bgf.py +0 -0
  65. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/binary.py +0 -0
  66. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/export.py +0 -0
  67. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/game_reconstructor.py +0 -0
  68. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/legality.py +0 -0
  69. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/mat.py +0 -0
  70. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/mat_parser.py +0 -0
  71. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/merge.py +0 -0
  72. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/met.py +0 -0
  73. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/notation.py +0 -0
  74. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/ogid.py +0 -0
  75. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/ogxm2.py +0 -0
  76. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/ogxm2_passthrough.py +0 -0
  77. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/ogxm2_writer.py +0 -0
  78. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/place.py +0 -0
  79. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/reader.py +0 -0
  80. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/share.py +0 -0
  81. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/stats.py +0 -0
  82. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat/xg.py +0 -0
  83. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/.gitignore +0 -0
  84. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/LICENSE +0 -0
  85. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/README.md +0 -0
  86. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/THIRD-PARTY-NOTICES.md +0 -0
  87. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/cli/README.md +0 -0
  88. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/cli/bgf2gva.js +0 -0
  89. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/cli/mat2gva.js +0 -0
  90. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/cli/xg2gva.js +0 -0
  91. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/package-lock.json +0 -0
  92. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/package.json +0 -0
  93. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/basefill.js +0 -0
  94. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/bgf2gva.js +0 -0
  95. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/binary.js +0 -0
  96. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/constants.js +0 -0
  97. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/export.js +0 -0
  98. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/index.js +0 -0
  99. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/legality.js +0 -0
  100. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/mat2gva.js +0 -0
  101. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/merge.js +0 -0
  102. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/met.js +0 -0
  103. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/notation.js +0 -0
  104. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/og2gva.js +0 -0
  105. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/ogid.js +0 -0
  106. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/ogxm2.js +0 -0
  107. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/ogxm2_passthrough.js +0 -0
  108. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/ogxm2_writer.js +0 -0
  109. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/place.js +0 -0
  110. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/reader.js +0 -0
  111. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/sha256.js +0 -0
  112. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/share.js +0 -0
  113. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/stats.js +0 -0
  114. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/src/xg2gva.js +0 -0
  115. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/3WNK_g1Z-PLsh_HyvQ5j4a.json +0 -0
  116. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/5nqfGw9bWG3deTaU.json +0 -0
  117. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/B4_SrGcsKAQmoTyHlgJCbM.json +0 -0
  118. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/C07OQCKyw4Pe-CnjFiAMYO.json +0 -0
  119. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/MYdvw1qGuyaRUH__.json +0 -0
  120. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/Sz-2PgKnvb6aFls69-qFXg.json +0 -0
  121. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/UL-CV6F9jMM-E1Pu.json +0 -0
  122. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/XCu3RJ0UvDg_Tldl.json +0 -0
  123. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/baR-U643iUDpvzTC.json +0 -0
  124. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/eXBNG5wZHS5Alu3P.json +0 -0
  125. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/hQ8sVn2LbTdF4wRm.json +0 -0
  126. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/rK7pXm4TqLb9NzWd.json +0 -0
  127. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/mat/uwvEbd63UvdX7SDin5o_Iw.json +0 -0
  128. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/annos-edits-sha256.json +0 -0
  129. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/annos.expected.json +0 -0
  130. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/annos.ogxm +0 -0
  131. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/bgf-writer-sha256.json +0 -0
  132. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/cube-on-two.expected.json +0 -0
  133. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/cube-on-two.ogxm +0 -0
  134. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/fields-docs.json +0 -0
  135. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/fields-sha256.json +0 -0
  136. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/fields.expected.json +0 -0
  137. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/fields.ogxm +0 -0
  138. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/foreign.ogxm +0 -0
  139. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/gen.py +0 -0
  140. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/match.expected.json +0 -0
  141. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/match.ogxm +0 -0
  142. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/passthrough-sha256.json +0 -0
  143. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/resign.expected.json +0 -0
  144. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/resign.ogxm +0 -0
  145. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/set-up.expected.json +0 -0
  146. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/set-up.ogxm +0 -0
  147. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/two-blocks.expected.json +0 -0
  148. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/two-blocks.ogxm +0 -0
  149. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/v1-chunks.gvab +0 -0
  150. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/fixtures/ogxm2/writer-sha256.json +0 -0
  151. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-alternative-move-steps.js +0 -0
  152. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-basefill.js +0 -0
  153. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-bgf-alternatives.js +0 -0
  154. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-bgf-embedded-cube.js +0 -0
  155. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-bgf-move-steps.js +0 -0
  156. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-chunk-passthrough.js +0 -0
  157. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-equity-loss.js +0 -0
  158. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-illegal-move.js +0 -0
  159. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-illegal-play-steps.js +0 -0
  160. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-legality.js +0 -0
  161. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-mat.js +0 -0
  162. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-merge.js +0 -0
  163. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-met.js +0 -0
  164. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-og.js +0 -0
  165. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogid.js +0 -0
  166. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-annos.js +0 -0
  167. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-blocks.js +0 -0
  168. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-fields.js +0 -0
  169. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-limits.js +0 -0
  170. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-passthrough.js +0 -0
  171. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2-writer.js +0 -0
  172. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-ogxm2.js +0 -0
  173. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-place.js +0 -0
  174. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-robustness.js +0 -0
  175. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-roundtrip.js +0 -0
  176. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-share.js +0 -0
  177. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-stats.js +0 -0
  178. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-xg-cube.js +0 -0
  179. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-xg-eval-levels.js +0 -0
  180. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-xg-move-steps.js +0 -0
  181. {gammonview-3.2.0 → gammonview-3.3.0}/gvformat-js/test/test-xg-zero-win-eval.js +0 -0
  182. {gammonview-3.2.0 → gammonview-3.3.0}/pyproject.toml +0 -0
  183. {gammonview-3.2.0 → gammonview-3.3.0}/samples/README.md +0 -0
  184. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/3WNK_g1Z-PLsh_HyvQ5j4a.bgf +0 -0
  185. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/5nqfGw9bWG3deTaU.bgf +0 -0
  186. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/B4_SrGcsKAQmoTyHlgJCbM.bgf +0 -0
  187. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/C07OQCKyw4Pe-CnjFiAMYO.bgf +0 -0
  188. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/MYdvw1qGuyaRUH__.bgf +0 -0
  189. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/Sz-2PgKnvb6aFls69-qFXg.bgf +0 -0
  190. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/UL-CV6F9jMM-E1Pu.bgf +0 -0
  191. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/XCu3RJ0UvDg_Tldl.bgf +0 -0
  192. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/baR-U643iUDpvzTC.bgf +0 -0
  193. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/eXBNG5wZHS5Alu3P.bgf +0 -0
  194. {gammonview-3.2.0 → gammonview-3.3.0}/samples/bgf/uwvEbd63UvdX7SDin5o_Iw.bgf +0 -0
  195. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/3WNK_g1Z-PLsh_HyvQ5j4a.gvab +0 -0
  196. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/5nqfGw9bWG3deTaU.gvab +0 -0
  197. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/B4_SrGcsKAQmoTyHlgJCbM.gva +0 -0
  198. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/B4_SrGcsKAQmoTyHlgJCbM.gvab +0 -0
  199. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/C07OQCKyw4Pe-CnjFiAMYO.gvab +0 -0
  200. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/MYdvw1qGuyaRUH__.gvab +0 -0
  201. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/Sz-2PgKnvb6aFls69-qFXg.gvab +0 -0
  202. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/UL-CV6F9jMM-E1Pu.gvab +0 -0
  203. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/XCu3RJ0UvDg_Tldl.gvab +0 -0
  204. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/baR-U643iUDpvzTC.gvab +0 -0
  205. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/eXBNG5wZHS5Alu3P.gvab +0 -0
  206. {gammonview-3.2.0 → gammonview-3.3.0}/samples/gv/uwvEbd63UvdX7SDin5o_Iw.gvab +0 -0
  207. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/3WNK_g1Z-PLsh_HyvQ5j4a.mat +0 -0
  208. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/5nqfGw9bWG3deTaU.mat +0 -0
  209. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/B4_SrGcsKAQmoTyHlgJCbM.mat +0 -0
  210. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/C07OQCKyw4Pe-CnjFiAMYO.mat +0 -0
  211. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/MYdvw1qGuyaRUH__.mat +0 -0
  212. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/Sz-2PgKnvb6aFls69-qFXg.mat +0 -0
  213. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/UL-CV6F9jMM-E1Pu.mat +0 -0
  214. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/XCu3RJ0UvDg_Tldl.mat +0 -0
  215. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/baR-U643iUDpvzTC.mat +0 -0
  216. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/eXBNG5wZHS5Alu3P.mat +0 -0
  217. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/hQ8sVn2LbTdF4wRm.mat +0 -0
  218. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/rK7pXm4TqLb9NzWd.mat +0 -0
  219. {gammonview-3.2.0 → gammonview-3.3.0}/samples/mat/uwvEbd63UvdX7SDin5o_Iw.mat +0 -0
  220. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/3WNK_g1Z-PLsh_HyvQ5j4a.xg +0 -0
  221. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/5nqfGw9bWG3deTaU.xg +0 -0
  222. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/B4_SrGcsKAQmoTyHlgJCbM.xg +0 -0
  223. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/C07OQCKyw4Pe-CnjFiAMYO.xg +0 -0
  224. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/MYdvw1qGuyaRUH__.xg +0 -0
  225. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/Sz-2PgKnvb6aFls69-qFXg.xg +0 -0
  226. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/UL-CV6F9jMM-E1Pu.xg +0 -0
  227. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/XCu3RJ0UvDg_Tldl.xg +0 -0
  228. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/baR-U643iUDpvzTC.xg +0 -0
  229. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/eXBNG5wZHS5Alu3P.xg +0 -0
  230. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/hQ8sVn2LbTdF4wRm.xg +0 -0
  231. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/rK7pXm4TqLb9NzWd.xg +0 -0
  232. {gammonview-3.2.0 → gammonview-3.3.0}/samples/xg/uwvEbd63UvdX7SDin5o_Iw.xg +0 -0
  233. {gammonview-3.2.0 → gammonview-3.3.0}/tests/audit_corpus.py +0 -0
  234. {gammonview-3.2.0 → gammonview-3.3.0}/tests/fixtures.py +0 -0
  235. {gammonview-3.2.0 → gammonview-3.3.0}/tests/gen_js_v2_fixtures.py +0 -0
  236. {gammonview-3.2.0 → gammonview-3.3.0}/tests/gen_ogxm2_annos_fixtures.py +0 -0
  237. {gammonview-3.2.0 → gammonview-3.3.0}/tests/gen_ogxm2_blocks_fixtures.py +0 -0
  238. {gammonview-3.2.0 → gammonview-3.3.0}/tests/gen_ogxm2_fields_fixtures.py +0 -0
  239. {gammonview-3.2.0 → gammonview-3.3.0}/tests/gen_ogxm2_passthrough_fixtures.py +0 -0
  240. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/3WNK_g1Z-PLsh_HyvQ5j4a.fast.gva +0 -0
  241. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/3WNK_g1Z-PLsh_HyvQ5j4a.fast.gvab +0 -0
  242. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/5nqfGw9bWG3deTaU.fast.gva +0 -0
  243. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/5nqfGw9bWG3deTaU.fast.gvab +0 -0
  244. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/MYdvw1qGuyaRUH__.fast.gva +0 -0
  245. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/MYdvw1qGuyaRUH__.fast.gvab +0 -0
  246. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/baR-U643iUDpvzTC.fast.gva +0 -0
  247. {gammonview-3.2.0 → gammonview-3.3.0}/tests/golden/baR-U643iUDpvzTC.fast.gvab +0 -0
  248. {gammonview-3.2.0 → gammonview-3.3.0}/tests/ogxm2_annos_cases.py +0 -0
  249. {gammonview-3.2.0 → gammonview-3.3.0}/tests/ogxm2_fields_cases.py +0 -0
  250. {gammonview-3.2.0 → gammonview-3.3.0}/tests/ogxm2_oracle.py +0 -0
  251. {gammonview-3.2.0 → gammonview-3.3.0}/tests/passthrough_cases.py +0 -0
  252. {gammonview-3.2.0 → gammonview-3.3.0}/tests/regen_golden.py +0 -0
  253. {gammonview-3.2.0 → gammonview-3.3.0}/tests/run_all.py +0 -0
  254. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_alternative_move_steps.py +0 -0
  255. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_analysis_orientation.py +0 -0
  256. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_analyze_position.py +0 -0
  257. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_basefill.py +0 -0
  258. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_bgf_alternatives.py +0 -0
  259. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_bgf_cube_response.py +0 -0
  260. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_bgf_move_steps.py +0 -0
  261. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_chunk_passthrough.py +0 -0
  262. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_count_illegal.py +0 -0
  263. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_cube_tiers.py +0 -0
  264. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_docs_presets.py +0 -0
  265. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_equity_loss.py +0 -0
  266. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_gvab_writer.py +0 -0
  267. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_illegal_move.py +0 -0
  268. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_illegal_play_steps.py +0 -0
  269. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_legality.py +0 -0
  270. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_loader_formats.py +0 -0
  271. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_luck_fill.py +0 -0
  272. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_merge_resign.py +0 -0
  273. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_met.py +0 -0
  274. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2.py +0 -0
  275. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_annos.py +0 -0
  276. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_blocks.py +0 -0
  277. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_blocks_analysis.py +0 -0
  278. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_fields.py +0 -0
  279. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_fields_analysis.py +0 -0
  280. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_limits.py +0 -0
  281. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_passthrough.py +0 -0
  282. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_reference.py +0 -0
  283. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm2_writer.py +0 -0
  284. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm_conformance.py +0 -0
  285. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm_export.py +0 -0
  286. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm_pipeline.py +0 -0
  287. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_ogxm_stats.py +0 -0
  288. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_parent_watch.py +0 -0
  289. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_position_id.py +0 -0
  290. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_presets.py +0 -0
  291. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_read_gvab.py +0 -0
  292. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_reconstruct_mat.py +0 -0
  293. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_resign_actor.py +0 -0
  294. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_resign_errors.py +0 -0
  295. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_restated_play_analysis.py +0 -0
  296. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_screened_checker.py +0 -0
  297. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_share_link.py +0 -0
  298. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_xg_cube.py +0 -0
  299. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_xg_eval_levels.py +0 -0
  300. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_xg_move_steps.py +0 -0
  301. {gammonview-3.2.0 → gammonview-3.3.0}/tests/test_xg_zero_win_eval.py +0 -0
  302. {gammonview-3.2.0 → gammonview-3.3.0}/uv.lock +0 -0
@@ -13,6 +13,24 @@ when the repository was opened; they are kept because they record why things
13
13
  are the way they are — particularly the breaking changes and the measurements
14
14
  behind several design decisions. Dates are the tag dates.
15
15
 
16
+ ## 3.3.0 — 2026-11-05
17
+
18
+ **A money session is analysed under the rules it was played under** *(fixed)*
19
+
20
+ `analyze_file` read a session's Jacoby and beaver rules and wrote them into the
21
+ summary, but passed neither to the engine, so every money session was judged
22
+ under bgsage's defaults, both on, whatever the file said. A session played
23
+ without Jacoby had its gammons counted with the cube centred, which moves cube
24
+ verdicts, checker equities, error sizes and PR across the whole session; one
25
+ played without beavers had a wrong double answered with a beaver. Every engine
26
+ call a decision makes now gets the session's rules, and so does `fill_luck`.
27
+ Match play is unaffected: it has neither rule.
28
+
29
+ Behaviour change: a money session whose file says Jacoby or beavers are off is
30
+ now analysed that way. The money golden, a session with neither, is
31
+ regenerated; its first game no longer has a missed double, which the v2 format
32
+ cases now write in rather than find.
33
+
16
34
  ## 3.2.0 — 2026-11-04
17
35
 
18
36
  **`analyze_position` takes the money rules: Jacoby and beavers** *(added)*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: gammonview
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: Backgammon match analysis — the pure-Python OGXM/GVA codec (`gvformat`) plus bgsage-powered match and position analysis (`gvanalysis`).
5
5
  Project-URL: Homepage, https://github.com/gammonview/gammonview-analysis
6
6
  Project-URL: Repository, https://github.com/gammonview/gammonview-analysis
@@ -140,6 +140,8 @@ def _compute_luck(
140
140
  verbose: bool = False,
141
141
  postroll_eq: float | None = None,
142
142
  hint_eq: float | None = None,
143
+ jacoby: bool = True,
144
+ beaver: bool = True,
143
145
  ) -> tuple[float, float] | tuple[None, None]:
144
146
  """Return (luck, preroll_equity).
145
147
 
@@ -170,6 +172,9 @@ def _compute_luck(
170
172
  roll, given I am the one on roll", which silently discards the roll-off that
171
173
  decided *who* is on roll. Positive luck means the actual dice were above
172
174
  average for the mover.
175
+
176
+ `jacoby` and `beaver` are the session's money rules, as for every other
177
+ engine call in a match; bgsage ignores them at a match score.
173
178
  """
174
179
  if list(board) == list(STARTING_BOARD):
175
180
  preroll = _opening_baseline(away1, away2, cube_value, is_crawford)
@@ -179,6 +184,7 @@ def _compute_luck(
179
184
  board, die1, die2,
180
185
  cube_value=cube_value, cube_owner=cube_owner,
181
186
  away1=away1, away2=away2, is_crawford=is_crawford,
187
+ jacoby=jacoby, beaver=beaver,
182
188
  )
183
189
  moves = list(result.moves)
184
190
  postroll_eq = float(moves[0].equity) if moves else 0.0
@@ -197,6 +203,7 @@ def _compute_luck(
197
203
  board, d1, d2,
198
204
  cube_value=cube_value, cube_owner=cube_owner,
199
205
  away1=away1, away2=away2, is_crawford=is_crawford,
206
+ jacoby=jacoby, beaver=beaver,
200
207
  )
201
208
  moves = list(result.moves)
202
209
  except Exception as e:
@@ -273,6 +280,18 @@ class _EvalCtx:
273
280
  # pass's 2T.
274
281
  analyzer_cube: "BgBotAnalyzer | None" = None
275
282
  level_display_cube: str | None = None
283
+ # The session's money rules. Defaulted to bgsage's own, both on, but a
284
+ # match passes what its file states: until 3.3.0 nothing did, and every
285
+ # money session was judged under Jacoby and beavers whatever it was played
286
+ # under.
287
+ jacoby: bool = True
288
+ beaver: bool = True
289
+
290
+ def rules(self, dec: dict) -> dict:
291
+ """The money rules for one decision's engine calls, as keywords.
292
+ Match play has neither, as `checker_eval.checker_play` also says."""
293
+ money = not dec["away1"] and not dec["away2"]
294
+ return {"jacoby": self.jacoby and money, "beaver": self.beaver and money}
276
295
 
277
296
  @property
278
297
  def cube_analyzer(self) -> "BgBotAnalyzer":
@@ -397,6 +416,7 @@ def _eval_cube_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
397
416
  away1=dec["away1"],
398
417
  away2=dec["away2"],
399
418
  is_crawford=dec["is_crawford"],
419
+ **ctx.rules(dec),
400
420
  )
401
421
 
402
422
  top = ctx.cube_analyzer
@@ -693,14 +713,15 @@ def _eval_resign_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
693
713
  analyzer, dec["board"], dice[0], dice[1],
694
714
  cube_value=dec["cube_value"], cube_owner=dec["cube_owner"],
695
715
  away1=dec["away1"], away2=dec["away2"], is_crawford=dec["is_crawford"],
696
- seed=seen[-1] if seen else None)
716
+ seed=seen[-1] if seen else None, **ctx.rules(dec))
697
717
  seen.append(r)
698
718
  best = list(r.moves)[0]
699
719
  e_roll, level, probs = float(best.equity), best.eval_level, best.probs
700
720
  else:
701
721
  r = analyzer.cube_action(
702
722
  dec["board"], cube_value=dec["cube_value"], cube_owner=dec["cube_owner"],
703
- away1=dec["away1"], away2=dec["away2"], is_crawford=dec["is_crawford"])
723
+ away1=dec["away1"], away2=dec["away2"], is_crawford=dec["is_crawford"],
724
+ **ctx.rules(dec))
704
725
  nd = float(r.equity_nd)
705
726
  e_roll = max(nd, min(float(r.equity_dt), float(r.equity_dp))) if can_double else nd
706
727
  level, probs = r.eval_level, r.probs
@@ -811,6 +832,7 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
811
832
  away1=dec["away1"],
812
833
  away2=dec["away2"],
813
834
  is_crawford=dec["is_crawford"],
835
+ **ctx.rules(dec),
814
836
  )
815
837
  forced_moves = list(forced_result.moves)
816
838
  if forced_moves:
@@ -849,6 +871,7 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
849
871
  away2=dec["away2"],
850
872
  is_crawford=dec["is_crawford"],
851
873
  force_boards=[dec["board_played"]],
874
+ **ctx.rules(dec),
852
875
  )
853
876
  cheap_moves = list(cheap_result.moves)
854
877
  if len(cheap_moves) >= 2:
@@ -887,6 +910,7 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
887
910
  force_boards=[dec["board_played"]],
888
911
  seed=seed,
889
912
  seed_window=window,
913
+ **ctx.rules(dec),
890
914
  )
891
915
 
892
916
  def played_error(move_list) -> float | None:
@@ -999,6 +1023,8 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
999
1023
  away1=dec["away1"],
1000
1024
  away2=dec["away2"],
1001
1025
  is_crawford=dec["is_crawford"],
1026
+ # bgsage takes no beaver rule here.
1027
+ jacoby=ctx.rules(dec)["jacoby"],
1002
1028
  )
1003
1029
  played_eq = post.cubeful_equity
1004
1030
  checker_err = max(0.0, best_eq - played_eq)
@@ -1028,6 +1054,8 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
1028
1054
  away1=dec["away1"],
1029
1055
  away2=dec["away2"],
1030
1056
  is_crawford=dec["is_crawford"],
1057
+ # bgsage takes no beaver rule here.
1058
+ jacoby=ctx.rules(dec)["jacoby"],
1031
1059
  )
1032
1060
  played_eq = float(post.cubeful_equity)
1033
1061
  checker_err = max(0.0, best_eq - played_eq)
@@ -1138,6 +1166,7 @@ def _eval_checker_decision(dec: dict, ctx: _EvalCtx) -> _DecResult:
1138
1166
  dec["cube_value"], dec["cube_owner"],
1139
1167
  dec["away1"], dec["away2"], dec["is_crawford"],
1140
1168
  _luck_az, verbose=ctx.verbose,
1169
+ **ctx.rules(dec),
1141
1170
  postroll_eq=None, # use the 1-ply (luck-level) post-roll, not the preset best_eq,
1142
1171
  hint_eq=_hint, # so luck is preset-independent (hint_eq still guards sign errors)
1143
1172
  )
@@ -1255,6 +1284,7 @@ def evaluate_game(game: dict, analyzer: BgBotAnalyzer, recon: dict,
1255
1284
  level: str = "3ply", level_cube: str | None = None,
1256
1285
  all_moves: bool = False,
1257
1286
  count_illegal: bool = False,
1287
+ jacoby: bool = True, beaver: bool = True,
1258
1288
  progress: "Callable[[], None] | None" = None) -> dict:
1259
1289
  """Evaluate all decisions in one game. Returns per-player error/decision counts and move log.
1260
1290
 
@@ -1262,6 +1292,7 @@ def evaluate_game(game: dict, analyzer: BgBotAnalyzer, recon: dict,
1262
1292
  entry) supplying the decisions and game result; `game` carries only the
1263
1293
  per-game metadata (number, starting scores) used for reporting.
1264
1294
  `progress`, if given, is called once per decision processed (for a bar).
1295
+ `jacoby` and `beaver` are the session's money rules (`_EvalCtx.rules`).
1265
1296
  """
1266
1297
  level_display = _LEVEL_DISPLAY.get(level, level)
1267
1298
  decisions = recon["decisions"]
@@ -1281,6 +1312,7 @@ def evaluate_game(game: dict, analyzer: BgBotAnalyzer, recon: dict,
1281
1312
  analyzer_cube=analyzer_cube,
1282
1313
  level_display_cube=(None if level_cube is None
1283
1314
  else _LEVEL_DISPLAY.get(level_cube, level_cube)),
1315
+ jacoby=jacoby, beaver=beaver,
1284
1316
  )
1285
1317
 
1286
1318
  results: "list[_DecResult]" = []
@@ -101,6 +101,8 @@ def fill_luck(ogxm: dict, *, analyzer=None, on_progress=None, verbose: bool = Fa
101
101
  from bgsage import BgBotAnalyzer
102
102
  analyzer = BgBotAnalyzer(eval_level=LUCK_LEVEL, cubeful=True)
103
103
 
104
+ jacoby = bool(ogxm.get("jacoby"))
105
+ beaver = bool(ogxm.get("beaver"))
104
106
  filled = 0
105
107
  for done, (ply, wanting) in enumerate(todo, start=1):
106
108
  try:
@@ -121,6 +123,8 @@ def fill_luck(ogxm: dict, *, analyzer=None, on_progress=None, verbose: bool = Fa
121
123
  state.cube_value, cube_owner,
122
124
  state.away1, state.away2, state.crawford,
123
125
  analyzer, verbose=verbose, hint_eq=hint,
126
+ # An OGID carries no money rules; the match states them.
127
+ jacoby=jacoby, beaver=beaver,
124
128
  )
125
129
  if luck is not None:
126
130
  for analysis in wanting:
@@ -221,7 +221,7 @@ _WORKER: dict = {}
221
221
 
222
222
  def _worker_init(base_level, base_level_cube, mid_level_checker, mid_level_cube, level,
223
223
  level_cube, thresholds, resign_errors, all_moves, count_illegal,
224
- level_display, engine_threads, verbose) -> None:
224
+ level_display, engine_threads, verbose, rules) -> None:
225
225
  # First, before any weights are loaded: from here on this process holds
226
226
  # hundreds of megabytes, and if the parent dies hard nothing else will ever
227
227
  # tell it to let go. See `parentwatch`.
@@ -260,6 +260,7 @@ def _worker_init(base_level, base_level_cube, mid_level_checker, mid_level_cube,
260
260
  level_display=level_display,
261
261
  level_display_cube=(None if level_cube is None
262
262
  else _LEVEL_DISPLAY.get(level_cube, level_cube)),
263
+ jacoby=rules[0], beaver=rules[1],
263
264
  )
264
265
 
265
266
 
@@ -606,6 +607,7 @@ def analyze_ogxm(
606
607
  level=level, level_cube=level_cube,
607
608
  all_moves=all_moves,
608
609
  count_illegal=count_illegal,
610
+ jacoby=jacoby_rule, beaver=beaver_rule,
609
611
  progress=advance)
610
612
  game_results.append(r)
611
613
  if not quiet:
@@ -625,6 +627,7 @@ def analyze_ogxm(
625
627
  base_level_r, base_level_cube, mid_level_checker, mid_level_cube, level,
626
628
  level_cube, (close_checker, close_cube, err_checker, err_cube), p.resign_errors, all_moves,
627
629
  count_illegal, _LEVEL_DISPLAY.get(level, level), worker_threads, verbose,
630
+ (jacoby_rule, beaver_rule),
628
631
  )
629
632
  buckets: "list[list[tuple[int, object]]]" = [[] for _ in recons]
630
633
  with ProcessPoolExecutor(max_workers=n_jobs, initializer=_worker_init,