continual-foragax 0.32.0__tar.gz → 0.33.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 (144) hide show
  1. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/PKG-INFO +1 -6
  2. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/pyproject.toml +3 -3
  3. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/continual_foragax.egg-info/PKG-INFO +1 -6
  4. continual_foragax-0.33.0/src/continual_foragax.egg-info/requires.txt +4 -0
  5. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/env.py +62 -31
  6. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/tests/test_foragax.py +140 -39
  7. continual_foragax-0.32.0/src/continual_foragax.egg-info/requires.txt +0 -10
  8. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/README.md +0 -0
  9. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/setup.cfg +0 -0
  10. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/continual_foragax.egg-info/SOURCES.txt +0 -0
  11. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/continual_foragax.egg-info/dependency_links.txt +0 -0
  12. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/continual_foragax.egg-info/entry_points.txt +0 -0
  13. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/continual_foragax.egg-info/top_level.txt +0 -0
  14. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/__init__.py +0 -0
  15. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/colors.py +0 -0
  16. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100897.txt +0 -0
  17. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100928.txt +0 -0
  18. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100929.txt +0 -0
  19. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100930.txt +0 -0
  20. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID100931.txt +0 -0
  21. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106714.txt +0 -0
  22. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106715.txt +0 -0
  23. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106716.txt +0 -0
  24. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106717.txt +0 -0
  25. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106718.txt +0 -0
  26. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106930.txt +0 -0
  27. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106931.txt +0 -0
  28. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106932.txt +0 -0
  29. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106933.txt +0 -0
  30. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106934.txt +0 -0
  31. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106935.txt +0 -0
  32. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106936.txt +0 -0
  33. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106937.txt +0 -0
  34. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106938.txt +0 -0
  35. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106939.txt +0 -0
  36. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106940.txt +0 -0
  37. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106941.txt +0 -0
  38. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106942.txt +0 -0
  39. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106943.txt +0 -0
  40. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106994.txt +0 -0
  41. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106995.txt +0 -0
  42. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106996.txt +0 -0
  43. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106997.txt +0 -0
  44. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106998.txt +0 -0
  45. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID106999.txt +0 -0
  46. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107000.txt +0 -0
  47. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107001.txt +0 -0
  48. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107002.txt +0 -0
  49. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107003.txt +0 -0
  50. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107004.txt +0 -0
  51. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107005.txt +0 -0
  52. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107006.txt +0 -0
  53. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107007.txt +0 -0
  54. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107008.txt +0 -0
  55. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107009.txt +0 -0
  56. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107010.txt +0 -0
  57. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107011.txt +0 -0
  58. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107012.txt +0 -0
  59. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107013.txt +0 -0
  60. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107014.txt +0 -0
  61. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107015.txt +0 -0
  62. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107016.txt +0 -0
  63. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107017.txt +0 -0
  64. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107018.txt +0 -0
  65. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107019.txt +0 -0
  66. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107020.txt +0 -0
  67. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107021.txt +0 -0
  68. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107022.txt +0 -0
  69. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107023.txt +0 -0
  70. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107024.txt +0 -0
  71. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107025.txt +0 -0
  72. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107026.txt +0 -0
  73. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107027.txt +0 -0
  74. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107028.txt +0 -0
  75. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107029.txt +0 -0
  76. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107030.txt +0 -0
  77. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107031.txt +0 -0
  78. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107032.txt +0 -0
  79. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107033.txt +0 -0
  80. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107034.txt +0 -0
  81. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107035.txt +0 -0
  82. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107036.txt +0 -0
  83. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107037.txt +0 -0
  84. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107038.txt +0 -0
  85. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107039.txt +0 -0
  86. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107040.txt +0 -0
  87. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107041.txt +0 -0
  88. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107042.txt +0 -0
  89. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107043.txt +0 -0
  90. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107044.txt +0 -0
  91. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107045.txt +0 -0
  92. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107046.txt +0 -0
  93. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107047.txt +0 -0
  94. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107048.txt +0 -0
  95. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107049.txt +0 -0
  96. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107050.txt +0 -0
  97. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107051.txt +0 -0
  98. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107052.txt +0 -0
  99. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107053.txt +0 -0
  100. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107054.txt +0 -0
  101. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107055.txt +0 -0
  102. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107056.txt +0 -0
  103. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107057.txt +0 -0
  104. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107058.txt +0 -0
  105. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107059.txt +0 -0
  106. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107060.txt +0 -0
  107. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107061.txt +0 -0
  108. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107062.txt +0 -0
  109. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107063.txt +0 -0
  110. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107064.txt +0 -0
  111. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107065.txt +0 -0
  112. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107066.txt +0 -0
  113. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107067.txt +0 -0
  114. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107068.txt +0 -0
  115. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107069.txt +0 -0
  116. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107070.txt +0 -0
  117. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID107071.txt +0 -0
  118. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID115808.txt +0 -0
  119. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID115812.txt +0 -0
  120. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID146811.txt +0 -0
  121. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156831.txt +0 -0
  122. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156835.txt +0 -0
  123. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156839.txt +0 -0
  124. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156843.txt +0 -0
  125. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156847.txt +0 -0
  126. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156851.txt +0 -0
  127. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156855.txt +0 -0
  128. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156859.txt +0 -0
  129. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156863.txt +0 -0
  130. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156867.txt +0 -0
  131. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156871.txt +0 -0
  132. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156875.txt +0 -0
  133. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156879.txt +0 -0
  134. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156883.txt +0 -0
  135. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/TG_SOUID156887.txt +0 -0
  136. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/elements.txt +0 -0
  137. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/metadata.txt +0 -0
  138. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/data/ECA_non-blended_custom/sources.txt +0 -0
  139. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/objects.py +0 -0
  140. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/registry.py +0 -0
  141. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/rendering.py +0 -0
  142. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/src/foragax/weather.py +0 -0
  143. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/tests/test_benchmark.py +0 -0
  144. {continual_foragax-0.32.0 → continual_foragax-0.33.0}/tests/test_registry.py +0 -0
@@ -1,17 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continual-foragax
3
- Version: 0.32.0
3
+ Version: 0.33.0
4
4
  Summary: A continual reinforcement learning benchmark
5
5
  Author-email: Steven Tang <stang5@ualberta.ca>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: gymnax
9
9
  Requires-Dist: six; python_version < "3.10"
10
- Provides-Extra: dev
11
- Requires-Dist: pre-commit; extra == "dev"
12
- Requires-Dist: pytest; extra == "dev"
13
- Requires-Dist: pytest-benchmark; extra == "dev"
14
- Requires-Dist: ruff; extra == "dev"
15
10
 
16
11
  # foragax
17
12
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "continual-foragax"
3
- version = "0.32.0"
3
+ version = "0.33.0"
4
4
  description = "A continual reinforcement learning benchmark"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -12,7 +12,7 @@ dependencies = [
12
12
  "six; python_version < '3.10'",
13
13
  ]
14
14
 
15
- [project.optional-dependencies]
15
+ [dependency-groups]
16
16
  dev = [
17
17
  "pre-commit",
18
18
  "pytest",
@@ -30,7 +30,7 @@ build-backend = "setuptools.build_meta"
30
30
  [tool]
31
31
  [tool.commitizen]
32
32
  name = "cz_conventional_commits"
33
- version = "0.32.0"
33
+ version = "0.33.0"
34
34
  tag_format = "$version"
35
35
  version_files = ["pyproject.toml"]
36
36
 
@@ -1,17 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: continual-foragax
3
- Version: 0.32.0
3
+ Version: 0.33.0
4
4
  Summary: A continual reinforcement learning benchmark
5
5
  Author-email: Steven Tang <stang5@ualberta.ca>
6
6
  Requires-Python: >=3.8
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: gymnax
9
9
  Requires-Dist: six; python_version < "3.10"
10
- Provides-Extra: dev
11
- Requires-Dist: pre-commit; extra == "dev"
12
- Requires-Dist: pytest; extra == "dev"
13
- Requires-Dist: pytest-benchmark; extra == "dev"
14
- Requires-Dist: ruff; extra == "dev"
15
10
 
16
11
  # foragax
17
12
 
@@ -0,0 +1,4 @@
1
+ gymnax
2
+
3
+ [:python_version < "3.10"]
4
+ six
@@ -506,17 +506,6 @@ class ForagaxEnv(environment.Environment):
506
506
  lambda: object_state,
507
507
  )
508
508
 
509
- # Clear color grid when object is collected
510
- object_state = jax.lax.cond(
511
- should_collect_now,
512
- lambda: object_state.replace(
513
- color=object_state.color.at[pos[1], pos[0]].set(
514
- jnp.full((3,), 255, dtype=jnp.uint8)
515
- )
516
- ),
517
- lambda: object_state,
518
- )
519
-
520
509
  # 3.5. HANDLE OBJECT EXPIRY
521
510
  # Only process expiry if there are objects that can expire
522
511
  key, object_state = self.expire_objects(key, state, object_state)
@@ -564,6 +553,23 @@ class ForagaxEnv(environment.Environment):
564
553
  info["biome_id"] = object_state.biome_id[pos[1], pos[0]]
565
554
  info["object_collected_id"] = jax.lax.select(should_collect, obj_at_pos, -1)
566
555
 
556
+ # Compute reward at each grid position
557
+ fixed_key = jax.random.key(0) # Fixed key for deterministic reward computation
558
+
559
+ def compute_reward(obj_id, params):
560
+ return jax.lax.cond(
561
+ obj_id > 0,
562
+ lambda: jax.lax.switch(
563
+ obj_id, self.reward_fns, state.time, fixed_key, params
564
+ ),
565
+ lambda: 0.0,
566
+ )
567
+
568
+ reward_grid = jax.vmap(jax.vmap(compute_reward))(
569
+ object_state.object_id, object_state.state_params
570
+ )
571
+ info["rewards"] = reward_grid
572
+
567
573
  # 4. UPDATE STATE
568
574
  state = EnvState(
569
575
  pos=pos,
@@ -648,12 +654,6 @@ class ForagaxEnv(environment.Environment):
648
654
  rand_key,
649
655
  )
650
656
 
651
- # Clear color grid when object expires
652
- empty_color = jnp.full((3,), 255, dtype=jnp.uint8)
653
- new_obj_state = new_obj_state.replace(
654
- color=new_obj_state.color.at[y, x].set(empty_color)
655
- )
656
-
657
657
  return new_obj_state
658
658
 
659
659
  def no_op():
@@ -1114,8 +1114,16 @@ class ForagaxEnv(environment.Environment):
1114
1114
  y_out = (y_coords < 0) | (y_coords >= self.size[1])
1115
1115
  x_out = (x_coords < 0) | (x_coords >= self.size[0])
1116
1116
  out_of_bounds = y_out | x_out
1117
- padding_index = self.object_ids[-1]
1118
- aperture = jnp.where(out_of_bounds, padding_index, values)
1117
+
1118
+ # Handle both object_id grids (2D) and color grids (3D)
1119
+ if len(values.shape) == 3:
1120
+ # Color grid: use PADDING color (0, 0, 0)
1121
+ padding_value = jnp.array([0, 0, 0], dtype=values.dtype)
1122
+ aperture = jnp.where(out_of_bounds[..., None], padding_value, values)
1123
+ else:
1124
+ # Object ID grid: use PADDING index
1125
+ padding_index = self.object_ids[-1]
1126
+ aperture = jnp.where(out_of_bounds, padding_index, values)
1119
1127
  else:
1120
1128
  aperture = values
1121
1129
 
@@ -1124,12 +1132,14 @@ class ForagaxEnv(environment.Environment):
1124
1132
  def get_obs(self, state: EnvState, params: EnvParams, key=None) -> jax.Array:
1125
1133
  """Get observation based on observation_type and full_world."""
1126
1134
  obs_grid = state.object_state.object_id
1135
+ color_grid = state.object_state.color
1127
1136
 
1128
1137
  if self.full_world:
1129
1138
  return self._get_world_obs(obs_grid, state)
1130
1139
  else:
1131
1140
  grid = self._get_aperture(obs_grid, state.pos)
1132
- return self._get_aperture_obs(grid, state)
1141
+ color_grid = self._get_aperture(color_grid, state.pos)
1142
+ return self._get_aperture_obs(grid, color_grid, state)
1133
1143
 
1134
1144
  def _get_world_obs(self, obs_grid: jax.Array, state: EnvState) -> jax.Array:
1135
1145
  """Get world observation."""
@@ -1146,12 +1156,14 @@ class ForagaxEnv(environment.Environment):
1146
1156
  obs = obs.at[state.pos[1], state.pos[0], -1].set(1)
1147
1157
  return obs
1148
1158
  elif self.observation_type == "rgb":
1149
- obs = jax.nn.one_hot(obs_grid, num_obj_types)
1150
- # Agent position
1151
- obs = obs.at[state.pos[1], state.pos[0], :].set(0)
1152
- obs = obs.at[state.pos[1], state.pos[0], -1].set(1)
1153
- colors = self.object_colors / 255.0
1154
- obs = jnp.tensordot(obs, colors, axes=1)
1159
+ # Use state colors directly (supports dynamic biomes)
1160
+ colors = state.object_state.color / 255.0
1161
+
1162
+ # Mask empty cells (object_id == 0) to white
1163
+ empty_mask = obs_grid == 0
1164
+ white_color = jnp.ones((self.size[1], self.size[0], 3), dtype=jnp.float32)
1165
+ obs = jnp.where(empty_mask[..., None], white_color, colors)
1166
+
1155
1167
  return obs
1156
1168
  elif self.observation_type == "color":
1157
1169
  # Handle case with no objects (only EMPTY)
@@ -1168,17 +1180,24 @@ class ForagaxEnv(environment.Environment):
1168
1180
  else:
1169
1181
  raise ValueError(f"Unknown observation_type: {self.observation_type}")
1170
1182
 
1171
- def _get_aperture_obs(self, aperture: jax.Array, state: EnvState) -> jax.Array:
1183
+ def _get_aperture_obs(
1184
+ self, aperture: jax.Array, color_aperture: jax.Array, state: EnvState
1185
+ ) -> jax.Array:
1172
1186
  """Get aperture observation."""
1173
1187
  if self.observation_type == "object":
1174
1188
  num_obj_types = len(self.object_ids)
1175
1189
  obs = jax.nn.one_hot(aperture, num_obj_types, axis=-1)
1176
1190
  return obs
1177
1191
  elif self.observation_type == "rgb":
1178
- num_obj_types = len(self.object_ids)
1179
- aperture_one_hot = jax.nn.one_hot(aperture, num_obj_types)
1180
- colors = self.object_colors / 255.0
1181
- obs = jnp.tensordot(aperture_one_hot, colors, axes=1)
1192
+ # Use the color aperture that was passed in
1193
+ aperture_colors = color_aperture / 255.0
1194
+
1195
+ # Mask empty cells (object_id == 0) to white
1196
+ empty_mask = aperture == 0
1197
+ white_color = jnp.ones(aperture_colors.shape, dtype=jnp.float32)
1198
+
1199
+ obs = jnp.where(empty_mask[..., None], white_color, aperture_colors)
1200
+
1182
1201
  return obs
1183
1202
  elif self.observation_type == "color":
1184
1203
  # Handle case with no objects (only EMPTY)
@@ -1229,6 +1248,10 @@ class ForagaxEnv(environment.Environment):
1229
1248
  if self.dynamic_biomes:
1230
1249
  # Use per-instance colors from state
1231
1250
  img = state.object_state.color.copy()
1251
+ # Mask empty cells (object_id == 0) to white
1252
+ empty_mask = state.object_state.object_id == 0
1253
+ white_color = jnp.array([255, 255, 255], dtype=jnp.uint8)
1254
+ img = jnp.where(empty_mask[..., None], white_color, img)
1232
1255
  else:
1233
1256
  # Use default object colors
1234
1257
  img = jnp.zeros((self.size[1], self.size[0], 3))
@@ -1297,6 +1320,14 @@ class ForagaxEnv(environment.Environment):
1297
1320
  )
1298
1321
  img = state.object_state.color[y_coords_adj, x_coords_adj]
1299
1322
 
1323
+ # Mask empty cells (object_id == 0) to white
1324
+ aperture_object_ids = state.object_state.object_id[
1325
+ y_coords_adj, x_coords_adj
1326
+ ]
1327
+ empty_mask = aperture_object_ids == 0
1328
+ white_color = jnp.array([255, 255, 255], dtype=jnp.uint8)
1329
+ img = jnp.where(empty_mask[..., None], white_color, img)
1330
+
1300
1331
  if self.nowrap:
1301
1332
  # For out-of-bounds, use padding object color
1302
1333
  y_out = (y_coords < 0) | (y_coords >= self.size[1])
@@ -308,7 +308,7 @@ def test_respawn():
308
308
 
309
309
 
310
310
  def test_random_respawn():
311
- """Test that an object respawns at a random empty location within its biome."""
311
+ """Test that an object can respawn at random empty locations within its biome."""
312
312
  key = jax.random.key(0)
313
313
 
314
314
  flower_random = DefaultForagaxObject(
@@ -329,46 +329,60 @@ def test_random_respawn():
329
329
  observation_type="color",
330
330
  )
331
331
  params = env.default_params
332
- _, state = env.reset(key, params)
333
332
 
334
333
  flower_id = 1 # 0 is EMPTY
335
334
  original_pos = jnp.array([3, 3])
336
335
 
337
- # Place a flower and move the agent to it
338
- grid = jnp.zeros((7, 7), dtype=int)
339
- grid = grid.at[original_pos[1], original_pos[0]].set(flower_id)
340
- # Add a wall to make sure it doesn't spawn there
341
- grid = grid.at[4, 4].set(2) # Use a fixed ID for the wall
342
- state = state.replace(
343
- object_state=state.object_state.replace(object_id=grid), pos=jnp.array([2, 3])
344
- )
336
+ # Test multiple times to verify randomness
337
+ timer_positions = []
338
+ for i in range(20):
339
+ key, reset_key = jax.random.split(key)
340
+ _, state = env.reset(reset_key, params)
341
+
342
+ # Place a flower and move the agent to it
343
+ grid = jnp.zeros((7, 7), dtype=int)
344
+ grid = grid.at[original_pos[1], original_pos[0]].set(flower_id)
345
+ # Add a wall to make sure it doesn't spawn there
346
+ grid = grid.at[4, 4].set(2) # Use a fixed ID for the wall
347
+ state = state.replace(
348
+ object_state=state.object_state.replace(object_id=grid),
349
+ pos=jnp.array([2, 3]),
350
+ )
345
351
 
346
- # Collect the flower
347
- key, step_key = jax.random.split(key)
348
- _, new_state, reward, _, _ = env.step(step_key, state, Actions.RIGHT, params)
352
+ # Collect the flower
353
+ key, step_key = jax.random.split(key)
354
+ _, new_state, reward, _, _ = env.step(step_key, state, Actions.RIGHT, params)
349
355
 
350
- assert reward == flower_random.reward_val
351
- # Original position should be empty
352
- assert new_state.object_state.object_id[original_pos[1], original_pos[0]] == 0
356
+ assert reward == flower_random.reward_val
357
+ # Original position should be empty
358
+ assert new_state.object_state.object_id[original_pos[1], original_pos[0]] == 0
353
359
 
354
- # A timer should be placed somewhere (check respawn_timer instead of object_id)
355
- assert jnp.sum(new_state.object_state.respawn_timer > 0) == 1
356
- timer_pos_flat = jnp.argmax(new_state.object_state.respawn_timer)
357
- timer_pos = jnp.array(jnp.unravel_index(timer_pos_flat, (7, 7)))
358
- # New position should not be the original position
359
- assert not jnp.array_equal(timer_pos, original_pos)
360
+ # A timer should be placed somewhere (check respawn_timer instead of object_id)
361
+ assert jnp.sum(new_state.object_state.respawn_timer > 0) == 1
362
+ timer_pos_flat = jnp.argmax(new_state.object_state.respawn_timer)
363
+ timer_pos_array = jnp.unravel_index(timer_pos_flat, (7, 7))
364
+ timer_pos = (int(timer_pos_array[0]), int(timer_pos_array[1]))
360
365
 
361
- # New position should be within the biome
362
- assert jnp.all(timer_pos >= jnp.array(biome.start))
363
- assert jnp.all(timer_pos < jnp.array(biome.stop))
366
+ # New position should be within the biome
367
+ assert timer_pos[0] >= biome.start[0] and timer_pos[0] < biome.stop[0]
368
+ assert timer_pos[1] >= biome.start[1] and timer_pos[1] < biome.stop[1]
364
369
 
365
- # New position should be on an empty cell (not the wall)
366
- assert not jnp.array_equal(timer_pos, jnp.array([4, 4]))
370
+ # New position should be on an empty cell (not the wall)
371
+ assert timer_pos != (4, 4)
367
372
 
368
- # Verify respawn_object_id is set correctly
369
- assert (
370
- new_state.object_state.respawn_object_id[timer_pos[0], timer_pos[1]]
371
- == flower_id
373
+ # Verify respawn_object_id is set correctly
374
+ assert (
375
+ new_state.object_state.respawn_object_id[timer_pos[0], timer_pos[1]]
376
+ == flower_id
377
+ )
378
+
379
+ timer_positions.append(timer_pos)
380
+
381
+ # Verify that we get multiple different positions (randomness works)
382
+ # With 20 trials and multiple valid positions, we should see at least 2 different locations
383
+ unique_positions = set(timer_positions)
384
+ assert len(unique_positions) >= 2, (
385
+ f"Expected at least 2 unique positions, got {len(unique_positions)}: {unique_positions}"
372
386
  )
373
387
 
374
388
 
@@ -1774,7 +1788,7 @@ def test_object_no_individual_respawn():
1774
1788
 
1775
1789
 
1776
1790
  def test_object_color_grid_cleared_on_collection():
1777
- """Test that object_color_grid is cleared when objects are collected."""
1791
+ """Test that object colors are preserved in state but masked in rendering when collected."""
1778
1792
  key = jax.random.key(0)
1779
1793
  env = ForagaxEnv(
1780
1794
  size=(7, 7),
@@ -1793,6 +1807,9 @@ def test_object_color_grid_cleared_on_collection():
1793
1807
  flower_pos = flower_positions[0]
1794
1808
  y, x = flower_pos
1795
1809
 
1810
+ # Store original color
1811
+ original_color = state.object_state.color[y, x].copy()
1812
+
1796
1813
  # Move agent to flower and collect it
1797
1814
  # Position agent above the flower so moving down collects it
1798
1815
  state = state.replace(pos=jnp.array([x, y - 1]))
@@ -1801,10 +1818,15 @@ def test_object_color_grid_cleared_on_collection():
1801
1818
 
1802
1819
  assert reward == FLOWER.reward_val
1803
1820
 
1804
- # Check that the color grid at the collected position is cleared (should be [255, 255, 255])
1821
+ # NEW BEHAVIOR: Color is preserved in state (not cleared to white)
1805
1822
  collected_color = state.object_state.color[y, x]
1806
- expected_empty_color = jnp.array([255, 255, 255], dtype=jnp.uint8)
1807
- chex.assert_trees_all_equal(collected_color, expected_empty_color)
1823
+ chex.assert_trees_all_equal(collected_color, original_color)
1824
+
1825
+ # But object_id should be 0 (or timer should be set)
1826
+ assert (
1827
+ state.object_state.object_id[y, x] == 0
1828
+ or state.object_state.respawn_timer[y, x] > 0
1829
+ )
1808
1830
 
1809
1831
  # Check that other positions with objects still have their colors
1810
1832
  other_flower_positions = jnp.argwhere(
@@ -1814,11 +1836,31 @@ def test_object_color_grid_cleared_on_collection():
1814
1836
  other_pos = other_flower_positions[0]
1815
1837
  other_color = state.object_state.color[other_pos[0], other_pos[1]]
1816
1838
  # Should not be the empty color
1839
+ expected_empty_color = jnp.array([255, 255, 255], dtype=jnp.uint8)
1817
1840
  assert not jnp.allclose(other_color, expected_empty_color)
1818
1841
 
1842
+ # Test RGB observation: empty cells should appear white
1843
+ # Create an RGB environment with the same setup
1844
+ env_rgb = ForagaxEnv(
1845
+ size=(7, 7),
1846
+ objects=(FLOWER,),
1847
+ biomes=(Biome(object_frequencies=(1.0,)),),
1848
+ observation_type="rgb",
1849
+ dynamic_biomes=True,
1850
+ aperture_size=-1, # Use world view to get full grid observation
1851
+ )
1852
+ # Use the same state to get observation
1853
+ obs_rgb = env_rgb.get_obs(state, params)
1854
+
1855
+ # Check that the collected position shows white in RGB observation
1856
+ # RGB observations are normalized to [0, 1], so white is [1.0, 1.0, 1.0]
1857
+ collected_rgb = obs_rgb[y, x]
1858
+ expected_white_rgb = jnp.array([1.0, 1.0, 1.0], dtype=jnp.float32)
1859
+ chex.assert_trees_all_close(collected_rgb, expected_white_rgb, rtol=1e-5)
1860
+
1819
1861
 
1820
1862
  def test_object_color_grid_cleared_on_expiry():
1821
- """Test that object_color_grid is cleared when objects expire."""
1863
+ """Test that object colors are preserved in state but masked in rendering when expired."""
1822
1864
  # Create an object that expires quickly
1823
1865
  expiring_obj = DefaultForagaxObject(
1824
1866
  name="expiring",
@@ -1847,6 +1889,9 @@ def test_object_color_grid_cleared_on_expiry():
1847
1889
  obj_pos = obj_positions[0]
1848
1890
  y, x = obj_pos
1849
1891
 
1892
+ # Store original color
1893
+ original_color = state.object_state.color[y, x].copy()
1894
+
1850
1895
  # Step until expiry (4 steps: expiry happens when age >= expiry_time)
1851
1896
  for _ in range(4):
1852
1897
  key, key_step = jax.random.split(key)
@@ -1854,10 +1899,34 @@ def test_object_color_grid_cleared_on_expiry():
1854
1899
  key_step, state, Actions.DOWN, env.default_params
1855
1900
  )
1856
1901
 
1857
- # Object should have expired and color should be cleared
1902
+ # NEW BEHAVIOR: Color is preserved in state (not cleared to white)
1858
1903
  expired_color = state.object_state.color[y, x]
1859
- expected_empty_color = jnp.array([255, 255, 255], dtype=jnp.uint8)
1860
- chex.assert_trees_all_equal(expired_color, expected_empty_color)
1904
+ chex.assert_trees_all_equal(expired_color, original_color)
1905
+
1906
+ # But object_id should be 0 (or timer should be set)
1907
+ assert (
1908
+ state.object_state.object_id[y, x] == 0
1909
+ or state.object_state.respawn_timer[y, x] > 0
1910
+ )
1911
+
1912
+ # Test RGB observation: empty/expired cells should appear white
1913
+ # Create an RGB environment with the same setup
1914
+ env_rgb = ForagaxEnv(
1915
+ size=(5, 5),
1916
+ aperture_size=-1, # Use world view to get full grid observation
1917
+ objects=(expiring_obj,),
1918
+ biomes=(Biome(object_frequencies=(0.5,)),),
1919
+ observation_type="rgb",
1920
+ dynamic_biomes=True,
1921
+ )
1922
+ # Use the same state to get observation
1923
+ obs_rgb = env_rgb.get_obs(state, env.default_params)
1924
+
1925
+ # Check that the expired position shows white in RGB observation
1926
+ # RGB observations are normalized to [0, 1], so white is [1.0, 1.0, 1.0]
1927
+ expired_rgb = obs_rgb[y, x]
1928
+ expected_white_rgb = jnp.array([1.0, 1.0, 1.0], dtype=jnp.float32)
1929
+ chex.assert_trees_all_close(expired_rgb, expected_white_rgb, rtol=1e-5)
1861
1930
 
1862
1931
 
1863
1932
  def test_biome_regeneration_preserves_old_objects():
@@ -2728,3 +2797,35 @@ def test_sine_object():
2728
2797
  r_orig = sine_obj.reward(t, key, None)
2729
2798
  r_shift = sine_obj_shifted.reward(t, key, None)
2730
2799
  assert jnp.allclose(r_orig + r_shift, 0.0, atol=0.01)
2800
+
2801
+
2802
+ def test_info_rewards():
2803
+ """Test that info contains rewards with reward values for each grid position."""
2804
+ key = jax.random.key(0)
2805
+ env = ForagaxEnv(
2806
+ size=(5, 5),
2807
+ objects=(FLOWER,),
2808
+ biomes=(Biome(object_frequencies=(0.5,)),),
2809
+ observation_type="object",
2810
+ )
2811
+ params = env.default_params
2812
+ obs, state = env.reset(key, params)
2813
+
2814
+ key, step_key = jax.random.split(key)
2815
+ _, _, _, _, info = env.step(step_key, state, Actions.UP, params)
2816
+
2817
+ # Check that rewards is in info
2818
+ assert "rewards" in info
2819
+
2820
+ # Check shape matches environment size
2821
+ assert info["rewards"].shape == (5, 5)
2822
+
2823
+ # Check that positions with objects have non-zero rewards
2824
+ object_mask = state.object_state.object_id > 0
2825
+ rewards_at_objects = info["rewards"][object_mask]
2826
+ assert jnp.all(rewards_at_objects == FLOWER.reward_val)
2827
+
2828
+ # Check that empty positions have zero rewards
2829
+ empty_mask = state.object_state.object_id == 0
2830
+ rewards_at_empty = info["rewards"][empty_mask]
2831
+ assert jnp.all(rewards_at_empty == 0.0)
@@ -1,10 +0,0 @@
1
- gymnax
2
-
3
- [:python_version < "3.10"]
4
- six
5
-
6
- [dev]
7
- pre-commit
8
- pytest
9
- pytest-benchmark
10
- ruff