From bd36847919b9ef5525fab398eccfb845eff3130e Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Sun, 23 Mar 2025 15:40:06 -0500 Subject: [PATCH 01/12] logic to calculate unreachables based on lookahead logic --- src/cell_tree_agent.hpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index d55f395..01cfae2 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -73,6 +73,28 @@ Dir move_to_parent(Grid const& cell_parents, Coord a) { throw "move_to_parent"; } +Unreachables& get_unreachables_from_lookahead( + const GameBase& game, + const std::vector& path, + Lookahead lookahead, + const Grid& dists) { + if (lookahead == Lookahead::many_move_tail) { + auto after_move_tail = after_moves(game, path, Lookahead::many_move_tail); + auto unreachable_move_tail = cell_tree_unreachables(after_move_tail, dists); + + if (!unreachable_move_tail.any) { + return unreachable_move_tail; + } else { + auto after_keep_tail = after_moves(game, path, Lookahead::many_keep_tail); + auto unreachable_keep_tail = cell_tree_unreachables(after_keep_tail, dists); + return unreachable_keep_tail; + } + } else { + auto after = after_moves(game, path, lookahead); + auto unreachable = cell_tree_unreachables(after, dists); + return unreachable; + } +} Unreachables cell_tree_unreachables(GameBase const& game, Grid const& dists) { auto cell_parents = cell_tree_parents(game.dimensions(), game.snake); @@ -156,9 +178,9 @@ struct CellTreeAgent : Agent { } // Heuristic 3: prevent making parts of the grid unreachable - if (detour != DetourStrategy::none) { - auto after = after_moves(game, path, lookahead); - auto unreachable = cell_tree_unreachables(after, dists); + if (detour != DetourStrategy::none) { + const Unreachables& unreachable = get_unreachables_from_lookahead(game, path, lookahead, dists); + if (unreachable.any) { if (log) { Grid unreachable_grid(game.dimensions()); From fecd038cca21abc7ce2cc35f9116de366448ed3b Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Thu, 10 Apr 2025 00:11:18 -0500 Subject: [PATCH 02/12] get it to compile on macos --- src/game_util.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game_util.hpp b/src/game_util.hpp index 5a38ffc..c9e1949 100644 --- a/src/game_util.hpp +++ b/src/game_util.hpp @@ -171,7 +171,7 @@ Grid random_spanning_tree(CoordRange dims, RNG& rng) { } } while (!queue.empty()) { - int i = rng.random(queue.size()); + int i = rng.random(static_cast(queue.size())); Coord parent = queue[i].first; Coord node = queue[i].second; queue[i] = queue.back(); From 08df74f05eb0b69d57c1826ca781745f649ee6d9 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Mon, 5 May 2025 15:17:09 -0500 Subject: [PATCH 03/12] bugfix to report game count in verbose mode --- src/snake.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/snake.cpp b/src/snake.cpp index e510ed1..575ec92 100644 --- a/src/snake.cpp +++ b/src/snake.cpp @@ -449,7 +449,7 @@ Stats play_multiple_threaded(AgentGen make_agent, Config& config) { t.join(); } // done - if (!config.quiet) std::cout << "\033[K\r"; + if (!config.quiet) std::cout << std::endl; return stats; } @@ -467,7 +467,7 @@ Stats play_multiple(AgentGen make_agent, Config& config) { std::cout << (i+1) << "/" << config.num_rounds << " " << stats << "\033[K\r" << std::flush; } } - if (!config.quiet) std::cout << "\033[K\r"; + if (!config.quiet) std::cout << std::endl; return stats; } From a0e97c7a01c897fe17762d354373c6eeaeeba5ae Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Tue, 6 May 2025 09:50:18 -0500 Subject: [PATCH 04/12] gitignore --- .gitignore | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitignore b/.gitignore index 9192c68..5261d75 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ build/ ideas/ +*.json +*.exe +.vscode/ +*.log +.DS_Store +.github/ From 58a081389f9069a62a41bc6720433fa336e8e719 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Tue, 13 May 2025 10:58:32 -0500 Subject: [PATCH 05/12] add dist to farthest member --- src/game_util.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/game_util.hpp b/src/game_util.hpp index c9e1949..f9e0aab 100644 --- a/src/game_util.hpp +++ b/src/game_util.hpp @@ -43,7 +43,9 @@ GameBase after_moves(GameBase const& game, std::vector const& path, Looka struct Unreachables { bool any = false; Coord nearest = {-1,-1}; + Coord farthest = {-1,-1}; int dist_to_nearest = INT_MAX; + int dist_to_farthest = 0; Grid reachable; Unreachables(Grid const& reachable) @@ -68,6 +70,10 @@ Unreachables unreachables(CanMove can_move, GameLike const& game, Grid con out.nearest = a; out.dist_to_nearest = dists[a].dist; } + if (dists[a].dist > out.dist_to_farthest) { // track the farthest unreachable coordinate + out.farthest = a; + out.dist_to_farthest = dists[a].dist; + } } } return out; From b2c2aea87382be42a9e053cb1cca8354b1d9f241 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 09:46:07 -0500 Subject: [PATCH 06/12] should use cached path for move tail --- src/cell_tree_agent.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index 01cfae2..fb36796 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -104,6 +104,15 @@ Unreachables cell_tree_unreachables(GameBase const& game, Grid const& dist return unreachables(can_move, game, dists); } +bool should_use_cached_path_for_move_tail(const Unreachables& unreachable, Lookahead lookahead, const std::vector& cached_path) { + if (lookahead == Lookahead::many_move_tail) { + if ((unreachable.any) && (unreachable.dist_to_farthest >= INT_MAX) && !cached_path.empty()) { + return true; + } + } + return false; +} + enum class DetourStrategy { none, any, @@ -180,6 +189,11 @@ struct CellTreeAgent : Agent { // Heuristic 3: prevent making parts of the grid unreachable if (detour != DetourStrategy::none) { const Unreachables& unreachable = get_unreachables_from_lookahead(game, path, lookahead, dists); + if (should_use_cached_path_for_move_tail(unreachable, lookahead, cached_path)) { + pos2 = cached_path.back(); + cached_path.pop_back(); + return pos2 - pos; + } if (unreachable.any) { if (log) { From db9ba696f6ae08e0803af5742d3d3a2f6d9b8e81 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 09:53:57 -0500 Subject: [PATCH 07/12] reorder some functions and dont use reference for Unreachables --- src/cell_tree_agent.hpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index fb36796..2f10484 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -73,7 +73,24 @@ Dir move_to_parent(Grid const& cell_parents, Coord a) { throw "move_to_parent"; } -Unreachables& get_unreachables_from_lookahead( +Unreachables cell_tree_unreachables(GameBase const& game, Grid const& dists) { + auto cell_parents = cell_tree_parents(game.dimensions(), game.snake); + auto can_move = [&](Coord from, Coord to, Dir dir) { + return can_move_in_cell_tree(cell_parents, from, to, dir) && !game.grid[to]; + }; + return unreachables(can_move, game, dists); +} + +bool should_use_cached_path_for_move_tail(const Unreachables& unreachable, Lookahead lookahead, const std::vector& cached_path) { + if (lookahead == Lookahead::many_move_tail) { + if ((unreachable.any) && (unreachable.dist_to_farthest >= INT_MAX) && !cached_path.empty()) { + return true; + } + } + return false; +} + +Unreachables get_unreachables_from_lookahead( const GameBase& game, const std::vector& path, Lookahead lookahead, @@ -96,23 +113,6 @@ Unreachables& get_unreachables_from_lookahead( } } -Unreachables cell_tree_unreachables(GameBase const& game, Grid const& dists) { - auto cell_parents = cell_tree_parents(game.dimensions(), game.snake); - auto can_move = [&](Coord from, Coord to, Dir dir) { - return can_move_in_cell_tree(cell_parents, from, to, dir) && !game.grid[to]; - }; - return unreachables(can_move, game, dists); -} - -bool should_use_cached_path_for_move_tail(const Unreachables& unreachable, Lookahead lookahead, const std::vector& cached_path) { - if (lookahead == Lookahead::many_move_tail) { - if ((unreachable.any) && (unreachable.dist_to_farthest >= INT_MAX) && !cached_path.empty()) { - return true; - } - } - return false; -} - enum class DetourStrategy { none, any, @@ -188,7 +188,7 @@ struct CellTreeAgent : Agent { // Heuristic 3: prevent making parts of the grid unreachable if (detour != DetourStrategy::none) { - const Unreachables& unreachable = get_unreachables_from_lookahead(game, path, lookahead, dists); + const Unreachables unreachable = get_unreachables_from_lookahead(game, path, lookahead, dists); if (should_use_cached_path_for_move_tail(unreachable, lookahead, cached_path)) { pos2 = cached_path.back(); cached_path.pop_back(); From c87b758cb817b8c0c5c2b3db25a119b250e9cb18 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 10:09:51 -0500 Subject: [PATCH 08/12] fix this as it should be 20x20 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 350c479..5d80de0 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Currently does not include "nascar" or "applefear" modes. ## Results -Number of steps to finish the game on a 30×30 grid (over 100 runs) +Number of steps to finish the game on a 20×20 grid (over 100 runs) |agent |mean |stddev |min |q.25 |median |q.75 |max |lost | |---------------|---------|---------|---------|---------|---------|---------|---------|----------| From 7248ff40d064d4cb0ca860e1f827653f3a8c7edb Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 10:11:34 -0500 Subject: [PATCH 09/12] variable naming --- src/cell_tree_agent.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index 2f10484..1ea9cb2 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -96,11 +96,11 @@ Unreachables get_unreachables_from_lookahead( Lookahead lookahead, const Grid& dists) { if (lookahead == Lookahead::many_move_tail) { - auto after_move_tail = after_moves(game, path, Lookahead::many_move_tail); - auto unreachable_move_tail = cell_tree_unreachables(after_move_tail, dists); + auto after = after_moves(game, path, Lookahead::many_move_tail); + auto unreachable = cell_tree_unreachables(after, dists); - if (!unreachable_move_tail.any) { - return unreachable_move_tail; + if (!unreachable.any) { + return unreachable; } else { auto after_keep_tail = after_moves(game, path, Lookahead::many_keep_tail); auto unreachable_keep_tail = cell_tree_unreachables(after_keep_tail, dists); From 539544877d246959f304743f185b448a16f49bab Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 10:13:37 -0500 Subject: [PATCH 10/12] more variable naming --- src/cell_tree_agent.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index 1ea9cb2..9edfb36 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -102,9 +102,9 @@ Unreachables get_unreachables_from_lookahead( if (!unreachable.any) { return unreachable; } else { - auto after_keep_tail = after_moves(game, path, Lookahead::many_keep_tail); - auto unreachable_keep_tail = cell_tree_unreachables(after_keep_tail, dists); - return unreachable_keep_tail; + auto after = after_moves(game, path, Lookahead::many_keep_tail); + auto unreachable = cell_tree_unreachables(after, dists); + return unreachable; } } else { auto after = after_moves(game, path, lookahead); From 4e810219cf17bc5e1ab0a8d6192a2e021db29c69 Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Wed, 14 May 2025 11:42:00 -0500 Subject: [PATCH 11/12] method rename --- src/cell_tree_agent.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cell_tree_agent.hpp b/src/cell_tree_agent.hpp index 9edfb36..00f9068 100644 --- a/src/cell_tree_agent.hpp +++ b/src/cell_tree_agent.hpp @@ -90,7 +90,7 @@ bool should_use_cached_path_for_move_tail(const Unreachables& unreachable, Looka return false; } -Unreachables get_unreachables_from_lookahead( +Unreachables get_unreachables( const GameBase& game, const std::vector& path, Lookahead lookahead, @@ -188,7 +188,7 @@ struct CellTreeAgent : Agent { // Heuristic 3: prevent making parts of the grid unreachable if (detour != DetourStrategy::none) { - const Unreachables unreachable = get_unreachables_from_lookahead(game, path, lookahead, dists); + const Unreachables unreachable = get_unreachables(game, path, lookahead, dists); if (should_use_cached_path_for_move_tail(unreachable, lookahead, cached_path)) { pos2 = cached_path.back(); cached_path.pop_back(); From 8d1759dd0ce5150d07edb6ca25cb6b5261f5938d Mon Sep 17 00:00:00 2001 From: Hasan Haq Date: Sat, 17 May 2025 10:12:59 -0500 Subject: [PATCH 12/12] Revert "fix this as it should be 20x20" This reverts commit c87b758cb817b8c0c5c2b3db25a119b250e9cb18. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d80de0..350c479 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Currently does not include "nascar" or "applefear" modes. ## Results -Number of steps to finish the game on a 20×20 grid (over 100 runs) +Number of steps to finish the game on a 30×30 grid (over 100 runs) |agent |mean |stddev |min |q.25 |median |q.75 |max |lost | |---------------|---------|---------|---------|---------|---------|---------|---------|----------|