Repository: google-deepmind/open_spiel (language: python)

Issue:
Game serialize/deserialize
Forenote: I previously wrote the `stones_n_gems` game.

## Problem 
The `stones_n_gems` game uses a string containing commas to represent the map being used, which clashes with how the `GameParametersFromString` function parses serialized Games.

## Description / Explanation
The `stones_n_gems` game allows for various input maps to play. Maps are used in the game initialization process through the GameParameter `grid`  string, which is a string containing newlines/commas to represent each item in the underlying map. I've been trying to use the game in python code which pickles the game/state, and have been getting errors about `Unknown parameter` during the deserializing process.

I've looked into how the pyspiel state python objects are pickled, and it appears that both the game/state are pickled. I've narrowed down the issue to what I believe is the `GameParametersFromString` function.  For this particular game, it receives as input the following (note that the commas/newlines are part of the string):
```
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18,18,18,18,18
18,02,02,02,02,02,02,02,02,02,02,18
18,02,02,02,02,02,04,02,02,02,02,18
18,02,02,02,02,02,02,02,02,02,02,18
18,02,02,02,02,02,01,02,02,02,02,18
18,02,02,02,00,02,01,02,02,02,02,18
18,02,02,02,02,02,01,02,02,02,02,18
18,02,02,02,02,02,01,02,02,02,02,18
18,02,02,02,02,02,02,02,02,02,02,18
18,02,02,02,02,02,02,02,02,02,02,18
18,02,02,02,02,02,02,02,02,02,08,18
18,18,18,18,18,18,18,18,18,18,18,18,obs_show_ids=True)
```
During the inner loop which reads each game parameter, I see the following when debug printing `game_string.substr(equals + 1, i - equals - 1)`:
```
12
---
stones_and_gems(grid=12,12
---
stones_and_gems(grid=12,12,999999
---
stones_and_gems(grid=12,12,999999,1
18
---
stones_and_gems(grid=12,12,999999,1
18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18,18,18,18
---
stones_and_gems(grid=12,12,999999,1
18,18,18,18,18,18,18,18,18,18,18,18
18

```
etc.

## Solution
I believe the solution to this is to change the commas in the `grid` parameter to be another symbol (say `|` as an example). This is an easy fix on my end, but will break compatibility for anyone who has existing code which uses this game.

Let me know if I should go ahead with a PR on this.



Discussion / hints:

Fix patch:
diff --git a/open_spiel/games/stones_and_gems.cc b/open_spiel/games/stones_and_gems.cc
index 03dc1bd0be..2d52e136c2 100644
--- a/open_spiel/games/stones_and_gems.cc
+++ b/open_spiel/games/stones_and_gems.cc
@@ -37,6 +37,7 @@ enum ElementProperties {
   kConsumable = 1 << 0,
   kCanExplode = 1 << 1,
   kRounded = 1 << 2,
+  kTraversable = 1 << 3,
 };
 
 // All possible elements
@@ -48,14 +49,16 @@ const Element kElAgentInExit = {HiddenCellType::kAgentInExit,
                                 ElementProperties::kNone, '!'};
 const Element kElExitOpen = {HiddenCellType::kExitOpen,
                              VisibleCellType::kExitOpen,
-                             ElementProperties::kNone, '#'};
+                             ElementProperties::kTraversable, '#'};
 const Element kElExitClosed = {HiddenCellType::kExitClosed,
                                VisibleCellType::kExitClosed,
                                ElementProperties::kNone, 'C'};
 const Element kElEmpty = {HiddenCellType::kEmpty, VisibleCellType::kEmpty,
-                          ElementProperties::kConsumable, ' '};
+                          ElementProperties::kConsumable | 
+                          ElementProperties::kTraversable, ' '};
 const Element kElDirt = {HiddenCellType::kDirt, VisibleCellType::kDirt,
-                         ElementProperties::kConsumable, '.'};
+                         ElementProperties::kConsumable | 
+                         ElementProperties::kTraversable, '.'};
 const Element kElStone = {
     HiddenCellType::kStone, VisibleCellType::kStone,
     ElementProperties::kConsumable | ElementProperties::kRounded, 'o'};
@@ -64,7 +67,9 @@ const Element kElStoneFalling = {HiddenCellType::kStoneFalling,
                                  ElementProperties::kConsumable, 'o'};
 const Element kElDiamond = {
     HiddenCellType::kDiamond, VisibleCellType::kDiamond,
-    ElementProperties::kConsumable | ElementProperties::kRounded, '*'};
+    ElementProperties::kConsumable | 
+    ElementProperties::kRounded | 
+    ElementProperties::kTraversable, '*'};
 const Element kElDiamondFalling = {HiddenCellType::kDiamondFalling,
                                    VisibleCellType::kDiamond,
                                    ElementProperties::kConsumable, '*'};
@@ -125,7 +130,7 @@ const Element kElGateRedOpen = {HiddenCellType::kGateRedOpen,
                                 VisibleCellType::kGateRedOpen,
                                 ElementProperties::kNone, 'R'};
 const Element kElKeyRed = {HiddenCellType::kKeyRed, VisibleCellType::kKeyRed,
-                           ElementProperties::kNone, '1'};
+                           ElementProperties::kTraversable, '1'};
 const Element kElGateBlueClosed = {HiddenCellType::kGateBlueClosed,
                                    VisibleCellType::kGateBlueClosed,
                                    ElementProperties::kNone, 'b'};
@@ -133,7 +138,7 @@ const Element kElGateBlueOpen = {HiddenCellType::kGateBlueOpen,
                                  VisibleCellType::kGateBlueOpen,
                                  ElementProperties::kNone, 'B'};
 const Element kElKeyBlue = {HiddenCellType::kKeyBlue, VisibleCellType::kKeyBlue,
-                            ElementProperties::kNone, '2'};
+                            ElementProperties::kTraversable, '2'};
 const Element kElGateGreenClosed = {HiddenCellType::kGateGreenClosed,
                                     VisibleCellType::kGateGreenClosed,
                                     ElementProperties::kNone, 'g'};
@@ -142,7 +147,7 @@ const Element kElGateGreenOpen = {HiddenCellType::kGateGreenOpen,
                                   ElementProperties::kNone, 'G'};
 const Element kElKeyGreen = {HiddenCellType::kKeyGreen,
                              VisibleCellType::kKeyGreen,
-                             ElementProperties::kNone, '3'};
+                             ElementProperties::kTraversable, '3'};
 const Element kElGateYellowClosed = {HiddenCellType::kGateYellowClosed,
                                      VisibleCellType::kGateYellowClosed,
                                      ElementProperties::kNone, 'y'};
@@ -151,7 +156,7 @@ const Element kElGateYellowOpen = {HiddenCellType::kGateYellowOpen,
                                    ElementProperties::kNone, 'Y'};
 const Element kElKeyYellow = {HiddenCellType::kKeyYellow,
                               VisibleCellType::kKeyYellow,
-                              ElementProperties::kNone, '4'};
+                              ElementProperties::kTraversable, '4'};
 const Element kElNut = {
     HiddenCellType::kNut, VisibleCellType::kNut,
     ElementProperties::kRounded | ElementProperties::kConsumable, '+'};
@@ -861,9 +866,17 @@ void StonesNGemsState::UpdateAgent(int index, int action) {
     OpenGate(kKeyToGate.at(GetItem(index, action)));
     MoveItem(index, action);
   } else if (IsOpenGate(GetItem(index, action))) {
-    // Walking through an open gate
+    // Walking through an open gate, with traversable element on other side
     int index_gate = IndexFromAction(index, action);
-    if (IsType(index_gate, kElEmpty, action)) {
+    if (HasProperty(index_gate, ElementProperties::kTraversable, action)) {
+      // Correct for landing on traversable elements
+      if (IsType(index_gate, kElDiamond, action)) {
+        ++gems_collected_;
+        current_reward_ += kGemPoints.at(GetItem(index_gate, action));
+        sum_reward_ += kGemPoints.at(GetItem(index_gate, action));
+      } else if (IsKey(GetItem(index_gate, action))) {
+        OpenGate(kKeyToGate.at(GetItem(index_gate, action)));
+      }
       SetItem(index_gate, kElAgent, grid_.ids[index], action);
       SetItem(index, kElEmpty, ++id_counter_);
     }
@@ -1126,9 +1139,11 @@ std::string StonesNGemsState::Serialize() const {
   absl::StrAppend(&out_str, cur_player_, "\n");
   // grid contents
   int col_counter = 0;
-  for (const auto el : grid_.elements) {
+  for (std::size_t i = 0; i < grid_.elements.size(); ++i) {
     ++col_counter;
-    absl::StrAppend(&out_str, static_cast<int>(el.cell_type), ",");
+    absl::StrAppend(&out_str, 
+      static_cast<int>(grid_.elements[i].cell_type), ",");
+    absl::StrAppend(&out_str, grid_.ids[i], ",");
     if (col_counter == grid_.num_cols) {
       out_str.pop_back();
       absl::StrAppend(&out_str, "\n");
@@ -1166,13 +1181,7 @@ StonesNGemsState::StonesNGemsState(
       grid_(grid),
       obs_show_ids_(obs_show_ids),
       id_counter_(id_counter),
-      cur_player_(player) {
-  // Initialize the grid element IDs
-  grid_.ids.clear();
-  for (std::size_t i = 0; i < grid.elements.size(); ++i) {
-    grid_.ids.push_back(++id_counter_);
-  }
-}
+      cur_player_(player) {}
 
 // ------ Game -------
 
@@ -1213,18 +1222,22 @@ std::unique_ptr<State> StonesNGemsGame::DeserializeState(
   for (std::size_t i = 1; i < lines.size(); ++i) {
     std::vector<std::string> grid_line = absl::StrSplit(lines[i], ',');
     // Check for proper number of columns
-    if (grid_line.size() != grid.num_cols) {
+    if (grid_line.size() != grid.num_cols * 2) {
       SpielFatalError(absl::StrCat("Grid line ", i - 1,
                                    "doesn't have correct number of elements."));
     }
     // Check each element in row
-    for (const auto &type : grid_line) {
-      auto it = kCellTypeToElement.find(std::stoi(type));
+    // for (const auto &type : grid_line) {
+    for (std::size_t i = 0; i < grid_line.size() / 2; ++i) {
+      // Element
+      auto it = kCellTypeToElement.find(std::stoi(grid_line[2*i]));
       if (it != kCellTypeToElement.end()) {
         grid.elements.push_back(it->second);
       } else {
-        SpielFatalError(absl::StrCat("Unknown element id: ", type));
+        SpielFatalError(absl::StrCat("Unknown element id: ", grid_line[2*i]));
       }
+      // ID
+      grid.ids.push_back(std::stoi(grid_line[2*i + 1]));
     }
   }
   // Ensure we read proper number of rows
@@ -1312,7 +1325,7 @@ Grid StonesNGemsGame::ParseGrid(const std::string &grid_string,
     SpielFatalError("Empty map string passed.");
   }
   // Parse first line which contains level properties
-  std::vector<std::string> property_line = absl::StrSplit(lines[0], ',');
+  std::vector<std::string> property_line = absl::StrSplit(lines[0], '|');
   SPIEL_CHECK_TRUE(absl::SimpleAtoi(property_line[0], &grid.num_cols));
   SPIEL_CHECK_TRUE(absl::SimpleAtoi(property_line[1], &grid.num_rows));
   SPIEL_CHECK_TRUE(absl::SimpleAtoi(property_line[2], &max_steps_));
@@ -1321,7 +1334,7 @@ Grid StonesNGemsGame::ParseGrid(const std::string &grid_string,
   // Parse grid contents
   for (std::size_t i = 1; i < lines.size(); ++i) {
     // Check for proper number of columns
-    std::vector<std::string> grid_line = absl::StrSplit(lines[i], ',');
+    std::vector<std::string> grid_line = absl::StrSplit(lines[i], '|');
     if (grid_line.size() != grid.num_cols) {
       SpielFatalError(absl::StrCat(
           "Grid line ", i - 1, " doesn't have correct number of elements.",
@@ -1350,6 +1363,12 @@ Grid StonesNGemsGame::ParseGrid(const std::string &grid_string,
   }
   blob_max_size_ = (int)(grid_.num_cols * grid_.num_rows * blob_max_percentage);
 
+  // Initialize the grid element IDs
+  grid_.ids.clear();
+  for (std::size_t i = 0; i < grid.elements.size(); ++i) {
+    grid_.ids.push_back(i + 1);
+  }
+
   return grid;
 }
 
diff --git a/open_spiel/games/stones_and_gems.h b/open_spiel/games/stones_and_gems.h
index e7c7ee8764..d543f9132d 100644
--- a/open_spiel/games/stones_and_gems.h
+++ b/open_spiel/games/stones_and_gems.h
@@ -73,7 +73,7 @@
 //                                          kDefaultGrid below)
 //
 // Grid parameter specification
-//     - The grid string parameter is a comma-separated string representing the
+//     - The grid string parameter is a pipe-separated (|) string representing the
 //     map
 //     - The first line should contain the # of cols, # of rows, max_steps, and
 //     gems required
@@ -236,19 +236,19 @@ struct Grid {
 
 // Default map, simple level of gems/stones/exit
 inline constexpr char kDefaultGrid[] =
-    "20,12,600,4\n"
-    "19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n"
-    "19,03,02,02,03,02,02,02,02,03,02,02,02,02,02,03,02,02,02,19\n"
-    "19,02,00,02,02,02,02,02,02,01,02,02,02,02,02,02,02,02,02,19\n"
-    "19,02,02,02,05,02,02,02,02,02,02,03,02,02,02,02,02,02,02,19\n"
-    "19,18,18,18,18,18,18,18,18,18,18,18,18,18,02,02,02,03,02,19\n"
-    "19,02,02,02,02,02,05,02,02,02,02,02,02,02,02,02,02,02,02,19\n"
-    "19,02,02,03,02,02,02,02,02,02,02,05,02,02,03,02,02,01,01,19\n"
-    "19,02,02,03,02,02,02,03,02,02,02,02,02,02,02,02,02,01,11,19\n"
-    "19,02,02,02,02,02,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n"
-    "19,02,02,05,02,02,02,02,02,02,05,03,02,02,03,02,02,03,02,19\n"
-    "19,02,02,02,02,02,02,02,02,02,02,02,02,02,03,02,02,02,02,07\n"
-    "19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19";
+    "20|12|600|4\n"
+    "19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19\n"
+    "19|03|02|02|03|02|02|02|02|03|02|02|02|02|02|03|02|02|02|19\n"
+    "19|02|00|02|02|02|02|02|02|01|02|02|02|02|02|02|02|02|02|19\n"
+    "19|02|02|02|05|02|02|02|02|02|02|03|02|02|02|02|02|02|02|19\n"
+    "19|18|18|18|18|18|18|18|18|18|18|18|18|18|02|02|02|03|02|19\n"
+    "19|02|02|02|02|02|05|02|02|02|02|02|02|02|02|02|02|02|02|19\n"
+    "19|02|02|03|02|02|02|02|02|02|02|05|02|02|03|02|02|01|01|19\n"
+    "19|02|02|03|02|02|02|03|02|02|02|02|02|02|02|02|02|01|11|19\n"
+    "19|02|02|02|02|02|18|18|18|18|18|18|18|18|18|18|18|18|18|19\n"
+    "19|02|02|05|02|02|02|02|02|02|05|03|02|02|03|02|02|03|02|19\n"
+    "19|02|02|02|02|02|02|02|02|02|02|02|02|02|03|02|02|02|02|07\n"
+    "19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19";
 
 class StonesNGemsState : public State {
  public:
@@ -350,7 +350,7 @@ class StonesNGemsGame : public Game {
     return std::unique_ptr<State>(new StonesNGemsState(
         shared_from_this(), max_steps_, magic_wall_steps_, false,
         blob_max_size_, 0, blob_chance_, kNullElement, true, gems_required_, 0,
-        0, 0, grid_, obs_show_ids_, 0, 0));
+        0, 0, grid_, obs_show_ids_, (int)grid_.ids.size(), 0));
   }
   int MaxGameLength() const override;
   int NumPlayers() const override;


Test patch:
diff --git a/open_spiel/games/stones_and_gems_test.cc b/open_spiel/games/stones_and_gems_test.cc
index e7e738e264..8595f595d0 100644
--- a/open_spiel/games/stones_and_gems_test.cc
+++ b/open_spiel/games/stones_and_gems_test.cc
@@ -33,14 +33,14 @@ void BasicStonesNGemsTests() {
 
 void BasicStonesNGemsTestsWithParams() {
   constexpr const char kTestDefaultGrid[] =
-      "6,7,20,2\n"
-      "19,19,19,19,19,19\n"
-      "19,01,01,01,01,19\n"
-      "19,02,02,01,01,19\n"
-      "19,01,01,01,01,19\n"
-      "19,00,03,01,02,19\n"
-      "19,05,02,05,01,07\n"
-      "19,19,19,19,19,19";
+      "6|7|20|2\n"
+      "19|19|19|19|19|19\n"
+      "19|01|01|01|01|19\n"
+      "19|02|02|01|01|19\n"
+      "19|01|01|01|01|19\n"
+      "19|00|03|01|02|19\n"
+      "19|05|02|05|01|07\n"
+      "19|19|19|19|19|19";
 
   testing::ChanceOutcomesTest(
       *LoadGame("stones_and_gems",
@@ -53,14 +53,14 @@ void BasicStonesNGemsTestsWithParams() {
 
 void ExtendedStonesNGemsTest() {
   constexpr const char kTestDefaultGrid[] =
-      "6,7,20,2\n"
-      "19,19,19,19,19,19\n"
-      "19,01,01,01,03,19\n"
-      "19,02,02,01,01,19\n"
-      "19,01,01,01,02,19\n"
-      "19,00,03,01,02,19\n"
-      "19,05,02,05,01,07\n"
-      "19,19,19,19,19,19";
+      "6|7|20|2\n"
+      "19|19|19|19|19|19\n"
+      "19|01|01|01|03|19\n"
+      "19|02|02|01|01|19\n"
+      "19|01|01|01|02|19\n"
+      "19|00|03|01|02|19\n"
+      "19|05|02|05|01|07\n"
+      "19|19|19|19|19|19";
 
   constexpr const char kStateToString[] =
       "SSSSSS\n"
@@ -73,14 +73,14 @@ void ExtendedStonesNGemsTest() {
       "time left: 20, gems required: 2, gems collectred: 0";
 
   constexpr const char kStateSerialize[] =
-      "6,7,20,20,0,10,0,50,-1,1,2,0,0,0,1,42,0\n"
-      "19,19,19,19,19,19\n"
-      "19,1,1,1,3,19\n"
-      "19,2,2,1,1,19\n"
-      "19,1,1,1,2,19\n"
-      "19,0,3,1,2,19\n"
-      "19,5,2,5,1,7\n"
-      "19,19,19,19,19,19";
+    "6,7,20,20,0,10,0,50,-1,1,2,0,0,0,1,42,0\n"
+      "19,1,19,2,19,3,19,4,19,5,19,6\n"
+      "19,7,1,8,1,9,1,10,3,11,19,12\n"
+      "19,13,2,14,2,15,1,16,1,17,19,18\n"
+      "19,19,1,20,1,21,1,22,2,23,19,24\n"
+      "19,25,0,26,3,27,1,28,2,29,19,30\n"
+      "19,31,5,32,2,33,5,34,1,35,7,36\n"
+      "19,37,19,38,19,39,19,40,19,41,19,42";
 
   // observation tensor index along with corresponding IDs
   const int offset = 6 * 7;
diff --git a/open_spiel/integration_tests/playthroughs/stones_and_gems.txt b/open_spiel/integration_tests/playthroughs/stones_and_gems.txt
index 63da467b59..f765471d80 100644
--- a/open_spiel/integration_tests/playthroughs/stones_and_gems.txt
+++ b/open_spiel/integration_tests/playthroughs/stones_and_gems.txt
@@ -19,7 +19,7 @@ GameType.utility = Utility.GENERAL_SUM
 NumDistinctActions() = 5
 PolicyTensorShape() = [5]
 MaxChanceOutcomes() = 1
-GetParameters() = {blob_chance=20,blob_max_percentage=0.16,grid=20,12,600,4\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,03,02,02,03,02,02,02,02,03,02,02,02,02,02,03,02,02,02,19\n19,02,00,02,02,02,02,02,02,01,02,02,02,02,02,02,02,02,02,19\n19,02,02,02,05,02,02,02,02,02,02,03,02,02,02,02,02,02,02,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,02,02,02,03,02,19\n19,02,02,02,02,02,05,02,02,02,02,02,02,02,02,02,02,02,02,19\n19,02,02,03,02,02,02,02,02,02,02,05,02,02,03,02,02,01,01,19\n19,02,02,03,02,02,02,03,02,02,02,02,02,02,02,02,02,01,11,19\n19,02,02,02,02,02,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,02,02,05,02,02,02,02,02,02,05,03,02,02,03,02,02,03,02,19\n19,02,02,02,02,02,02,02,02,02,02,02,02,02,03,02,02,02,02,07\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,magic_wall_steps=140,obs_show_ids=False,rng_seed=0}
+GetParameters() = {blob_chance=20,blob_max_percentage=0.16,grid=20|12|600|4\n19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19\n19|03|02|02|03|02|02|02|02|03|02|02|02|02|02|03|02|02|02|19\n19|02|00|02|02|02|02|02|02|01|02|02|02|02|02|02|02|02|02|19\n19|02|02|02|05|02|02|02|02|02|02|03|02|02|02|02|02|02|02|19\n19|18|18|18|18|18|18|18|18|18|18|18|18|18|02|02|02|03|02|19\n19|02|02|02|02|02|05|02|02|02|02|02|02|02|02|02|02|02|02|19\n19|02|02|03|02|02|02|02|02|02|02|05|02|02|03|02|02|01|01|19\n19|02|02|03|02|02|02|03|02|02|02|02|02|02|02|02|02|01|11|19\n19|02|02|02|02|02|18|18|18|18|18|18|18|18|18|18|18|18|18|19\n19|02|02|05|02|02|02|02|02|02|05|03|02|02|03|02|02|03|02|19\n19|02|02|02|02|02|02|02|02|02|02|02|02|02|03|02|02|02|02|07\n19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19|19,magic_wall_steps=140,obs_show_ids=False,rng_seed=0}
 NumPlayers() = 1
 MinUtility() = 0.0
 MaxUtility() = 664.0
@@ -142,20 +142,20 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,600,140,0,38,0,20,-1,1,4,0,0,0,0,240,0\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,3,2,2,3,2,2,2,2,3,2,2,2,2,2,3,2,2,2,19\n19,2,0,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,19\n19,2,2,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,1,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,1,11,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,600,140,0,38,0,20,-1,1,4,0,0,0,0,240,0\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,3,22,2,23,2,24,3,25,2,26,2,27,2,28,2,29,3,30,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,2,42,0,43,2,44,2,45,2,46,2,47,2,48,2,49,1,50,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,2,62,2,63,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,18,82,18,83,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,138,1,139,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,1,158,11,159,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 Rewards() = [0.0]
 Returns() = [0.0]
 LegalActions() = [0, 1, 2, 3, 4]
 StringLegalActions() = ["none", "up", "right", "down", "left"]
 
-# Apply action "left"
-action: 4
+# Apply action "right"
+action: 2
 
 # State 1
 # chance node
 IsTerminal() = False
-History() = [4]
-HistoryString() = "4"
+History() = [2]
+HistoryString() = "2"
 IsChanceNode() = True
 IsSimultaneousNode() = False
 CurrentPlayer() = -1
@@ -251,7 +251,7 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,599,140,0,38,0,20,-1,1,4,0,0,0,0,241,-1\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,3,2,2,3,2,2,2,2,3,2,2,2,2,2,3,2,2,2,19\n19,0,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,19\n19,2,2,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,1,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,1,11,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,599,140,0,38,0,20,-1,1,4,0,0,0,0,241,-1\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,3,22,2,23,2,24,3,25,2,26,2,27,2,28,2,29,3,30,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,2,42,1,241,0,43,2,45,2,46,2,47,2,48,2,49,1,50,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,2,62,2,63,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,18,82,18,83,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,138,1,139,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,1,158,11,159,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 ChanceOutcomes() = [(0, 1.0)]
 LegalActions() = [0]
 StringLegalActions() = ["Chance outcome: 0"]
@@ -262,7 +262,7 @@ action: 0
 # State 2
 # SSSSSSSSSSSSSSSSSSSS
 # So..o.... .....o...S
-# S@ ......o.........S
+# S. @.....o.........S
 # S...*......o.......S
 # SHHHHHHHHHHHHH...o.S
 # S.....*............S
@@ -274,16 +274,16 @@ action: 0
 # SSSSSSSSSSSSSSSSSSSS
 # time left: 599, gems required: 4, gems collectred: 0
 IsTerminal() = False
-History() = [4, 0]
-HistoryString() = "4, 0"
+History() = [2, 0]
+HistoryString() = "2, 0"
 IsChanceNode() = False
 IsSimultaneousNode() = False
 CurrentPlayer() = 0
-ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nSo..o.... .....o...S\nS@ ......o.........S\nS...*......o.......S\nSHHHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o..  S\nS..o...o.........F S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 599, gems required: 4, gems collectred: 0"
+ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nSo..o.... .....o...S\nS. @.....o.........S\nS...*......o.......S\nSHHHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o..  S\nS..o...o.........F S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 599, gems required: 4, gems collectred: 0"
 ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◉◉◯◉◉◉◉◯◉◉◉◉◉◯◉◉◉◯  ◯◉◯◯◉◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
+◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◯◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◉◉◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯  ◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◉◉◯◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯
@@ -371,20 +371,20 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,599,140,0,38,0,20,5,1,4,0,0,0,0,243,0\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,3,2,2,3,2,2,2,2,1,2,2,2,2,2,3,2,2,2,19\n19,0,1,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,19\n19,2,2,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,1,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,11,1,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,599,140,0,38,0,20,5,1,4,0,0,0,0,243,0\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,3,22,2,23,2,24,3,25,2,26,2,27,2,28,2,29,1,242,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,2,42,1,241,0,43,2,45,2,46,2,47,2,48,2,49,4,30,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,2,62,2,63,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,18,82,18,83,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,138,1,139,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,11,159,1,243,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 Rewards() = [0.0]
 Returns() = [0.0]
 LegalActions() = [0, 1, 2, 3, 4]
 StringLegalActions() = ["none", "up", "right", "down", "left"]
 
-# Apply action "up"
-action: 1
+# Apply action "left"
+action: 4
 
 # State 3
 # chance node
 IsTerminal() = False
-History() = [4, 0, 1]
-HistoryString() = "4, 0, 1"
+History() = [2, 0, 4]
+HistoryString() = "2, 0, 4"
 IsChanceNode() = True
 IsSimultaneousNode() = False
 CurrentPlayer() = -1
@@ -480,7 +480,7 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,598,140,0,38,0,20,5,1,4,0,0,0,0,243,-1\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,3,2,2,3,2,2,2,2,1,2,2,2,2,2,3,2,2,2,19\n19,0,1,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,19\n19,2,2,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,1,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,11,1,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,598,140,0,38,0,20,5,1,4,0,0,0,0,244,-1\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,3,22,2,23,2,24,3,25,2,26,2,27,2,28,2,29,1,242,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,2,42,0,43,1,244,2,45,2,46,2,47,2,48,2,49,4,30,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,2,62,2,63,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,18,82,18,83,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,138,1,139,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,11,159,1,243,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 ChanceOutcomes() = [(0, 1.0)]
 LegalActions() = [0]
 StringLegalActions() = ["Chance outcome: 0"]
@@ -491,7 +491,7 @@ action: 0
 # State 4
 # SSSSSSSSSSSSSSSSSSSS
 # So..o.... .....o...S
-# S@ ......o.........S
+# S.@ .....o.........S
 # S...*......o.......S
 # SHHHHHHHHHHHHH...o.S
 # S.....*............S
@@ -503,16 +503,16 @@ action: 0
 # SSSSSSSSSSSSSSSSSSSS
 # time left: 598, gems required: 4, gems collectred: 0
 IsTerminal() = False
-History() = [4, 0, 1, 0]
-HistoryString() = "4, 0, 1, 0"
+History() = [2, 0, 4, 0]
+HistoryString() = "2, 0, 4, 0"
 IsChanceNode() = False
 IsSimultaneousNode() = False
 CurrentPlayer() = 0
-ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nSo..o.... .....o...S\nS@ ......o.........S\nS...*......o.......S\nSHHHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o..  S\nS..o...o.........F S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 598, gems required: 4, gems collectred: 0"
+ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nSo..o.... .....o...S\nS.@ .....o.........S\nS...*......o.......S\nSHHHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o..  S\nS..o...o.........F S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 598, gems required: 4, gems collectred: 0"
 ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◉◉◯◉◉◉◉◯◉◉◉◉◉◯◉◉◉◯  ◯◉◯◯◉◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
+◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◯◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◉◉◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯  ◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◉◉◯◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯
@@ -600,7 +600,7 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,598,140,0,38,0,20,5,1,4,0,0,0,0,243,0\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,3,2,2,3,2,2,2,2,1,2,2,2,2,2,3,2,2,2,19\n19,0,1,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,19\n19,2,2,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,18,18,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,1,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,10,1,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,598,140,0,38,0,20,5,1,4,0,0,0,0,244,0\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,3,22,2,23,2,24,3,25,2,26,2,27,2,28,2,29,1,242,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,2,42,0,43,1,244,2,45,2,46,2,47,2,48,2,49,3,30,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,2,62,2,63,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,18,82,18,83,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,138,1,139,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,10,159,1,243,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 Rewards() = [0.0]
 Returns() = [0.0]
 LegalActions() = [0, 1, 2, 3, 4]
@@ -614,25 +614,33 @@ action: 0
 action: 0
 
 # State 6
-# Apply action "down"
-action: 3
+# Apply action "left"
+action: 4
 
 # State 7
 # Apply action "Chance outcome: 0"
 action: 0
 
 # State 8
-# Apply action "left"
-action: 4
+# Apply action "down"
+action: 3
 
 # State 9
 # Apply action "Chance outcome: 0"
 action: 0
 
 # State 10
+# Apply action "none"
+action: 0
+
+# State 11
+# Apply action "Chance outcome: 0"
+action: 0
+
+# State 12
 # SSSSSSSSSSSSSSSSSSSS
 # S ..o.... .....o...S
-# SEE......o.........S
+# SEE .....o.........S
 # SEE.*......o.......S
 # SEEHHHHHHHHHHH...o.S
 # S.....*............S
@@ -642,18 +650,18 @@ action: 0
 # S..*......*o..o..o.S
 # S.............o....C
 # SSSSSSSSSSSSSSSSSSSS
-# time left: 595, gems required: 4, gems collectred: 0
+# time left: 594, gems required: 4, gems collectred: 0
 IsTerminal() = True
-History() = [4, 0, 1, 0, 0, 0, 3, 0, 4, 0]
-HistoryString() = "4, 0, 1, 0, 0, 0, 3, 0, 4, 0"
+History() = [2, 0, 4, 0, 0, 0, 4, 0, 3, 0, 0, 0]
+HistoryString() = "2, 0, 4, 0, 0, 0, 4, 0, 3, 0, 0, 0"
 IsChanceNode() = False
 IsSimultaneousNode() = False
 CurrentPlayer() = -4
-ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nS ..o.... .....o...S\nSEE......o.........S\nSEE.*......o.......S\nSEEHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o.. FS\nS..o...o.........  S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 595, gems required: 4, gems collectred: 0"
+ObservationString(0) = "SSSSSSSSSSSSSSSSSSSS\nS ..o.... .....o...S\nSEE .....o.........S\nSEE.*......o.......S\nSEEHHHHHHHHHHH...o.S\nS.....*............S\nS..o.......*..o.. FS\nS..o...o.........  S\nS.....HHHHHHHHHHHHHS\nS..*......*o..o..o.S\nS.............o....C\nSSSSSSSSSSSSSSSSSSSS\ntime left: 594, gems required: 4, gems collectred: 0"
 ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◉◉◯◉◉◉◉◯◉◉◉◉◉◯◉◉◉◯  ◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
+◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◉◯◉◉◉◉◉◉◯◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯  ◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◉◉◯◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◉◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◉◉◉◉◉◯◉◉◉◉◉◉◉◉◉◉◉◉◯  ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯  ◯◯◯◯◯◯◉◯◯◯◯◯◯◯◯◯◯◯◯◯
@@ -741,6 +749,6 @@ ObservationTensor(0):
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
 ◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯◯
-SerializeState() = "20,12,595,140,0,38,0,20,5,1,4,0,0,0,0,253,0\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19\n19,1,2,2,3,2,2,2,2,1,2,2,2,2,2,3,2,2,2,19\n19,26,26,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,19\n19,26,26,2,5,2,2,2,2,2,2,3,2,2,2,2,2,2,2,19\n19,26,26,18,18,18,18,18,18,18,18,18,18,18,2,2,2,3,2,19\n19,2,2,2,2,2,5,2,2,2,2,2,2,2,2,2,2,2,2,19\n19,2,2,3,2,2,2,2,2,2,2,5,2,2,3,2,2,1,13,19\n19,2,2,3,2,2,2,3,2,2,2,2,2,2,2,2,2,1,1,19\n19,2,2,2,2,2,18,18,18,18,18,18,18,18,18,18,18,18,18,19\n19,2,2,5,2,2,2,2,2,2,5,3,2,2,3,2,2,3,2,19\n19,2,2,2,2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,7\n19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19"
+SerializeState() = "20,12,594,140,0,38,0,20,5,1,4,0,0,0,0,255,0\n19,1,19,2,19,3,19,4,19,5,19,6,19,7,19,8,19,9,19,10,19,11,19,12,19,13,19,14,19,15,19,16,19,17,19,18,19,19,19,20\n19,21,1,248,2,23,2,24,3,25,2,26,2,27,2,28,2,29,1,242,2,31,2,32,2,33,2,34,2,35,3,36,2,37,2,38,2,39,19,40\n19,41,26,251,26,254,1,244,2,45,2,46,2,47,2,48,2,49,3,30,2,51,2,52,2,53,2,54,2,55,2,56,2,57,2,58,2,59,19,60\n19,61,26,250,26,252,2,64,5,65,2,66,2,67,2,68,2,69,2,70,2,71,3,72,2,73,2,74,2,75,2,76,2,77,2,78,2,79,19,80\n19,81,26,253,26,255,18,84,18,85,18,86,18,87,18,88,18,89,18,90,18,91,18,92,18,93,18,94,2,95,2,96,2,97,3,98,2,99,19,100\n19,101,2,102,2,103,2,104,2,105,2,106,5,107,2,108,2,109,2,110,2,111,2,112,2,113,2,114,2,115,2,116,2,117,2,118,2,119,19,120\n19,121,2,122,2,123,3,124,2,125,2,126,2,127,2,128,2,129,2,130,2,131,5,132,2,133,2,134,3,135,2,136,2,137,1,249,12,159,19,140\n19,141,2,142,2,143,3,144,2,145,2,146,2,147,3,148,2,149,2,150,2,151,2,152,2,153,2,154,2,155,2,156,2,157,1,245,1,243,19,160\n19,161,2,162,2,163,2,164,2,165,2,166,18,167,18,168,18,169,18,170,18,171,18,172,18,173,18,174,18,175,18,176,18,177,18,178,18,179,19,180\n19,181,2,182,2,183,5,184,2,185,2,186,2,187,2,188,2,189,2,190,5,191,3,192,2,193,2,194,3,195,2,196,2,197,3,198,2,199,19,200\n19,201,2,202,2,203,2,204,2,205,2,206,2,207,2,208,2,209,2,210,2,211,2,212,2,213,2,214,3,215,2,216,2,217,2,218,2,219,7,220\n19,221,19,222,19,223,19,224,19,225,19,226,19,227,19,228,19,229,19,230,19,231,19,232,19,233,19,234,19,235,19,236,19,237,19,238,19,239,19,240"
 Rewards() = [0.0]
 Returns() = [0.0]