diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7b3e5a218..62543c13c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,7 +24,7 @@ If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. mac/linux/windows] - - Version [e.g. 1.2.22] + - Version [e.g. 1.2.23] **Additional context** Add any other context about the problem here. diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dc63384b..8a5fb3b25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10.0) -project(Griddly VERSION 1.2.22) +project(Griddly VERSION 1.2.23) set(BINARY ${CMAKE_PROJECT_NAME}) diff --git a/bindings/python.cpp b/bindings/python.cpp index 5be7d269f..0e85b2f32 100644 --- a/bindings/python.cpp +++ b/bindings/python.cpp @@ -12,7 +12,7 @@ namespace griddly { PYBIND11_MODULE(python_griddly, m) { m.doc() = "Griddly python bindings"; - m.attr("version") = "1.2.22"; + m.attr("version") = "1.2.23"; #ifndef NDEBUG spdlog::set_level(spdlog::level::debug); diff --git a/docs/conf.py b/docs/conf.py index 985526b1c..be697b481 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Chris Bamford' # The full version, including alpha/beta/rc tags -release = '1.2.22' +release = '1.2.23' # -- General configuration --------------------------------------------------- diff --git a/python/setup.py b/python/setup.py index cc30304f8..c379d3404 100644 --- a/python/setup.py +++ b/python/setup.py @@ -71,7 +71,7 @@ def griddly_package_data(config='Debug'): setup( name='griddly', - version="1.2.22", + version="1.2.23", author_email="chrisbam4d@gmail.com", description="Griddly Python Libraries", long_description=long_description, diff --git a/python/tests/env_state_test.py b/python/tests/env_state_test.py new file mode 100644 index 000000000..2793960fc --- /dev/null +++ b/python/tests/env_state_test.py @@ -0,0 +1,64 @@ +import numpy as np +import gym +import pytest +from griddly import GymWrapperFactory, gd + +@pytest.fixture +def test_name(request): + return request.node.name + + +def build_test_env(test_name, yaml_file): + wrapper_factory = GymWrapperFactory() + + wrapper_factory.build_gym_from_yaml( + test_name, + yaml_file, + global_observer_type=gd.ObserverType.VECTOR, + player_observer_type=gd.ObserverType.VECTOR, + ) + + env = gym.make(f'GDY-{test_name}-v0') + env.reset() + return env + +def test_state_hash_consistent_under_nop(test_name): + """ + Test that under NOP actions, the state hash stays the same no state change other than environment steps + """ + env = build_test_env( + test_name, + "tests/gdy/test_step_SinglePlayer_SingleActionType.yaml" + ) + + first_state = env.get_state() + env.step(0) + second_state = env.get_state() + + assert first_state['Hash'] == second_state['Hash'] + + +def test_state_hash_consistent_return_to_state(test_name): + """ + Test that if we move to one state and back, the two states should have consistent states + """ + env = build_test_env( + test_name, + "tests/gdy/test_step_SinglePlayer_SingleActionType.yaml" + ) + + first_state_hashes = [] + second_state_hashes = [] + first_state_hashes.append(env.get_state()['Hash']) + + env.step(1) + second_state_hashes.append(env.get_state()['Hash']) + + env.step(3) + first_state_hashes.append(env.get_state()['Hash']) + + env.step(1) + second_state_hashes.append(env.get_state()['Hash']) + + assert len(set(first_state_hashes)) == 1 + assert len(set(second_state_hashes)) == 1 \ No newline at end of file diff --git a/src/Griddly/Core/GameProcess.cpp b/src/Griddly/Core/GameProcess.cpp index a721836ab..170fe4d34 100644 --- a/src/Griddly/Core/GameProcess.cpp +++ b/src/Griddly/Core/GameProcess.cpp @@ -300,10 +300,14 @@ std::vector GameProcess::getAvailableActionIdsAtLocation(glm::ivec2 lo void GameProcess::generateStateHash(StateInfo& stateInfo) const { // Hash global variables for (auto variableIt : stateInfo.globalVariables) { - hash_combine(stateInfo.hash, variableIt.first); - for (auto playerVariableIt : variableIt.second) { - hash_combine(stateInfo.hash, playerVariableIt.second); - hash_combine(stateInfo.hash, playerVariableIt.first); + + // Ignore the internal _steps count + if(variableIt.first != "_steps") { + hash_combine(stateInfo.hash, variableIt.first); + for (auto playerVariableIt : variableIt.second) { + hash_combine(stateInfo.hash, playerVariableIt.second); + hash_combine(stateInfo.hash, playerVariableIt.first); + } } }