diff --git a/GenerateCases/GenerateCases.sln b/GenerateCases/GenerateCases.sln new file mode 100644 index 0000000..4c9e47a --- /dev/null +++ b/GenerateCases/GenerateCases.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenerateCases", "GenerateCases\GenerateCases.csproj", "{9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3}.Debug|x86.ActiveCfg = Debug|x86 + {9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3}.Debug|x86.Build.0 = Debug|x86 + {9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3}.Release|x86.ActiveCfg = Release|x86 + {9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GenerateCases/GenerateCases.suo b/GenerateCases/GenerateCases.suo new file mode 100644 index 0000000..62e0e84 Binary files /dev/null and b/GenerateCases/GenerateCases.suo differ diff --git a/GenerateCases/GenerateCases/GenerateCases.csproj b/GenerateCases/GenerateCases/GenerateCases.csproj new file mode 100644 index 0000000..19a9724 --- /dev/null +++ b/GenerateCases/GenerateCases/GenerateCases.csproj @@ -0,0 +1,57 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {9DFB7EEF-7262-4F0E-9812-E9283CA9C9A3} + Exe + Properties + GenerateCases + GenerateCases + v4.0 + Client + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GenerateCases/GenerateCases/Program.cs b/GenerateCases/GenerateCases/Program.cs new file mode 100644 index 0000000..f5e2c4e --- /dev/null +++ b/GenerateCases/GenerateCases/Program.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace GenerateCases +{ + public enum Dir + { + Down = 0, + DownRight = 1, + Right = 2, + UpRight = 3, + Up = 4, + UpLeft = 5, + Left = 6, + DownLeft = 7, + All = 8 + }; + + class Program + { + static void Main(string[] args) + { + using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"Cases.h")) + + for (int bits = 0; bits < 256; ++bits) + { + file.WriteLine("CASE(" + TranslateDown(Down(bits)) + ")"); + file.WriteLine("CASE(" + TranslateDownRight(DownRight(bits)) + ")"); + file.WriteLine("CASE(" + TranslateRight(Right(bits)) + ")"); + file.WriteLine("CASE(" + TranslateUpRight(UpRight(bits)) + ")"); + file.WriteLine("CASE(" + TranslateUp(Up(bits)) + ")"); + file.WriteLine("CASE(" + TranslateUpLeft(UpLeft(bits)) + ")"); + file.WriteLine("CASE(" + TranslateLeft(Left(bits)) + ")"); + file.WriteLine("CASE(" + TranslateDownLeft(DownLeft(bits)) + ")"); + } + + } + + static bool Blocked(int bits, Dir dir) + { + return (((bits) & (1 << (int)dir)) > 0); + } + + static bool Empty(int bits, Dir dir) + { + return !Blocked(bits, dir); + } + + static string Down(int bits) + { + Dir primaryDir = Dir.Down; + bool straight = Empty(bits, Dir.Down); + bool leftForcedNeighbor = Blocked(bits, Dir.UpRight) && Empty(bits, Dir.Right); + bool rightForcedNeighbor = Blocked(bits, Dir.UpLeft) && Empty(bits, Dir.Left); + bool leftForcedDiagonal = leftForcedNeighbor && straight && Empty(bits, Dir.DownRight); + bool rightForcedDiagonal = rightForcedNeighbor && straight && Empty(bits, Dir.DownLeft); + + return GetCardinalVariation( + bits, + primaryDir, + straight, + leftForcedNeighbor, + rightForcedNeighbor, + leftForcedDiagonal, + rightForcedDiagonal); + } + + static string Right(int bits) + { + Dir primaryDir = Dir.Right; + bool straight = Empty(bits, Dir.Right); + bool leftForcedNeighbor = Blocked(bits, Dir.UpLeft) && Empty(bits, Dir.Up); + bool rightForcedNeighbor = Blocked(bits, Dir.DownLeft) && Empty(bits, Dir.Down); + bool leftForcedDiagonal = leftForcedNeighbor && straight && Empty(bits, Dir.UpRight); + bool rightForcedDiagonal = rightForcedNeighbor && straight && Empty(bits, Dir.DownRight); + + return GetCardinalVariation( + bits, + primaryDir, + straight, + leftForcedNeighbor, + rightForcedNeighbor, + leftForcedDiagonal, + rightForcedDiagonal); + } + + static string Up(int bits) + { + Dir primaryDir = Dir.Up; + bool straight = Empty(bits, Dir.Up); + bool leftForcedNeighbor = Blocked(bits, Dir.DownLeft) && Empty(bits, Dir.Left); + bool rightForcedNeighbor = Blocked(bits, Dir.DownRight) && Empty(bits, Dir.Right); + bool leftForcedDiagonal = leftForcedNeighbor && straight && Empty(bits, Dir.UpLeft); + bool rightForcedDiagonal = rightForcedNeighbor && straight && Empty(bits, Dir.UpRight); + + return GetCardinalVariation( + bits, + primaryDir, + straight, + leftForcedNeighbor, + rightForcedNeighbor, + leftForcedDiagonal, + rightForcedDiagonal); + } + + static string Left(int bits) + { + Dir primaryDir = Dir.Left; + bool straight = Empty(bits, Dir.Left); + bool leftForcedNeighbor = Blocked(bits, Dir.DownRight) && Empty(bits, Dir.Down); + bool rightForcedNeighbor = Blocked(bits, Dir.UpRight) && Empty(bits, Dir.Up); + bool leftForcedDiagonal = leftForcedNeighbor && straight && Empty(bits, Dir.DownLeft); + bool rightForcedDiagonal = rightForcedNeighbor && straight && Empty(bits, Dir.UpLeft); + + return GetCardinalVariation( + bits, + primaryDir, + straight, + leftForcedNeighbor, + rightForcedNeighbor, + leftForcedDiagonal, + rightForcedDiagonal); + } + + static string GetCardinalVariation( + int bits, + Dir dir, + bool straight, + bool leftForcedNeighbor, + bool rightForcedNeighbor, + bool leftForcedDiagonal, + bool rightForcedDiagonal) + { + string pre = ""; + + if (straight && !leftForcedNeighbor && !rightForcedNeighbor) + { + return pre + "XX2XX"; + } + else if (!straight && leftForcedNeighbor && !rightForcedNeighbor) + { + return pre + "0XXXX"; + } + else if (!straight && !leftForcedNeighbor && rightForcedNeighbor) + { + return pre + "XXXX4"; + } + else if (leftForcedDiagonal && !rightForcedNeighbor) + { + return pre + "012XX"; + } + else if (rightForcedDiagonal && !leftForcedNeighbor) + { + return pre + "XX234"; + } + else if (leftForcedDiagonal && rightForcedDiagonal) + { + return pre + "01234"; + } + else if (straight && leftForcedNeighbor && !rightForcedNeighbor && !leftForcedDiagonal) + { + return pre + "0X2XX"; + } + else if (straight && !leftForcedNeighbor && rightForcedNeighbor && !rightForcedDiagonal) + { + return pre + "XX2X4"; + } + else if (!straight && leftForcedNeighbor && rightForcedNeighbor) + { + return pre + "0XXX4"; + } + else if (straight && leftForcedNeighbor && rightForcedNeighbor && !leftForcedDiagonal && !rightForcedDiagonal) + { + return pre + "0X2X4"; + } + else if (straight && leftForcedNeighbor && rightForcedNeighbor && leftForcedDiagonal && !rightForcedDiagonal) + { + return pre + "012X4"; + } + else if (straight && leftForcedNeighbor && rightForcedNeighbor && !leftForcedDiagonal && rightForcedDiagonal) + { + return pre + "0X234"; + } + else + { + return pre + "XXXXX"; + } + } + + static string DownRight(int bits) + { + Dir primaryDir = Dir.DownRight; + bool leftish = Empty(bits, Dir.Right); + bool rightish = Empty(bits, Dir.Down); + bool straight = leftish && rightish && Empty(bits, Dir.DownRight); + + return GetDiagonalVariation( + primaryDir, + straight, + leftish, + rightish); + } + + static string UpRight(int bits) + { + Dir primaryDir = Dir.UpRight; + bool leftish = Empty(bits, Dir.Up); + bool rightish = Empty(bits, Dir.Right); + bool straight = leftish && rightish && Empty(bits, Dir.UpRight); + + return GetDiagonalVariation( + primaryDir, + straight, + leftish, + rightish); + } + + static string UpLeft(int bits) + { + Dir primaryDir = Dir.UpLeft; + bool leftish = Empty(bits, Dir.Left); + bool rightish = Empty(bits, Dir.Up); + bool straight = leftish && rightish && Empty(bits, Dir.UpLeft); + + return GetDiagonalVariation( + primaryDir, + straight, + leftish, + rightish); + } + + static string DownLeft(int bits) + { + Dir primaryDir = Dir.DownLeft; + bool leftish = Empty(bits, Dir.Down); + bool rightish = Empty(bits, Dir.Left); + bool straight = leftish && rightish && Empty(bits, Dir.DownLeft); + + return GetDiagonalVariation( + primaryDir, + straight, + leftish, + rightish); + } + + static string GetDiagonalVariation( + Dir dir, + bool straight, + bool leftish, + bool rightish) + { + string pre = ""; + + if (leftish && !rightish) + { + return pre + "0XX"; + } + else if (!leftish && rightish) + { + return pre + "XX2"; + } + else if (straight) + { + return pre + "012"; + } + else if (leftish && rightish && !straight) + { + return pre + "0X2"; + } + else + { + return pre + "XXX"; + } + } + + static string TranslateDown(string input) + { + if (input == "XX2XX") return "D"; + if (input == "0XXXX") return "R"; + if (input == "XXXX4") return "L"; + if (input == "0X2XX") return "D_R"; + if (input == "XX2X4") return "L_D"; + if (input == "0XXX4") return "R_L"; + if (input == "012XX") return "D_DR_R"; + if (input == "XX234") return "L_DL_D"; + if (input == "0X2X4") return "L_D_R"; + if (input == "012X4") return "R_DR_D_L"; + if (input == "0X234") return "R_D_DL_L"; + if (input == "01234") return "R_DR_D_DL_L"; + if (input == "XXXXX") return "Null"; + return "Null"; + } + + static string TranslateDownRight(string input) + { + if (input == "0XX") return "R"; + if (input == "XX2") return "D"; + if (input == "0X2") return "D_R"; + if (input == "012") return "D_DR_R"; + if (input == "XXX") return "Null"; + return "Null"; + } + + static string TranslateRight(string input) + { + if (input == "XX2XX") return "R"; + if (input == "0XXXX") return "U"; + if (input == "XXXX4") return "D"; + if (input == "0X2XX") return "R_U"; + if (input == "XX2X4") return "D_R"; + if (input == "0XXX4") return "D_U"; + if (input == "012XX") return "R_UR_U"; + if (input == "XX234") return "D_DR_R"; + if (input == "0X2X4") return "D_R_U"; + if (input == "012X4") return "U_UR_R_D"; + if (input == "0X234") return "U_R_DR_D"; + if (input == "01234") return "U_UR_R_DR_D"; + if (input == "XXXXX") return "Null"; + return "Null"; + } + + static string TranslateUpRight(string input) + { + if (input == "0XX") return "U"; + if (input == "XX2") return "R"; + if (input == "0X2") return "R_U"; + if (input == "012") return "R_UR_U"; + if (input == "XXX") return "Null"; + return "Null"; + } + + static string TranslateUp(string input) + { + if (input == "XX2XX") return "U"; + if (input == "0XXXX") return "L"; + if (input == "XXXX4") return "R"; + if (input == "0X2XX") return "U_L"; + if (input == "XX2X4") return "R_U"; + if (input == "0XXX4") return "R_L"; + if (input == "012XX") return "U_UL_L"; + if (input == "XX234") return "R_UR_U"; + if (input == "0X2X4") return "R_U_L"; + if (input == "012X4") return "L_UL_U_R"; + if (input == "0X234") return "L_U_UR_R"; + if (input == "01234") return "L_UL_U_UR_R"; + if (input == "XXXXX") return "Null"; + return "Null"; + } + + static string TranslateUpLeft(string input) + { + if (input == "0XX") return "L"; + if (input == "XX2") return "U"; + if (input == "0X2") return "U_L"; + if (input == "012") return "U_UL_L"; + if (input == "XXX") return "Null"; + return "Null"; + } + + static string TranslateLeft(string input) + { + if (input == "XX2XX") return "L"; + if (input == "0XXXX") return "D"; + if (input == "XXXX4") return "U"; + if (input == "0X2XX") return "L_D"; + if (input == "XX2X4") return "U_L"; + if (input == "0XXX4") return "D_U"; + if (input == "012XX") return "L_DL_D"; + if (input == "XX234") return "U_UL_L"; + if (input == "0X2X4") return "U_L_D"; + if (input == "012X4") return "D_DL_L_U"; + if (input == "0X234") return "D_L_UL_U"; + if (input == "01234") return "D_DL_L_UL_U"; + if (input == "XXXXX") return "Null"; + return "Null"; + } + + static string TranslateDownLeft(string input) + { + if (input == "0XX") return "D"; + if (input == "XX2") return "L"; + if (input == "0X2") return "L_D"; + if (input == "012") return "L_DL_D"; + if (input == "XXX") return "Null"; + return "Null"; + } + + + } +} diff --git a/GenerateCases/GenerateCases/Properties/AssemblyInfo.cs b/GenerateCases/GenerateCases/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fdf06b4 --- /dev/null +++ b/GenerateCases/GenerateCases/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GenerateCases")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("GenerateCases")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("520a70d7-e42b-4bd5-9757-db6184c3a683")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/JPSPlusGoalBounding/BucketPriorityQueue.cpp b/JPSPlusGoalBounding/BucketPriorityQueue.cpp new file mode 100644 index 0000000..7be585e --- /dev/null +++ b/JPSPlusGoalBounding/BucketPriorityQueue.cpp @@ -0,0 +1,166 @@ +/* + * BucketPriorityQueue.cpp + * + * Copyright (c) 2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "BucketPriorityQueue.h" +#include "UnsortedPriorityQueue.h" + +BucketPriorityQueue::BucketPriorityQueue(int buckets, int arraySize, unsigned int division) +{ + m_numBuckets = buckets; + m_division = division; + + Reset(); + + // Allocate a bunch of free buckets + m_maxFreeBuckets = 200; + m_nextFreeBucket = 0; + m_freeBuckets = new UnsortedPriorityQueue*[m_maxFreeBuckets]; + for (int m = 0; m < m_maxFreeBuckets; m++) + { + m_freeBuckets[m] = new UnsortedPriorityQueue(arraySize); + } + + // Allocate bucket slots + m_bin = new UnsortedPriorityQueue*[m_numBuckets]; + for (int m = 0; m < m_numBuckets; m++) + { + m_bin[m] = 0; + } +} + +BucketPriorityQueue::~BucketPriorityQueue() +{ + for (int m = 0; m < m_maxFreeBuckets; m++) + { + if(m_freeBuckets[m] != 0) + { + delete m_freeBuckets[m]; + } + } + + delete[] m_freeBuckets; + + for (int m = 0; m < m_numBuckets; m++) + { + if(m_bin[m] != 0) + { + delete m_bin[m]; + } + } + + delete[] m_bin; +} + +void BucketPriorityQueue::Push(DijkstraPathfindingNode* node) +{ + m_numNodesTracked++; + int index = GetBinIndex(node->m_givenCost); + + if(m_bin[index] == 0) + { + m_bin[index] = m_freeBuckets[m_nextFreeBucket++]; + } + + m_bin[index]->Push(node); + + if (index < m_lowestNonEmptyBin) + { + m_lowestNonEmptyBin = index; + } +} + +DijkstraPathfindingNode* BucketPriorityQueue::Pop(void) +{ + DijkstraPathfindingNode* node = m_bin[m_lowestNonEmptyBin]->Pop(); + m_numNodesTracked--; + + if(m_bin[m_lowestNonEmptyBin]->Empty(node->m_iteration)) + { + m_freeBuckets[--m_nextFreeBucket] = m_bin[m_lowestNonEmptyBin]; + m_bin[m_lowestNonEmptyBin] = 0; + } + + if (m_numNodesTracked > 0) + { + // Find the next non-empty bin + for (m_lowestNonEmptyBin; m_lowestNonEmptyBin < m_numBuckets; m_lowestNonEmptyBin++) + { + if (m_bin[m_lowestNonEmptyBin] != 0 && + !m_bin[m_lowestNonEmptyBin]->Empty(node->m_iteration)) + { + break; + } + } + } + else + { + m_lowestNonEmptyBin = m_numBuckets; + } + + return node; +} + +void BucketPriorityQueue::DecreaseKey(DijkstraPathfindingNode* node, unsigned int lastCost) +{ + // Remove node + int index = GetBinIndex(lastCost); + m_bin[index]->Remove(node); + + if(m_bin[index]->Empty(node->m_iteration)) + { + m_freeBuckets[--m_nextFreeBucket] = m_bin[index]; + m_bin[index] = 0; + } + + // Push node + index = GetBinIndex(node->m_givenCost); + + if(m_bin[index] == 0) + { + m_bin[index] = m_freeBuckets[m_nextFreeBucket++]; + } + + m_bin[index]->Push(node); + + if (index < m_lowestNonEmptyBin) + { + m_lowestNonEmptyBin = index; + } +} diff --git a/JPSPlusGoalBounding/BucketPriorityQueue.h b/JPSPlusGoalBounding/BucketPriorityQueue.h new file mode 100644 index 0000000..1454f2b --- /dev/null +++ b/JPSPlusGoalBounding/BucketPriorityQueue.h @@ -0,0 +1,75 @@ +/* + * BucketPriorityQueue.h + * + * Copyright (c) 2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "UnsortedPriorityQueue.h" + +// This data structure is dangerous since there are no safeguards if the max size is exceeded. +// However, any method to detect a problem and deal with it gracefully will sacrifice speed. +// The number of buckets can be reduced if the maximum final cost is known to be lower (significant memory savings) +// In this code base, this is only used by the Dijkstra floodfill for Goal Bounding preprocessing. + +class BucketPriorityQueue +{ +public: + BucketPriorityQueue(int buckets, int arraySize, unsigned int division); + ~BucketPriorityQueue(); + + inline void SetBaseCost(unsigned int baseCost) { m_baseCost = baseCost; } + inline void Reset() { m_lowestNonEmptyBin = m_numBuckets; m_numNodesTracked = 0; m_baseCost = 0; } + inline bool Empty() { return m_numNodesTracked == 0; } + void Push(DijkstraPathfindingNode* node); + DijkstraPathfindingNode* Pop(void); + void DecreaseKey(DijkstraPathfindingNode* node, unsigned int lastCost); + +private: + int m_numBuckets; + int m_lowestNonEmptyBin; + int m_numNodesTracked; + unsigned int m_division; + unsigned int m_baseCost; + UnsortedPriorityQueue** m_bin; + + int m_maxFreeBuckets; + int m_nextFreeBucket; + UnsortedPriorityQueue** m_freeBuckets; + + inline int GetBinIndex(unsigned int cost) { return ((cost - m_baseCost) / m_division); } +}; + diff --git a/JPSPlusGoalBounding/Cases.h b/JPSPlusGoalBounding/Cases.h new file mode 100644 index 0000000..2dec775 --- /dev/null +++ b/JPSPlusGoalBounding/Cases.h @@ -0,0 +1,2048 @@ +CASE(D) +CASE(D_DR_R) +CASE(R) +CASE(R_UR_U) +CASE(U) +CASE(U_UL_L) +CASE(L) +CASE(L_DL_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(U) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_R) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U_UL_L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(L) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(R_U) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L_DL_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U_UL_L) +CASE(D_DL_L_UL_U) +CASE(L_DL_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(D_DL_L_UL_U) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D_DR_R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(U_L) +CASE(L) +CASE(L_DL_D) +CASE(L) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D_R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U_L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(L) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(L) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(L) +CASE(L) +CASE(R_DR_D_DL_L) +CASE(D_DR_R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L_DL_D) +CASE(R_L) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(R_D_DL_L) +CASE(D_R) +CASE(R_U) +CASE(R_U) +CASE(R_U) +CASE(U_L) +CASE(D_DL_L_U) +CASE(L_DL_D) +CASE(R_L) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(R_U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(D_DL_L_U) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_DL_D) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(L) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(L) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(R_DR_D_DL_L) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(R_L) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(R_D_DL_L) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(R_L) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_DL_D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L_DL_D) +CASE(L_DL_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_DR_R) +CASE(R) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(R_U) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R_UR_U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(L_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_R) +CASE(D_R) +CASE(R_UR_U) +CASE(L_UL_U_UR_R) +CASE(U_UL_L) +CASE(L_D) +CASE(L_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(L_UL_U_UR_R) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L_D) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(L) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R_U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D_R) +CASE(D_R) +CASE(D_R) +CASE(R_U) +CASE(L_UL_U_R) +CASE(U_UL_L) +CASE(D_L_UL_U) +CASE(L_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(L_UL_U_R) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(D_L_UL_U) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(U_UL_L) +CASE(L) +CASE(D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D_R) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D_DR_R) +CASE(U_UR_R_DR_D) +CASE(R_UR_U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D) +CASE(L) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D_R) +CASE(U_UR_R_D) +CASE(R_UR_U) +CASE(L_U_UR_R) +CASE(U_L) +CASE(L_D) +CASE(L_D) +CASE(L) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(L_U_UR_R) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L_D) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L) +CASE(R_DR_D_L) +CASE(D_DR_R) +CASE(U_R_DR_D) +CASE(R_U) +CASE(U_L) +CASE(U_L) +CASE(U_L) +CASE(L_D) +CASE(R_L) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U_L) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D_R) +CASE(D_R) +CASE(D_R_U) +CASE(R_U) +CASE(R_U_L) +CASE(U_L) +CASE(U_L_D) +CASE(L_D) +CASE(R_L) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(R_U_L) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(U_L) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(U_L_D) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(U) +CASE(U) +CASE(U_L) +CASE(U_L) +CASE(U_L) +CASE(L) +CASE(L_D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(L) +CASE(R) +CASE(R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(R_DR_D_L) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(R_L) +CASE(R) +CASE(R) +CASE(R) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D_R) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(R_L) +CASE(R) +CASE(R) +CASE(R) +CASE(R_L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(L_D) +CASE(D) +CASE(D) +CASE(Null) +CASE(L) +CASE(L) +CASE(L_D) +CASE(L_D) +CASE(L) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(L) +CASE(L) +CASE(L) +CASE(L) +CASE(D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(D_R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(D_R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(U) +CASE(U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(U_UR_R_DR_D) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(U_UR_R_D) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(R_UR_U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(U_R_DR_D) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(D_R_U) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(R) +CASE(R) +CASE(R_U) +CASE(R_U) +CASE(R_U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D) +CASE(D_U) +CASE(U) +CASE(U) +CASE(U) +CASE(D_U) +CASE(D) +CASE(Null) +CASE(Null) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(U) +CASE(Null) +CASE(D) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(D_DR_R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D_R) +CASE(D_R) +CASE(D_R) +CASE(R) +CASE(R) +CASE(Null) +CASE(D) +CASE(D) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(R) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(D) +CASE(D) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) +CASE(Null) diff --git a/JPSPlusGoalBounding/DijkstraFloodfill.cpp b/JPSPlusGoalBounding/DijkstraFloodfill.cpp new file mode 100644 index 0000000..3f71945 --- /dev/null +++ b/JPSPlusGoalBounding/DijkstraFloodfill.cpp @@ -0,0 +1,687 @@ +/* + * DijkstraFloodfill.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "DijkstraFloodfill.h" + +#define ONLY_VISIT_REASONABLE_NEIGHBORS // 3% to 17% speed-up + +#define FIXED_POINT_MULTIPLIER 100000 +#define FIXED_POINT_SHIFT(x) ((x) * FIXED_POINT_MULTIPLIER) +#define FIXED_POINT_ONE FIXED_POINT_MULTIPLIER +#define FIXED_POINT_SQRT_2 141421 + +typedef const void (DijkstraFloodfill::*DijkstraFloodFunctionPointer)(DijkstraPathfindingNode * currentNode); + +DijkstraFloodfill::DijkstraFloodfill(int width, int height, std::vector map, DistantJumpPoints** distantJumpPointMap) +: m_width(width), m_height(height), m_map(map) +{ + m_currentIteration = 1; + +#ifdef USE_FAST_OPEN_LIST + // Number of buckets + const int numberOfBuckets = 300000; // Must be no smaller than longest path divided by "division" + const int nodesInEachBucket = 1000; + const int division = 10000; + m_fastOpenList = new BucketPriorityQueue(numberOfBuckets, nodesInEachBucket, division); +#endif + + // Initialize nodes + InitArray(m_mapNodes, m_width, m_height); + for (int r = 0; rReset(); +#else + m_openList.reset(); + m_openList.reserve(3000); +#endif + + if (IsEmpty(r, c)) + { + // Begin with starting node + DijkstraPathfindingNode* node = &m_mapNodes[r][c]; + node->m_parent = NULL; + node->m_directionFromStart = 255; + node->m_directionFromParent = 255; + node->m_givenCost = 0; + node->m_iteration = m_currentIteration; + node->m_listStatus = PathfindingNode::OnOpen; + + // Explore outward in all directions on the starting node + Explore_AllDirectionsWithChecks(node); + + node->m_listStatus = PathfindingNode::OnClosed; + } + +#ifdef USE_FAST_OPEN_LIST + while (!m_fastOpenList->Empty()) +#else + while (!m_openList.empty()) +#endif + { + +#ifdef USE_FAST_OPEN_LIST + DijkstraPathfindingNode* currentNode = m_fastOpenList->Pop(); +#else + DijkstraPathfindingNode* currentNode = m_openList.remove(); +#endif + + // Explore nodes based on the parent and surrounding walls. + // This must be in the search style of JPS+ in order to produce + // the correct data for JPS+. If goal bounding is used for regular + // A*, then this search would need to mimic regular A*. + (this->*exploreDirectionsDijkstraFlood[(currentNode->m_blockedDirectionBitfield * 8) + + currentNode->m_directionFromParent])(currentNode); + + currentNode->m_listStatus = PathfindingNode::OnClosed; + } +} + +const void DijkstraFloodfill::Explore_AllDirectionsWithChecks(DijkstraPathfindingNode * currentNode) +{ + //DOWN, DOWNRIGHT, RIGHT, UPRIGHT, UP, UPLEFT, LEFT, DOWNLEFT + static const int offsetRow[] = { 1, 1, 0, -1, -1, -1, 0, 1 }; + static const int offsetCol[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; + + for (int i = 0; i < 8; ++i) + { + unsigned int neighborRow = currentNode->m_row + offsetRow[i]; + + // Out of grid bounds? + if (neighborRow >= m_height) + continue; + + unsigned int neighborCol = currentNode->m_col + offsetCol[i]; + + // Out of grid bounds? + if (neighborCol >= m_width) + continue; + + // Valid tile - get the node + DijkstraPathfindingNode* newSuccessor = &m_mapNodes[neighborRow][neighborCol]; + + // Blocked? + if (!m_map[neighborCol + (neighborRow * m_width)]) + continue; + + // Diagonal blocked? + bool isDiagonal = (i & 0x1) == 1; + if (isDiagonal && (!m_map[currentNode->m_col + ((currentNode->m_row + offsetRow[i]) * m_width)] || + !m_map[currentNode->m_col + offsetCol[i] + (currentNode->m_row * m_width)])) + { + continue; + } + + unsigned int costToNextNode = isDiagonal ? FIXED_POINT_SQRT_2 : FIXED_POINT_ONE; + ArrayDirections dir = (ArrayDirections)i; + + PushNewNode(newSuccessor, currentNode, dir, dir, costToNextNode); + } +} + +inline const void DijkstraFloodfill::Explore_Null(DijkstraPathfindingNode * currentNode) +{ + // Purposely does nothing +} + +inline const void DijkstraFloodfill::Explore_D(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DR(DijkstraPathfindingNode * currentNode) +{ + SearchDownRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UR(DijkstraPathfindingNode * currentNode) +{ + SearchUpRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UL(DijkstraPathfindingNode * currentNode) +{ + SearchUpLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DL(DijkstraPathfindingNode * currentNode) +{ + SearchDownLeft(currentNode); +} + +// Adjacent Doubles + +inline const void DijkstraFloodfill::Explore_D_DR(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchDownRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DR_R(DijkstraPathfindingNode * currentNode) +{ + SearchDownRight(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_UR(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchUpRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UR_U(DijkstraPathfindingNode * currentNode) +{ + SearchUpRight(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_UL(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchUpLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UL_L(DijkstraPathfindingNode * currentNode) +{ + SearchUpLeft(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_DL(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchDownLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DL_D(DijkstraPathfindingNode * currentNode) +{ + SearchDownLeft(currentNode); + SearchDown(currentNode); +} + +// Non-Adjacent Cardinal Doubles + +inline const void DijkstraFloodfill::Explore_D_R(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_U(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_L(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_D(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_D_U(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_L(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchLeft(currentNode); +} + +// Adjacent Triples + +inline const void DijkstraFloodfill::Explore_D_DR_R(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchDownRight(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DR_R_UR(DijkstraPathfindingNode * currentNode) +{ + SearchDownRight(currentNode); + SearchRight(currentNode); + SearchUpRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_UR_U(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchUpRight(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UR_U_UL(DijkstraPathfindingNode * currentNode) +{ + SearchUpRight(currentNode); + SearchUp(currentNode); + SearchUpLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_UL_L(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchUpLeft(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_UL_L_DL(DijkstraPathfindingNode * currentNode) +{ + SearchUpLeft(currentNode); + SearchLeft(currentNode); + SearchDownLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_DL_D(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchDownLeft(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_DL_D_DR(DijkstraPathfindingNode * currentNode) +{ + SearchDownLeft(currentNode); + SearchDown(currentNode); + SearchDownRight(currentNode); +} + +// Non-Adjacent Cardinal Triples + +inline const void DijkstraFloodfill::Explore_D_R_U(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchRight(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_U_L(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchUp(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_L_D(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchLeft(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_D_R(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchDown(currentNode); + SearchRight(currentNode); +} + +// Quads + +inline const void DijkstraFloodfill::Explore_R_DR_D_L(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchDownRight(currentNode); + SearchDown(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_R_D_DL_L(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchDown(currentNode); + SearchDownLeft(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_UR_R_D(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchUpRight(currentNode); + SearchRight(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_R_DR_D(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchRight(currentNode); + SearchDownRight(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_UL_U_R(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchUpLeft(currentNode); + SearchUp(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_U_UR_R(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchUp(currentNode); + SearchUpRight(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_D_DL_L_U(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchDownLeft(currentNode); + SearchLeft(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_D_L_UL_U(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchLeft(currentNode); + SearchUpLeft(currentNode); + SearchUp(currentNode); +} + +// Quints + +inline const void DijkstraFloodfill::Explore_R_DR_D_DL_L(DijkstraPathfindingNode * currentNode) +{ + SearchRight(currentNode); + SearchDownRight(currentNode); + SearchDown(currentNode); + SearchDownLeft(currentNode); + SearchLeft(currentNode); +} + +inline const void DijkstraFloodfill::Explore_U_UR_R_DR_D(DijkstraPathfindingNode * currentNode) +{ + SearchUp(currentNode); + SearchUpRight(currentNode); + SearchRight(currentNode); + SearchDownRight(currentNode); + SearchDown(currentNode); +} + +inline const void DijkstraFloodfill::Explore_L_UL_U_UR_R(DijkstraPathfindingNode * currentNode) +{ + SearchLeft(currentNode); + SearchUpLeft(currentNode); + SearchUp(currentNode); + SearchUpRight(currentNode); + SearchRight(currentNode); +} + +inline const void DijkstraFloodfill::Explore_D_DL_L_UL_U(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchDownLeft(currentNode); + SearchLeft(currentNode); + SearchUpLeft(currentNode); + SearchUp(currentNode); +} + +inline const void DijkstraFloodfill::Explore_AllDirections(DijkstraPathfindingNode * currentNode) +{ + SearchDown(currentNode); + SearchDownLeft(currentNode); + SearchLeft(currentNode); + SearchUpLeft(currentNode); + SearchUp(currentNode); + SearchUpRight(currentNode); + SearchRight(currentNode); + SearchDownRight(currentNode); +} + +void DijkstraFloodfill::SearchDown(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row + 1; + int newCol = currentNode->m_col; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_ONE; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, Down, givenCost); +} + +void DijkstraFloodfill::SearchDownRight(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row + 1; + int newCol = currentNode->m_col + 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SQRT_2; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, DownRight, givenCost); +} + +void DijkstraFloodfill::SearchRight(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row; + int newCol = currentNode->m_col + 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_ONE; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, Right, givenCost); +} + +void DijkstraFloodfill::SearchUpRight(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row - 1; + int newCol = currentNode->m_col + 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SQRT_2; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, UpRight, givenCost); +} + +void DijkstraFloodfill::SearchUp(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row - 1; + int newCol = currentNode->m_col; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_ONE; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, Up, givenCost); +} + +void DijkstraFloodfill::SearchUpLeft(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row - 1; + int newCol = currentNode->m_col - 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SQRT_2; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, UpLeft, givenCost); +} + +void DijkstraFloodfill::SearchLeft(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row; + int newCol = currentNode->m_col - 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_ONE; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, Left, givenCost); +} + +void DijkstraFloodfill::SearchDownLeft(DijkstraPathfindingNode * currentNode) +{ + int newRow = currentNode->m_row + 1; + int newCol = currentNode->m_col - 1; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SQRT_2; + DijkstraPathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, (ArrayDirections)currentNode->m_directionFromStart, DownLeft, givenCost); +} + +void DijkstraFloodfill::PushNewNode( + DijkstraPathfindingNode * newSuccessor, + DijkstraPathfindingNode * currentNode, + ArrayDirections startDirection, + ArrayDirections parentDirection, + unsigned int givenCost) +{ + if (newSuccessor->m_iteration != m_currentIteration) + { + // Place node on the Open list (we've never seen it before) + newSuccessor->m_parent = currentNode; + newSuccessor->m_directionFromStart = startDirection; + newSuccessor->m_directionFromParent = parentDirection; + newSuccessor->m_givenCost = givenCost; + newSuccessor->m_listStatus = PathfindingNode::OnOpen; + newSuccessor->m_iteration = m_currentIteration; + +#ifdef USE_FAST_OPEN_LIST + m_fastOpenList->Push(newSuccessor); +#else + m_openList.add(newSuccessor); +#endif + } + else if (givenCost < newSuccessor->m_givenCost && + newSuccessor->m_listStatus == PathfindingNode::OnOpen) + { + // We found a cheaper way to this node - update it + unsigned int lastCost = newSuccessor->m_givenCost; + newSuccessor->m_parent = currentNode; + newSuccessor->m_directionFromStart = startDirection; + newSuccessor->m_directionFromParent = parentDirection; + newSuccessor->m_givenCost = givenCost; + +#ifdef USE_FAST_OPEN_LIST + m_fastOpenList->DecreaseKey(newSuccessor, lastCost); +#else + m_openList.decreaseKey(newSuccessor); +#endif + } +} + +inline bool DijkstraFloodfill::IsEmpty(int r, int c) +{ + unsigned int colBoundsCheck = c; + unsigned int rowBoundsCheck = r; + if (colBoundsCheck < (unsigned int)m_width && rowBoundsCheck < (unsigned int)m_height) + { + return m_map[c + (r * m_width)]; + } + else + { + return false; + } +} + +template +void DijkstraFloodfill::InitArray(T**& t, int width, int height) +{ + t = new T*[height]; + for (int i = 0; i < height; ++i) + { + t[i] = new T[width]; + memset(t[i], 0, sizeof(T)*width); + } +} + +template +void DijkstraFloodfill::DestroyArray(T**& t) +{ + for (int i = 0; i < m_height; ++i) + delete[] t[i]; + delete[] t; + + t = 0; +} + diff --git a/JPSPlusGoalBounding/DijkstraFloodfill.h b/JPSPlusGoalBounding/DijkstraFloodfill.h new file mode 100644 index 0000000..39158d6 --- /dev/null +++ b/JPSPlusGoalBounding/DijkstraFloodfill.h @@ -0,0 +1,181 @@ +/* + * DijkstraFloodfill.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include +#include "PathfindingNode.h" +#include "GenericHeap.h" +#include "BucketPriorityQueue.h" +#include "PrecomputeMap.h" + +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + +#define USE_FAST_OPEN_LIST // Significantly faster, but preallocated memory might not be large enough. Verify in cpp file. + +// A Dijkstra floodfill has no goal. It floods the map from the starting node until all connected nodes are exhausted. +// This Dijkstra floodfill propagate to all explored nodes the original direction it left the staring node. This is +// needed to determine the Goal Bounds for each neighboring edge of the starting node. + +class DijkstraFloodfill +{ +public: + DijkstraFloodfill(int width, int height, std::vector map, DistantJumpPoints** distantJumpPointMap); + ~DijkstraFloodfill(); + + void Flood(int r, int c); + inline int GetCurrentInteration() { return m_currentIteration; } + + DijkstraPathfindingNode ** m_mapNodes; + +private: + + // 48 function variations of exploring (used in 2048 entry look-up table) + // D = Down, U = Up, R = Right, L = Left, DR = Down Right, DL = Down Left, UR = Up Right, UL = Up Left + const void Explore_Null(DijkstraPathfindingNode * currentNode); + const void Explore_D(DijkstraPathfindingNode * currentNode); + const void Explore_DR(DijkstraPathfindingNode * currentNode); + const void Explore_R(DijkstraPathfindingNode * currentNode); + const void Explore_UR(DijkstraPathfindingNode * currentNode); + const void Explore_U(DijkstraPathfindingNode * currentNode); + const void Explore_UL(DijkstraPathfindingNode * currentNode); + const void Explore_L(DijkstraPathfindingNode * currentNode); + const void Explore_DL(DijkstraPathfindingNode * currentNode); + const void Explore_D_DR(DijkstraPathfindingNode * currentNode); + const void Explore_DR_R(DijkstraPathfindingNode * currentNode); + const void Explore_R_UR(DijkstraPathfindingNode * currentNode); + const void Explore_UR_U(DijkstraPathfindingNode * currentNode); + const void Explore_U_UL(DijkstraPathfindingNode * currentNode); + const void Explore_UL_L(DijkstraPathfindingNode * currentNode); + const void Explore_L_DL(DijkstraPathfindingNode * currentNode); + const void Explore_DL_D(DijkstraPathfindingNode * currentNod); + const void Explore_D_R(DijkstraPathfindingNode * currentNode); + const void Explore_R_U(DijkstraPathfindingNode * currentNode); + const void Explore_U_L(DijkstraPathfindingNode * currentNode); + const void Explore_L_D(DijkstraPathfindingNode * currentNode); + const void Explore_D_U(DijkstraPathfindingNode * currentNode); + const void Explore_R_L(DijkstraPathfindingNode * currentNode); + const void Explore_D_DR_R(DijkstraPathfindingNode * currentNode); + const void Explore_DR_R_UR(DijkstraPathfindingNode * currentNode); + const void Explore_R_UR_U(DijkstraPathfindingNode * currentNode); + const void Explore_UR_U_UL(DijkstraPathfindingNode * currentNode); + const void Explore_U_UL_L(DijkstraPathfindingNode * currentNode); + const void Explore_UL_L_DL(DijkstraPathfindingNode * currentNode); + const void Explore_L_DL_D(DijkstraPathfindingNode * currentNode); + const void Explore_DL_D_DR(DijkstraPathfindingNode * currentNode); + const void Explore_D_R_U(DijkstraPathfindingNode * currentNode); + const void Explore_R_U_L(DijkstraPathfindingNode * currentNode); + const void Explore_U_L_D(DijkstraPathfindingNode * currentNode); + const void Explore_L_D_R(DijkstraPathfindingNode * currentNode); + const void Explore_R_DR_D_L(DijkstraPathfindingNode * currentNode); + const void Explore_R_D_DL_L(DijkstraPathfindingNode * currentNode); + const void Explore_U_UR_R_D(DijkstraPathfindingNode * currentNode); + const void Explore_U_R_DR_D(DijkstraPathfindingNode * currentNode); + const void Explore_L_UL_U_R(DijkstraPathfindingNode * currentNode); + const void Explore_L_U_UR_R(DijkstraPathfindingNode * currentNode); + const void Explore_D_DL_L_U(DijkstraPathfindingNode * currentNode); + const void Explore_D_L_UL_U(DijkstraPathfindingNode * currentNode); + const void Explore_R_DR_D_DL_L(DijkstraPathfindingNode * currentNode); + const void Explore_U_UR_R_DR_D(DijkstraPathfindingNode * currentNode); + const void Explore_L_UL_U_UR_R(DijkstraPathfindingNode * currentNode); + const void Explore_D_DL_L_UL_U(DijkstraPathfindingNode * currentNode); + const void Explore_AllDirections(DijkstraPathfindingNode * currentNode); + + const void Explore_AllDirectionsWithChecks(DijkstraPathfindingNode * currentNode); + + void SearchDown(DijkstraPathfindingNode * currentNode); + void SearchDownRight(DijkstraPathfindingNode * currentNode); + void SearchRight(DijkstraPathfindingNode * currentNode); + void SearchUpRight(DijkstraPathfindingNode * currentNode); + void SearchUp(DijkstraPathfindingNode * currentNode); + void SearchUpLeft(DijkstraPathfindingNode * currentNode); + void SearchLeft(DijkstraPathfindingNode * currentNode); + void SearchDownLeft(DijkstraPathfindingNode * currentNode); + + void PushNewNode( + DijkstraPathfindingNode * newSuccessor, + DijkstraPathfindingNode * currentNode, + ArrayDirections startDirection, + ArrayDirections parentDirection, + unsigned int givenCost); + + // Helper functions for heap open list + struct PathfindingNodeEqual { + bool operator()(const DijkstraPathfindingNode* i1, const DijkstraPathfindingNode* i2) + { + return (i1 == i2); + } + }; + + struct PathfindingNodeCmp : std::binary_function { + bool operator()(DijkstraPathfindingNode* const lhs, DijkstraPathfindingNode* const rhs) const { + return lhs->m_givenCost > rhs->m_givenCost; + } + }; + + struct SearchNodeHash { + size_t operator()(const DijkstraPathfindingNode* x) const + { + return (size_t)(x->m_col + (x->m_row * MAX_WIDTH)); + } + }; + + typedef GenericHeap PQueue; + + // Open list + PQueue m_openList; +#ifdef USE_FAST_OPEN_LIST + BucketPriorityQueue* m_fastOpenList; +#endif + + // Map properties + int m_width, m_height; + std::vector m_map; + + // Search specific info + int m_currentIteration; // This allows us to know if a node has been touched this iteration (faster than clearing all the nodes before each search) + + // Wall queries + bool IsEmpty(int r, int c); + + // 2D array initialization and destruction + template void InitArray(T**& t, int width, int height); + template void DestroyArray(T**& t); +}; diff --git a/JPSPlusGoalBounding/Entry.cpp b/JPSPlusGoalBounding/Entry.cpp new file mode 100644 index 0000000..31a5f52 --- /dev/null +++ b/JPSPlusGoalBounding/Entry.cpp @@ -0,0 +1,74 @@ +/* + * Entry.cpp + * + * Copyright (c) 2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include +#include "Entry.h" +#include "PrecomputeMap.h" +#include "JPSPlus.h" + +const char *GetName() +{ + return "JPS+"; +} + +void PreprocessMap(std::vector &bits, int w, int h, const char *filename) +{ + printf("Writing to file '%s'\n", filename); + + PrecomputeMap precomputeMap(w, h, bits); + precomputeMap.CalculateMap(); + precomputeMap.SaveMap(filename); +} + +void *PrepareForSearch(std::vector &bits, int w, int h, const char *filename) +{ + //printf("Reading from file '%s'\n", filename); + + PrecomputeMap precomputeMap(w, h, bits); + precomputeMap.LoadMap(filename); + JumpDistancesAndGoalBounds** preprocessedMap = precomputeMap.GetPreprocessedMap(); + return (void*)new JPSPlus(preprocessedMap, bits, w, h); +} + +bool GetPath(void *data, xyLoc s, xyLoc g, std::vector &path) +{ + JPSPlus* search = (JPSPlus*)data; + return search->GetPath((xyLocJPS&)s, (xyLocJPS&)g, (std::vector&)path); +} diff --git a/JPSPlusGoalBounding/Entry.h b/JPSPlusGoalBounding/Entry.h new file mode 100644 index 0000000..6af1b10 --- /dev/null +++ b/JPSPlusGoalBounding/Entry.h @@ -0,0 +1,50 @@ +/* + * Entry.h + * + * Copyright (c) 2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +struct xyLoc { + int16_t x; + int16_t y; +}; + +void PreprocessMap(std::vector &bits, int width, int height, const char *filename); +void *PrepareForSearch(std::vector &bits, int width, int height, const char *filename); +bool GetPath(void *data, xyLoc s, xyLoc g, std::vector &path); +const char *GetName(); diff --git a/JPSPlusGoalBounding/FPUtil.cpp b/JPSPlusGoalBounding/FPUtil.cpp new file mode 100644 index 0000000..dea50b0 --- /dev/null +++ b/JPSPlusGoalBounding/FPUtil.cpp @@ -0,0 +1,31 @@ +#include "stdafx.h" +#include "FPUtil.h" + +/* + * FPUtil.cpp + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ diff --git a/JPSPlusGoalBounding/FPUtil.h b/JPSPlusGoalBounding/FPUtil.h new file mode 100644 index 0000000..9336c44 --- /dev/null +++ b/JPSPlusGoalBounding/FPUtil.h @@ -0,0 +1,61 @@ +/* + * FPUtil.h + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _MSC_VER +#include "stdafx.h" +#endif + +#ifndef FPUTIL_H +#define FPUTIL_H + +/** + * FPUtil.h + * + * This file defines floating point compare functions with tolerances. + * + */ + +// Floating point comparisons +static const double TOLERANCE = 0.000001; // floating point tolerance + +/** +* Compare two doubles using a floating-point tolerance +*/ +inline bool fless(double a, double b) { return (a < b - TOLERANCE); } +/** +* Compare two doubles using a floating-point tolerance +*/ +inline bool fgreater(double a, double b) { return (a > b + TOLERANCE); } +/** +* Compare two doubles using a floating-point tolerance +*/ +inline bool fequal(double a, double b) +{ return (a > b - TOLERANCE) && (a < b+TOLERANCE); } + +#endif diff --git a/JPSPlusGoalBounding/FastStack.cpp b/JPSPlusGoalBounding/FastStack.cpp new file mode 100644 index 0000000..ca457d0 --- /dev/null +++ b/JPSPlusGoalBounding/FastStack.cpp @@ -0,0 +1,42 @@ +/* + * FastStack.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "StdAfx.h" +#include "FastStack.h" + diff --git a/JPSPlusGoalBounding/FastStack.h b/JPSPlusGoalBounding/FastStack.h new file mode 100644 index 0000000..39eaa9f --- /dev/null +++ b/JPSPlusGoalBounding/FastStack.h @@ -0,0 +1,63 @@ +/* + * FastStack.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "PathfindingNode.h" + +// This class is designed to be used only for grid searches that use the Octile heuristic. +// In this specific use case, a stack can be used instead of a traditional open list to +// hold neighboring all nodes that have a final cost equal to the parent node. When the +// cheapest node is needed, exhaust this stack first before pulling off of the open list. + +class FastStack +{ +public: + FastStack(int size) : m_nextFreeNode(0) { m_nodeArray = new PathfindingNode*[size]; } + ~FastStack(void) { delete[] m_nodeArray; } + + inline void Reset(void) { m_nextFreeNode = 0; } + inline bool Empty(void) { return m_nextFreeNode == 0; } + inline void Push(PathfindingNode* node) { m_nodeArray[m_nextFreeNode++] = node; } + PathfindingNode* Pop(void) { return m_nodeArray[--m_nextFreeNode]; } + +private: + int m_nextFreeNode; + PathfindingNode** m_nodeArray; +}; + diff --git a/JPSPlusGoalBounding/GenericHeap.cpp b/JPSPlusGoalBounding/GenericHeap.cpp new file mode 100644 index 0000000..509d619 --- /dev/null +++ b/JPSPlusGoalBounding/GenericHeap.cpp @@ -0,0 +1,31 @@ +/* + * GenericHeap.cpp + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "GenericHeap.h" diff --git a/JPSPlusGoalBounding/GenericHeap.h b/JPSPlusGoalBounding/GenericHeap.h new file mode 100644 index 0000000..4cf858b --- /dev/null +++ b/JPSPlusGoalBounding/GenericHeap.h @@ -0,0 +1,312 @@ +/* + * GenericHeap.h + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _MSC_VER +#include "stdafx.h" +#include +#else +#include +#endif + +#ifndef HEAP2_H +#define HEAP2_H + +#include +#include +#include + +/** + * Generic Heap + * +* A relatively simple heap class. Uses a second hash table so that + * keys can be looked up and re-heaped in constant time instead of + * linear time. + * + * The EqKey and CmpKey functions were required for the gnu hash_map, but + * aren't compatible with the windows hash_map. So, there is some + * unnecessary code here which I just haven't re-written. + */ +template +class GenericHeap { +public: + GenericHeap(); + ~GenericHeap(); + void reset(); + void add(Obj val); + void decreaseKey(Obj val); + bool isIn(Obj val); + Obj remove(); + void pop() { remove(); } + Obj top() { return _elts[0]; } + Obj find(Obj val); + bool empty(); + uint32_t size() { return (uint32_t)_elts.size(); } + void reserve(unsigned int c) { _elts.reserve(c); } +private: + std::vector _elts; + void heapifyUp(unsigned int index); + void heapifyDown(unsigned int index); +#ifdef _MSC_VER + typedef stdext::hash_map IndexTable; +#else +// // this was my original definition, but to maintain compatibility with +// // microsoft's hash_map, we now have to require a perfect hash function +// typedef __gnu_cxx::hash_map IndexTable; + typedef __gnu_cxx::hash_map IndexTable; +#endif + IndexTable table; +}; + + +template +GenericHeap::GenericHeap() +{ +} + +template +GenericHeap::~GenericHeap() +{ +} + +/** + * GenericHeap::reset() + * + * \brief Remove all objects from queue. + * + * \return none + */ +template +void GenericHeap::reset() +{ + table.clear(); + _elts.resize(0); +} + +/** +* GenericHeap::add() + * + * \brief Add object into GenericHeap. + * + * \param val Object to be added + * \return none + */ +template +void GenericHeap::add(Obj val) +{ + HashKey hk; + + assert(table.find(hk(val)) == table.end()); + table[hk(val)] = (unsigned int)_elts.size(); + _elts.push_back(val); + heapifyUp(table[hk(val)]); +} + +/** +* GenericHeap::decreaseKey() + * + * \brief Indicate that the key for a particular object has decreased. + * + * \param val Object which has had its key decreased + * \return none + */ +template +void GenericHeap::decreaseKey(Obj val) +{ + +// otherwise we get an unused variable warning when compiling in release mode +#ifndef NDEBUG + EqKey eq; +#endif + HashKey hk; + + assert(eq(_elts[table[hk(val)]], val)); + _elts[table[hk(val)]] = val; + heapifyUp(table[hk(val)]); +} + +/** +* GenericHeap::isIn() + * + * \brief Returns true if the object is in the GenericHeap. + * + * \param val Object to be tested + * \return true if the object is in the heap + */ +template +bool GenericHeap::isIn(Obj val) +{ + EqKey eq; + HashKey hk; + + if ((table.find(hk(val)) != table.end()) && (table[hk(val)] < _elts.size()) && + (eq(_elts[table[hk(val)]], val))) + return true; + return false; +} + +/** +* GenericHeap::remove() + * + * \brief Remove the item with the lowest key from the heap & re-heapify. + * + * \return Object with lowest key + */ +template +Obj GenericHeap::remove() +{ + HashKey hk; + + if (empty()) + return Obj(); + Obj ans = _elts[0]; + _elts[0] = _elts[_elts.size()-1]; + table[hk(_elts[0])] = 0; + _elts.pop_back(); + table.erase(hk(ans)); + heapifyDown(0); + + return ans; +} + +/** +* GenericHeap::find() + * + * \brief Find this object in the heap and return + * + * The object passed in only needs enough fields filled in to find + * the hash key of the object. All fields will be filled in when returned. + * + * \param val Object to find + * \return The same object from the heap. + */ +template +Obj GenericHeap::find(Obj val) +{ + HashKey hk; + + if (!isIn(val)) + return Obj(); + return _elts[table[hk(val)]]; +} + +/** + * GenericHeap::empty() + * + * \brief Returns true if no items are in the heap. + * + * \return true if no items are in the heap. + */ +/** +* Returns true if no items are in the GenericHeap. + */ +template +bool GenericHeap::empty() +{ + return _elts.size() == 0; +} + +/** +* GenericHeap::heapifyUp() + * + * \brief Check the object at the current index and see if it needs to move up the heap. + * + * An object moves up if it has a lower key than its parent. + * + * \param index Current index + * \return none + */ +template +void GenericHeap::heapifyUp(unsigned int index) +{ + if (index == 0) return; + int parent = (index-1)/2; + CmpKey compare; + HashKey hk; + + if (compare(_elts[parent], _elts[index])) + { + Obj tmp = _elts[parent]; + _elts[parent] = _elts[index]; + _elts[index] = tmp; + table[hk(_elts[parent])] = parent; + table[hk(_elts[index])] = index; +#ifndef NDEBUG + EqKey eq; +#endif + assert(!eq(_elts[parent], _elts[index])); + heapifyUp(parent); + } +} + +/** +* GenericHeap::heapifyDown() + * + * \brief Check the object at the current index and see if it needs to move down the heap. + * + * If an object has a higher key than one or more of its children, it is swapped + * with its lowest-valued child. + * + * \param index Current index + * \return none + */ +template +void GenericHeap::heapifyDown(unsigned int index) +{ + HashKey hk; + CmpKey compare; + unsigned int child1 = index*2+1; + unsigned int child2 = index*2+2; + int which; + unsigned int count = (unsigned int)_elts.size(); + // find smallest child + if (child1 >= count) + return; + else if (child2 >= count) + which = child1; + //else if (fless(_elts[child1]->getKey(), _elts[child2]->getKey())) + else if (!(compare(_elts[child1], _elts[child2]))) + which = child1; + else + which = child2; + + //if (fless(_elts[which]->getKey(), _elts[index]->getKey())) + if (!(compare(_elts[which], _elts[index]))) + { + Obj tmp = _elts[which]; + _elts[which] = _elts[index]; + table[hk(_elts[which])] = which; + _elts[index] = tmp; + table[hk(_elts[index])] = index; + // _elts[which]->key = which; + // _elts[index]->key = index; + heapifyDown(which); + } +} + +#endif diff --git a/JPSPlusGoalBounding/JPSPlus.cpp b/JPSPlusGoalBounding/JPSPlus.cpp new file mode 100644 index 0000000..367b173 --- /dev/null +++ b/JPSPlusGoalBounding/JPSPlus.cpp @@ -0,0 +1,985 @@ +/* + * JPSPlus.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "JPSPlus.h" + +// Ideal choice of fixed-point equivalent to 1.0 that can almost perfectly represent sqrt(2) and (sqrt(2) - 1) in whole numbers +// 1.000000000 = 2378 +// 0.414213624 = 985 / 2378 +// 1.414213625 = 3363 / 2378 +// 1.414213562 = Actual sqrt(2) +// 0.00000006252 = Difference between actual sqrt(2) and fixed-point sqrt(2) +#define FIXED_POINT_MULTIPLIER 2378 +#define FIXED_POINT_SHIFT(x) ((x) * FIXED_POINT_MULTIPLIER) +#define SQRT_2 3363 +#define SQRT_2_MINUS_ONE 985 + +typedef const void (JPSPlus::*FunctionPointer)(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + +JPSPlus::JPSPlus(JumpDistancesAndGoalBounds** jumpDistancesAndGoalBoundsMap, std::vector &rawMap, int w, int h) +{ + // Map properties + m_width = w; + m_height = h; + + // Adjust preallocation for worst-case + m_simpleUnsortedPriorityQueue = new SimpleUnsortedPriorityQueue(10000); + m_fastStack = new FastStack(1000); + + m_jumpDistancesAndGoalBounds = jumpDistancesAndGoalBoundsMap; + m_currentIteration = 1; // This gets incremented on each search + + // Initialize nodes + InitArray(m_mapNodes, m_width, m_height); + for (int r = 0; r +void JPSPlus::InitArray(T**& t, int width, int height) +{ + t = new T*[height]; + for (int i = 0; i < height; ++i) + { + t[i] = new T[width]; + memset(t[i], 0, sizeof(T)*width); + } +} + +template +void JPSPlus::DestroyArray(T**& t) +{ + for (int i = 0; i < m_height; ++i) + delete[] t[i]; + delete[] t; + + t = 0; +} + +bool JPSPlus::GetPath(xyLocJPS& s, xyLocJPS& g, std::vector &path) +{ + if (path.size() > 0) + { + path.push_back(g); + return true; + } + + int startRow = s.y; + int startCol = s.x; + m_goalRow = g.y; + m_goalCol = g.x; + + { + // Initialize map + path.clear(); + + m_goalNode = &m_mapNodes[m_goalRow][m_goalCol]; + m_currentIteration++; + + m_fastStack->Reset(); + m_simpleUnsortedPriorityQueue->Reset(); + } + + // Create starting node + PathfindingNode* startNode = &m_mapNodes[startRow][startCol]; + startNode->m_parent = NULL; + startNode->m_givenCost = 0; + startNode->m_finalCost = 0; + startNode->m_listStatus = PathfindingNode::OnOpen; + startNode->m_iteration = m_currentIteration; + + // Actual search + PathStatus status = SearchLoop(startNode); + + if (status == PathFound) + { + FinalizePath(path); + if (path.size() > 0) + { + path.pop_back(); + return false; + } + return true; + } + else + { + // No path + return true; + } +} + +PathStatus JPSPlus::SearchLoop(PathfindingNode* startNode) +{ + // Create 2048 entry function pointer lookup table + #define CASE(x) &JPSPlus::Explore_ ## x ## , + static const FunctionPointer exploreDirections[2048] = + { + #include "cases.h" + }; + #undef CASE(x) + + { + // Special case for the starting node + + if (startNode == m_goalNode) + { + return PathFound; + } + + JumpDistancesAndGoalBounds* jumpDistancesAndGoalBounds = &m_jumpDistancesAndGoalBounds[startNode->m_row][startNode->m_col]; + Explore_AllDirections(startNode, jumpDistancesAndGoalBounds); + startNode->m_listStatus = PathfindingNode::OnClosed; + } + + while (!m_simpleUnsortedPriorityQueue->Empty() || !m_fastStack->Empty()) + { + PathfindingNode* currentNode; + + if(!m_fastStack->Empty()) + { + currentNode = m_fastStack->Pop(); + } + else + { + currentNode = m_simpleUnsortedPriorityQueue->Pop(); + } + + if (currentNode == m_goalNode) + { + return PathFound; + } + + // Explore nodes based on parent + JumpDistancesAndGoalBounds* jumpDistancesAndGoalBounds = + &m_jumpDistancesAndGoalBounds[currentNode->m_row][currentNode->m_col]; + + (this->*exploreDirections[(jumpDistancesAndGoalBounds->blockedDirectionBitfield * 8) + + currentNode->m_directionFromParent])(currentNode, jumpDistancesAndGoalBounds); + + currentNode->m_listStatus = PathfindingNode::OnClosed; + } + return NoPathExists; +} + +void JPSPlus::FinalizePath(std::vector &finalPath) +{ + PathfindingNode* prevNode = NULL; + PathfindingNode* curNode = m_goalNode; + + while (curNode != NULL) + { + xyLocJPS loc; + loc.x = curNode->m_col; + loc.y = curNode->m_row; + + if (prevNode != NULL) + { + // Insert extra nodes if needed (may not be neccessary depending on final path use) + int xDiff = curNode->m_col - prevNode->m_col; + int yDiff = curNode->m_row - prevNode->m_row; + + int xInc = 0; + int yInc = 0; + + if (xDiff > 0) { xInc = 1; } + else if (xDiff < 0) { xInc = -1; xDiff = -xDiff; } + + if (yDiff > 0) { yInc = 1; } + else if (yDiff < 0) { yInc = -1; yDiff = -yDiff; } + + int x = prevNode->m_col; + int y = prevNode->m_row; + int steps = xDiff - 1; + if (yDiff > xDiff) { steps = yDiff - 1; } + + for (int i = 0; i < steps; i++) + { + x += xInc; + y += yInc; + + xyLocJPS locNew; + locNew.x = x; + locNew.y = y; + + finalPath.push_back(locNew); + } + } + + finalPath.push_back(loc); + prevNode = curNode; + curNode = curNode->m_parent; + } + std::reverse(finalPath.begin(), finalPath.end()); +} + +// Macro definitions for exploring in a particular direction +#define MacroExploreDown \ + if (m_goalRow >= map->bounds[Down][MinRow] && \ + m_goalRow <= map->bounds[Down][MaxRow] && \ + m_goalCol >= map->bounds[Down][MinCol] && \ + m_goalCol <= map->bounds[Down][MaxCol]) SearchDown(currentNode, map->jumpDistance[Down]); + +#define MacroExploreDownRight \ + if (m_goalRow >= map->bounds[DownRight][MinRow] && \ + m_goalRow <= map->bounds[DownRight][MaxRow] && \ + m_goalCol >= map->bounds[DownRight][MinCol] && \ + m_goalCol <= map->bounds[DownRight][MaxCol]) SearchDownRight(currentNode, map->jumpDistance[DownRight]); + +#define MacroExploreRight \ + if (m_goalRow >= map->bounds[Right][MinRow] && \ + m_goalRow <= map->bounds[Right][MaxRow] && \ + m_goalCol >= map->bounds[Right][MinCol] && \ + m_goalCol <= map->bounds[Right][MaxCol]) SearchRight(currentNode, map->jumpDistance[Right]); + +#define MacroExploreUpRight \ + if (m_goalRow >= map->bounds[UpRight][MinRow] && \ + m_goalRow <= map->bounds[UpRight][MaxRow] && \ + m_goalCol >= map->bounds[UpRight][MinCol] && \ + m_goalCol <= map->bounds[UpRight][MaxCol]) SearchUpRight(currentNode, map->jumpDistance[UpRight]); + +#define MacroExploreUp \ + if (m_goalRow >= map->bounds[Up][MinRow] && \ + m_goalRow <= map->bounds[Up][MaxRow] && \ + m_goalCol >= map->bounds[Up][MinCol] && \ + m_goalCol <= map->bounds[Up][MaxCol]) SearchUp(currentNode, map->jumpDistance[Up]); + +#define MacroExploreUpLeft \ + if (m_goalRow >= map->bounds[UpLeft][MinRow] && \ + m_goalRow <= map->bounds[UpLeft][MaxRow] && \ + m_goalCol >= map->bounds[UpLeft][MinCol] && \ + m_goalCol <= map->bounds[UpLeft][MaxCol]) SearchUpLeft(currentNode, map->jumpDistance[UpLeft]); + +#define MacroExploreLeft \ + if (m_goalRow >= map->bounds[Left][MinRow] && \ + m_goalRow <= map->bounds[Left][MaxRow] && \ + m_goalCol >= map->bounds[Left][MinCol] && \ + m_goalCol <= map->bounds[Left][MaxCol]) SearchLeft(currentNode, map->jumpDistance[Left]); + +#define MacroExploreDownLeft \ + if (m_goalRow >= map->bounds[DownLeft][MinRow] && \ + m_goalRow <= map->bounds[DownLeft][MaxRow] && \ + m_goalCol >= map->bounds[DownLeft][MinCol] && \ + m_goalCol <= map->bounds[DownLeft][MaxCol]) SearchDownLeft(currentNode, map->jumpDistance[DownLeft]); + +inline const void JPSPlus::Explore_Null(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + // Purposely does nothing +} + +inline const void JPSPlus::Explore_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; +} + +inline const void JPSPlus::Explore_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownRight; +} + +inline const void JPSPlus::Explore_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; +} + +inline const void JPSPlus::Explore_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpRight; +} + +inline const void JPSPlus::Explore_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; +} + +inline const void JPSPlus::Explore_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpLeft; +} + +inline const void JPSPlus::Explore_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownLeft; +} + +// Adjacent Doubles + +inline const void JPSPlus::Explore_D_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreDownRight; +} + +inline const void JPSPlus::Explore_DR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownRight; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_R_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreUpRight; +} + +inline const void JPSPlus::Explore_UR_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpRight; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_U_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreUpLeft; +} + +inline const void JPSPlus::Explore_UL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpLeft; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_L_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreDownLeft; +} + +inline const void JPSPlus::Explore_DL_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownLeft; + MacroExploreDown; +} + +// Non-Adjacent Cardinal Doubles + +inline const void JPSPlus::Explore_D_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_R_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_U_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_L_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_D_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_R_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreLeft; +} + +// Adjacent Triples + +inline const void JPSPlus::Explore_D_DR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreDownRight; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_DR_R_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownRight; + MacroExploreRight; + MacroExploreUpRight; +} + +inline const void JPSPlus::Explore_R_UR_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreUpRight; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_UR_U_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpRight; + MacroExploreUp; + MacroExploreUpLeft; +} + +inline const void JPSPlus::Explore_U_UL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreUpLeft; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_UL_L_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUpLeft; + MacroExploreLeft; + MacroExploreDownLeft; +} + +inline const void JPSPlus::Explore_L_DL_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreDownLeft; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_DL_D_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDownLeft; + MacroExploreDown; + MacroExploreDownRight; +} + +// Non-Adjacent Cardinal Triples + +inline const void JPSPlus::Explore_D_R_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreRight; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_R_U_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreUp; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_U_L_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreLeft; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_L_D_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreDown; + MacroExploreRight; +} + +// Quads + +inline const void JPSPlus::Explore_R_DR_D_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreDownRight; + MacroExploreDown; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_R_D_DL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreDown; + MacroExploreDownLeft; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_U_UR_R_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreUpRight; + MacroExploreRight; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_U_R_DR_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreRight; + MacroExploreDownRight; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_L_UL_U_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreUpLeft; + MacroExploreUp; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_L_U_UR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreUp; + MacroExploreUpRight; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_D_DL_L_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreDownLeft; + MacroExploreLeft; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_D_L_UL_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreLeft; + MacroExploreUpLeft; + MacroExploreUp; +} + +// Quints + +inline const void JPSPlus::Explore_R_DR_D_DL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreRight; + MacroExploreDownRight; + MacroExploreDown; + MacroExploreDownLeft; + MacroExploreLeft; +} + +inline const void JPSPlus::Explore_U_UR_R_DR_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreUp; + MacroExploreUpRight; + MacroExploreRight; + MacroExploreDownRight; + MacroExploreDown; +} + +inline const void JPSPlus::Explore_L_UL_U_UR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreLeft; + MacroExploreUpLeft; + MacroExploreUp; + MacroExploreUpRight; + MacroExploreRight; +} + +inline const void JPSPlus::Explore_D_DL_L_UL_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreDownLeft; + MacroExploreLeft; + MacroExploreUpLeft; + MacroExploreUp; +} + +inline const void JPSPlus::Explore_AllDirections(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map) +{ + MacroExploreDown; + MacroExploreDownLeft; + MacroExploreLeft; + MacroExploreUpLeft; + MacroExploreUp; + MacroExploreUpRight; + MacroExploreRight; + MacroExploreDownRight; +} + +void JPSPlus::SearchDown(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Consider straight line to Goal + if (col == m_goalCol && row < m_goalRow) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + if ((row + absJumpDistance) >= m_goalRow) + { + unsigned int diff = m_goalRow - row; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(diff); + PathfindingNode * newSuccessor = m_goalNode; + PushNewNode(newSuccessor, currentNode, Down, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row + jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][col]; + PushNewNode(newSuccessor, currentNode, Down, givenCost); + } +} + +void JPSPlus::SearchDownRight(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Check for goal in general direction (straight line to Goal or Target Jump Point) + if (row < m_goalRow && col < m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + int diffRow = m_goalRow - row; + int diffCol = m_goalCol - col; + int smallerDiff = diffRow; + if (diffCol < smallerDiff) { smallerDiff = diffCol; } + + if (smallerDiff <= absJumpDistance) + { + int newRow = row + smallerDiff; + int newCol = col + smallerDiff; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * smallerDiff); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, DownRight, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row + jumpDistance; + int newCol = col + jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, DownRight, givenCost); + } +} + +void JPSPlus::SearchRight(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Consider straight line to Goal + if (row == m_goalRow && col < m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + if ((col + absJumpDistance) >= m_goalCol) + { + unsigned int diff = m_goalCol - col; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(diff); + PathfindingNode * newSuccessor = m_goalNode; + PushNewNode(newSuccessor, currentNode, Right, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newCol = col + jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[row][newCol]; + PushNewNode(newSuccessor, currentNode, Right, givenCost); + } +} + +void JPSPlus::SearchUpRight(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Check for goal in general direction (straight line to Goal or Target Jump Point) + if (row > m_goalRow && col < m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + int diffRow = row - m_goalRow; + int diffCol = m_goalCol - col; + int smallerDiff = diffRow; + if (diffCol < smallerDiff) { smallerDiff = diffCol; } + + if (smallerDiff <= absJumpDistance) + { + int newRow = row - smallerDiff; + int newCol = col + smallerDiff; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * smallerDiff); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, UpRight, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row - jumpDistance; + int newCol = col + jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, UpRight, givenCost); + } +} + +void JPSPlus::SearchUp(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Consider straight line to Goal + if (col == m_goalCol && row > m_goalRow) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + if ((row - absJumpDistance) <= m_goalRow) + { + unsigned int diff = row - m_goalRow; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(diff); + PathfindingNode * newSuccessor = m_goalNode; + PushNewNode(newSuccessor, currentNode, Up, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row - jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][col]; + PushNewNode(newSuccessor, currentNode, Up, givenCost); + } +} + +void JPSPlus::SearchUpLeft(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Check for goal in general direction (straight line to Goal or Target Jump Point) + if (row > m_goalRow && col > m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + int diffRow = row - m_goalRow; + int diffCol = col - m_goalCol; + int smallerDiff = diffRow; + if (diffCol < smallerDiff) { smallerDiff = diffCol; } + + if (smallerDiff <= absJumpDistance) + { + int newRow = row - smallerDiff; + int newCol = col - smallerDiff; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * smallerDiff); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, UpLeft, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row - jumpDistance; + int newCol = col - jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, UpLeft, givenCost); + } +} + +void JPSPlus::SearchLeft(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Consider straight line to Goal + if (row == m_goalRow && col > m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + if ((col - absJumpDistance) <= m_goalCol) + { + unsigned int diff = col - m_goalCol; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(diff); + PathfindingNode * newSuccessor = m_goalNode; + PushNewNode(newSuccessor, currentNode, Left, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newCol = col - jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + FIXED_POINT_SHIFT(jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[row][newCol]; + PushNewNode(newSuccessor, currentNode, Left, givenCost); + } +} + +void JPSPlus::SearchDownLeft(PathfindingNode * currentNode, int jumpDistance) +{ + int row = currentNode->m_row; + int col = currentNode->m_col; + + // Check for goal in general direction (straight line to Goal or Target Jump Point) + if (row < m_goalRow && col > m_goalCol) + { + int absJumpDistance = jumpDistance; + if (absJumpDistance < 0) { absJumpDistance = -absJumpDistance; } + + int diffRow = m_goalRow - row; + int diffCol = col - m_goalCol; + int smallerDiff = diffRow; + if (diffCol < smallerDiff) { smallerDiff = diffCol; } + + if (smallerDiff <= absJumpDistance) + { + int newRow = row + smallerDiff; + int newCol = col - smallerDiff; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * smallerDiff); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, DownLeft, givenCost); + return; + } + } + + if (jumpDistance > 0) + { + // Directly jump + int newRow = row + jumpDistance; + int newCol = col - jumpDistance; + unsigned int givenCost = currentNode->m_givenCost + (SQRT_2 * jumpDistance); + PathfindingNode * newSuccessor = &m_mapNodes[newRow][newCol]; + PushNewNode(newSuccessor, currentNode, DownLeft, givenCost); + } +} + +void JPSPlus::PushNewNode( + PathfindingNode * newSuccessor, + PathfindingNode * currentNode, + ArrayDirections parentDirection, + unsigned int givenCost) +{ + if (newSuccessor->m_iteration != m_currentIteration) + { + // Place node on the Open list (we've never seen it before) + + // Compute heuristic using octile calculation (optimized: minDiff * SQRT_2_MINUS_ONE + maxDiff) + unsigned int diffrow = abs(m_goalRow - newSuccessor->m_row); + unsigned int diffcolumn = abs(m_goalCol - newSuccessor->m_col); + unsigned int heuristicCost; + if (diffrow <= diffcolumn) + { + heuristicCost = (diffrow * SQRT_2_MINUS_ONE) + FIXED_POINT_SHIFT(diffcolumn); + } + else + { + heuristicCost = (diffcolumn * SQRT_2_MINUS_ONE) + FIXED_POINT_SHIFT(diffrow); + } + + newSuccessor->m_parent = currentNode; + newSuccessor->m_directionFromParent = parentDirection; + newSuccessor->m_givenCost = givenCost; + newSuccessor->m_finalCost = givenCost + heuristicCost; + newSuccessor->m_listStatus = PathfindingNode::OnOpen; + newSuccessor->m_iteration = m_currentIteration; + + if(newSuccessor->m_finalCost <= currentNode->m_finalCost) + { + m_fastStack->Push(newSuccessor); + } + else + { + m_simpleUnsortedPriorityQueue->Add(newSuccessor); + } + } + else if (givenCost < newSuccessor->m_givenCost && + newSuccessor->m_listStatus == PathfindingNode::OnOpen) // Might be valid to remove this 2nd condition for extra speed (a node on the closed list wouldn't be cheaper) + { + // We found a cheaper way to this node - update node + + // Extract heuristic cost (was previously calculated) + unsigned int heuristicCost = newSuccessor->m_finalCost - newSuccessor->m_givenCost; + + newSuccessor->m_parent = currentNode; + newSuccessor->m_directionFromParent = parentDirection; + newSuccessor->m_givenCost = givenCost; + newSuccessor->m_finalCost = givenCost + heuristicCost; + + // No decrease key operation necessary (already in unsorted open list) + } +} \ No newline at end of file diff --git a/JPSPlusGoalBounding/JPSPlus.h b/JPSPlusGoalBounding/JPSPlus.h new file mode 100644 index 0000000..f3ed652 --- /dev/null +++ b/JPSPlusGoalBounding/JPSPlus.h @@ -0,0 +1,160 @@ +/* + * JPSPlus.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "PathfindingNode.h" +#include "PrecomputeMap.h" +#include "FastStack.h" +#include "SimpleUnsortedPriorityQueue.h" +#include + +struct xyLocJPS { + int16_t x; + int16_t y; +}; + +enum PathStatus +{ + Working, + PathFound, + NoPathExists +}; + +// This version of JPS+ is intimately tied with Goal Bounding. +// Every effort has been made to maximize speed. +// If you develop a way to improve this code or make it faster, contact steve.rabin@gmail.com + +class JPSPlus +{ +public: + JPSPlus(JumpDistancesAndGoalBounds** jumpDistancesAndGoalBoundsMap, std::vector &rawMap, int w, int h); + ~JPSPlus(); + + bool GetPath(xyLocJPS& s, xyLocJPS& g, std::vector &path); + +protected: + + PathStatus SearchLoop(PathfindingNode* startNode); + void FinalizePath(std::vector &finalPath); + + // 48 function variations of exploring (used in 2048 entry look-up table) + // D = Down, U = Up, R = Right, L = Left, DR = Down Right, DL = Down Left, UR = Up Right, UL = Up Left + const void Explore_Null(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UR_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DL_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_DR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DR_R_UR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_UR_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UR_U_UL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_UL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_UL_L_DL(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_DL_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_DL_D_DR(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_R_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_U_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_L_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_D_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_DR_D_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_D_DL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_UR_R_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_R_DR_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_UL_U_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_U_UR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_DL_L_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_L_UL_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_R_DR_D_DL_L(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_U_UR_R_DR_D(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_L_UL_U_UR_R(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_D_DL_L_UL_U(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + const void Explore_AllDirections(PathfindingNode * currentNode, JumpDistancesAndGoalBounds * map); + + void SearchDown(PathfindingNode * currentNode, int jumpDistance); + void SearchDownRight(PathfindingNode * currentNode, int jumpDistance); + void SearchRight(PathfindingNode * currentNode, int jumpDistance); + void SearchUpRight(PathfindingNode * currentNode, int jumpDistance); + void SearchUp(PathfindingNode * currentNode, int jumpDistance); + void SearchUpLeft(PathfindingNode * currentNode, int jumpDistance); + void SearchLeft(PathfindingNode * currentNode, int jumpDistance); + void SearchDownLeft(PathfindingNode * currentNode, int jumpDistance); + + void PushNewNode(PathfindingNode * newSuccessor, PathfindingNode * currentNode, ArrayDirections parentDirection, unsigned int givenCost); + + // 2D array initialization and destruction + template void InitArray(T**& t, int width, int height); + template void DestroyArray(T**& t); + + // Map properties + int m_width, m_height; + + // Open list structures + FastStack* m_fastStack; + SimpleUnsortedPriorityQueue* m_simpleUnsortedPriorityQueue; + + // Precomputed data + JumpDistancesAndGoalBounds** m_jumpDistancesAndGoalBounds; + + // Preallocated nodes + PathfindingNode** m_mapNodes; + + // Search specific info + unsigned short m_currentIteration; // This allows us to know if a node has been touched this iteration (faster than clearing all the nodes before each search) + PathfindingNode* m_goalNode; + int m_goalRow, m_goalCol; +}; + diff --git a/JPSPlusGoalBounding/JPSPlusGoalBounding.sln b/JPSPlusGoalBounding/JPSPlusGoalBounding.sln new file mode 100644 index 0000000..9242058 --- /dev/null +++ b/JPSPlusGoalBounding/JPSPlusGoalBounding.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JPSPlusGoalBounding", "JPSPlusGoalBounding.vcxproj", "{32176719-9104-4AF2-841F-EFCCA868B47A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {32176719-9104-4AF2-841F-EFCCA868B47A}.Debug|Win32.ActiveCfg = Debug|Win32 + {32176719-9104-4AF2-841F-EFCCA868B47A}.Debug|Win32.Build.0 = Debug|Win32 + {32176719-9104-4AF2-841F-EFCCA868B47A}.Release|Win32.ActiveCfg = Release|Win32 + {32176719-9104-4AF2-841F-EFCCA868B47A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/JPSPlusGoalBounding/JPSPlusGoalBounding.sln.docstates.suo b/JPSPlusGoalBounding/JPSPlusGoalBounding.sln.docstates.suo new file mode 100644 index 0000000..d4331fc Binary files /dev/null and b/JPSPlusGoalBounding/JPSPlusGoalBounding.sln.docstates.suo differ diff --git a/JPSPlusGoalBounding/JPSPlusGoalBounding.suo b/JPSPlusGoalBounding/JPSPlusGoalBounding.suo new file mode 100644 index 0000000..1e46a5f Binary files /dev/null and b/JPSPlusGoalBounding/JPSPlusGoalBounding.suo differ diff --git a/JPSPlusGoalBounding/JPSPlusGoalBounding.vcxproj b/JPSPlusGoalBounding/JPSPlusGoalBounding.vcxproj new file mode 100644 index 0000000..f9340a8 --- /dev/null +++ b/JPSPlusGoalBounding/JPSPlusGoalBounding.vcxproj @@ -0,0 +1,123 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {32176719-9104-4AF2-841F-EFCCA868B47A} + Win32Proj + JPSPlusGoalBounding + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + true + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + AnySuitable + Speed + false + false + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + \ No newline at end of file diff --git a/JPSPlusGoalBounding/Map.cpp b/JPSPlusGoalBounding/Map.cpp new file mode 100644 index 0000000..82359fd --- /dev/null +++ b/JPSPlusGoalBounding/Map.cpp @@ -0,0 +1,403 @@ +/* + * Map.cpp + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "Map.h" +#include +#include + +using namespace std; + +static const bool verbose = false; + +/** +* Map::Map() +* +* \brief Create a new map of a particular size. +* +* A map is an array of tiles according to the height and width of the map. +* +* \param wide The new map width +* \param high The new map height +* \return none +*/ +Map::Map(uint32_t wide, uint32_t high) +:width(wide), height(high) +{ + map_name[0] = 0; + land.resize(height*width); + for (uint32_t x = 0; x < land.size(); x++) + land[x] = 1; + +} + +/** +* Map::Map() +* +* \brief Create a new map by loading it from a file. +* +* Creates a new map and initializes it with the file passed to it. +* +* \param filename The path of a file containing a map. +* \return none +*/ +Map::Map(const char *filename) +{ + Load(filename); +} + +/** +* Map::Map() +* +* \brief Create a new map by loading it from a file pointer. +* +* Creates a new map and initializes it with the file pointer passed to it. +* +* \param f A file pointer ready to read the beginning of a map within a file +*/ +Map::Map(FILE *f) +{ + map_name[0] = 0; + land.resize(0); + Load(f); +} + +Map::~Map() +{ +} + +/** +* Map::Scale() + * + * \brief Scale a map to the new size + * + * \param newWidth The new width of the map + * \param newHeight The new height of the map + */ +void Map::Scale(uint32_t newWidth, uint32_t newHeight) +{ + std::vector newLand; + newLand.resize(newWidth*newHeight); + for (uint32_t x = 0; x < newWidth; x++) + { + for (uint32_t y = 0; y < newHeight; y++) + { + newLand[GetIndex(x, y)] = land[GetIndex((x*width)/newWidth, + (y*height)/newHeight)]; + } + } + land = newLand; + width = newWidth; + height = newHeight; + updated = true; + map_name[0] = 0; +} + +/** +* Map::Load() +* +* \brief Resets the current map by loading the file passed in. +* +* Resets the current map by loading the file passed in. +* +* \param filename The file to load +* \return none +*/ +void Map::Load(const char *filename) +{ + land.resize(0); + FILE *f = fopen(filename, "r"); + if (f) + { + Load(f); + fclose(f); + strncpy(map_name, filename, 128); + } + else { + printf("Error! Can't open file %s\n", filename); + width = height = 64; + land.resize(height*width); + + updated = true; + map_name[0] = 0; + } +} + +/** +* Map::Load() +* +* \brief Resets the current map by loading the file from the pointer passed in. +* +* Resets the current map by loading the file from the pointer passed in. +* +* Loads an octile map according to the following format. +* The header includes 4 lines: +* type octile\n +* height \n +* width \n +* map\n +* +* \param f A (open) file pointer read to read from the file. +* \return none +*/ +void Map::Load(FILE *f) +{ + land.resize(0); + + char format[32]; + // ADD ERROR HANDLING HERE + int num = fscanf(f, "type %s\nheight %u\nwidth %u\nmap\n", format, &height, &width); + if (num == 3) + { + if (strcmp(format, "octile") == 0) + { + printf("Loading octile %ux%u\n", width, height); + LoadOctile(f, height, width); + } + } +} + +/** +* Map::LoadOctile() + * + * \brief Helper function for loading an octile map + * + * After the header has been ready, + * following header lines there is a "@" or an "O" for blocked land + * and any other character for unblocked land. + * + * \param f and open file pointer + * \param high The height of the map being loaded (number of lines) + * \param wide The width of the map being loaded (column width) + * \return none + */ +void Map::LoadOctile(FILE *f, int high, int wide) +{ + height = high; + width = wide; + updated = true; + land.resize(high*wide); + for (int y = 0; y < high; y++) + { + for (int x = 0; x < wide; x++) + { + char what; + fscanf(f, "%c", &what); + switch (toupper(what)) + { + case '@': + case 'O': + land[GetIndex(x, y)] = 0; + break; + default: + land[GetIndex(x, y)] = 1; + break; + } + fscanf(f, "\n"); + } + } +} + +/** +* Map::Save() +* +* \brief Saves the current map out to the designated file. +* +* \param filename The filename to save the map in. +* \return none +*/ +void Map::Save(const char *filename) +{ + FILE *f = fopen(filename, "w+"); + if (f) + { + Save(f); + fclose(f); + } + else { + printf("Error! Couldn't open file to save\n"); + } +} + +/** +* Map::Save() +* +* \brief Saves the current map out to the designated file. +* +* Saves the current map out to the designated file. +* +* \param f An open file pointer +* \return none +*/ +void Map::Save(FILE *f) +{ + SaveOctile(f); +} + +/** +* Map::SaveOctile() + * + * \brief Write out using the octile map format + * + * \param f An open file pointer + * \return none + */ +void Map::SaveOctile(FILE *f) +{ + if (f) + { + fprintf(f, "type octile\nheight %u\nwidth %u\nmap\n", height, width); + for (uint32_t y = 0; y < height; y++) + { + for (uint32_t x = 0; x < width; x++) + { + switch (land[GetIndex(x, y)]) + { + case 0: fprintf(f, "@"); break; + default: + case 1: fprintf(f, "."); break; + } + } + fprintf(f, "\n"); + } + } +} + +/** +* Map::GetMapName() + * + * \brief Returns the file name of the map, if available + * + * \return A pointer to a string containing the name of the map. + */ + +const char *Map::GetMapName() +{ + if (map_name[0] == 0) + return ""; + return map_name; +} + + +/** +* Map::GetTerrainType() + * + * \brief Get the terrain at a particular coordinate. + * + * \param x The x-coordinate to query + * \param y The y-coordinate to query + * \return The terrain at that coordinate + */ +tTerrain Map::GetTerrainType(uint32_t x, uint32_t y) +{ + int index = GetIndex(x, y); + if (index == -1) + return kOutOfBounds; + if (land[index] == 0) + return kOutOfBounds; + return kGround; +} + +/** +* Map::SetTerrainType() + * + * \brief Set the terrain at a particular coordinate. + * + * \param x The x-coordinate to set + * \param y The y-coordinate to set + * \param terrain The terrain for that coordinate + * \return none + */ +void Map::SetTerrainType(uint32_t x, uint32_t y, tTerrain terrain) +{ + updated = true; + int index = GetIndex(x, y); + if (index == -1) + return; + if (terrain == kOutOfBounds) + land[index] = 0; + else + land[index] = 1; +} + +/** +* Map::SetTerrainType() + * + * \brief Set all the terrain between two points to be the same + * + * \param x1 The first x-coordinate to set + * \param y1 The first y-coordinate to set + * \param x2 The second x-coordinate to set + * \param y2 The second y-coordinate to set + * \param terrain The terrain for the line between the coordinates + * \return none + */ +void Map::SetTerrainType(int32_t x1, int32_t y1, + int32_t x2, int32_t y2, tTerrain t) +{ + updated = true; + //printf("---> (%d, %d) to (%d, %d)\n", x1, y1, x2, y2); + double xdiff = (int)x1-(int)x2; + double ydiff = (int)y1-(int)y2; + double dist = sqrt(xdiff*xdiff + ydiff*ydiff); + SetTerrainType(x1, y1, t); + for (double c = 0; c < dist; c += 0.5) + { + double ratio = c/dist; + double newx = (double)x1-xdiff*ratio; + double newy = (double)y1-ydiff*ratio; + SetTerrainType((uint32_t)newx, (uint32_t)newy, t); + } + SetTerrainType(x2, y2, t); +} + +/** +* Map::SetTerrainType() + * + * \brief Set the terrain at a radius from a point to be the same + * + * \param x The center x-coordinate + * \param y The center y-coordinate + * \param radius The radius of the circle + * \param terrain The terrain for the circle + * \return none + */ +void Map::SetTerrainType(int32_t x, int32_t y, int32_t radius, tTerrain t) +{ + updated = true; + for (int x2 = -radius; x2 <= radius; x2++) + { + for (int y2 = -radius; y2 <= radius; y2++) + { + if ((x+x2 >= 0) && (y+y2 >= 0)) + if ((x2*x2+y2*y2) < radius*radius) + SetTerrainType(x+x2, y+y2, t); + } + } +} diff --git a/JPSPlusGoalBounding/Map.h b/JPSPlusGoalBounding/Map.h new file mode 100644 index 0000000..1b5a785 --- /dev/null +++ b/JPSPlusGoalBounding/Map.h @@ -0,0 +1,126 @@ +/* + * Map.h + * + * Copyright (c) 2007, Nathan Sturtevant + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of Alberta nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY NATHAN STURTEVANT ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _MSC_VER +#include "stdafx.h" +#else +#include +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 4294967295U +#endif + +#ifndef MAP_H +#define MAP_H + +static const double ONE = 1.0f; +static const double TWO = 2.0f; +static const double ROOT_TWO = 1.414213562f;//or 1.5f if desired +static const double ONE_OVER_ROOT_TWO = 1.0/ROOT_TWO;//0.707106781f; + +#include +#include +#include +#include +#include +#include +#include + +//#define uint32_t unsigned int +//#define int32_t int + +/** +* Terrain is simple here, either out-of-bounds or passable. + * In reality a much more complex mode could be used for passibility, + * but this suffices for now. + */ + +enum tTerrain { + kOutOfBounds, + kGround +}; + +/** +* + * Map + * + * This code is simplified from a more complex map structure. + * This map class + * + */ +class Map { +public: + Map(uint32_t width, uint32_t height); + Map(const char *filename); + Map(Map *); + Map(FILE *); + ~Map(); + void Load(const char *filename); + void Load(FILE *f); + void Scale(uint32_t newWidth, uint32_t newHeight); + void Save(const char *filename); + void Save(FILE *f); + const char *GetMapName(); + + /** return the width of the map */ + inline uint32_t GetMapWidth() const { return width; } + /** return the height of the map */ + inline uint32_t GetMapHeight() const { return height; } + + tTerrain GetTerrainType(uint32_t x, uint32_t y); + void SetTerrainType(uint32_t x, uint32_t y, tTerrain); + void SetTerrainType(int32_t x1, int32_t y1, + int32_t x2, int32_t y2, tTerrain); + void SetTerrainType(int32_t x, int32_t y, int32_t radius, tTerrain); +private: + /** Given an x/y coordinate, compute the index in the land vector */ + inline int GetIndex(uint32_t x, uint32_t y) + { + if (x >= width) return -1; + if (y >= height) return -1; + return y*width+x; + } + /** Given a location in the land vector, get the x/y coordinate */ + inline void GetCoordinate(int loc, uint32_t &x, uint32_t &y) + { + y = loc/width; + x = loc%width; + } + + void LoadOctile(FILE *f, int height, int width); + void SaveOctile(FILE *f); + void DrawLandQuickly(); + uint32_t width, height; + std::vector land; + char map_name[128]; + bool updated; +}; + +#endif diff --git a/JPSPlusGoalBounding/Maps/maze-100-1.map b/JPSPlusGoalBounding/Maps/maze-100-1.map new file mode 100644 index 0000000..0f85539 --- /dev/null +++ b/JPSPlusGoalBounding/Maps/maze-100-1.map @@ -0,0 +1,104 @@ +type octile +height 100 +width 100 +map +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@.......@.......@.@...........@...............@...@.....@...@.@.........@.......@.......@........... +@.@@@@@.@@@@@.@.@.@@@.@@@@@.@@@.@.@.@@@@@@@@@@@.@.@.@@@.@.@.@.@@@.@@@@@@@.@@@.@@@.@@@@@@@@@.@@@@@@@. +@.....@.......@.....@.....@.....@.@...........@.@...@...@.@.@...@...@.....@.....@.........@.....@... +@.@@@.@@@@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@@@@.@@@.@@@@@@@.@.@.@.@@@.@.@.@.@@@.@@@.@.@@@.@@@@@@@@@.@.@@ +@.@.@.................@.....@...@.....@...@.@...@.....@.@.@.@.....@...@.@.....@.@...@.......@...@... +@.@.@@@@@.@@@@@@@@@@@@@.@@@.@.@.@@@.@.@.@.@.@.@@@.@.@@@.@.@.@@@@@@@@@@@.@.@@@@@.@.@@@@@.@@@@@.@@@@@. +@.@.....@.@.........@...@.....@.@...@.@.@...@.....@...@.@.@.........@...@.@...@.@.@.....@.......@... +@.@@@.@.@@@.@@@@@.@@@.@.@.@@@@@.@.@@@.@.@@@@@@@.@@@@@.@.@.@@@@@@@@@.@.@@@.@@@.@.@@@@@@@.@.@@@@@@@@@. +@...@.@.........@.@...@.@.@...@...@...@.....@.@.@...@.@.....@.@.......@.@.....@.@.......@.....@...@. +@@@.@.@@@@@@@.@@@.@.@.@@@.@@@.@@@@@@@.@@@.@@@.@.@.@@@.@@@@@@@.@.@.@@@.@.@.@@@@@@@.@@@@@@@.@@@@@.@.@. +@...@...@...@.@.....@.@.....@.@.....@...@...@...@...@.....@...@.@...@...@.......@...@.....@.....@... +@.@@@@@.@.@.@@@@@@@@@.@@@.@.@.@.@@@.@@@.@@@.@.@@@@@.@.@@@.@.@@@.@@@.@.@@@@@@@.@@@@@.@.@@@@@.@@@@@@@@ +@.@...@.@.@.........@...@.@...@.@...@.......@.....@.@...@.@.......@.@.......@.....@.....@.@.@....... +@.@.@@@@@.@@@.@@@@@.@.@.@.@.@@@.@.@.@@@@@@@@@@@.@@@.@@@@@.@.@@@@@@@.@@@.@@@@@.@@@.@@@@@.@.@.@.@@@.@@ +@.@...@...@.@.@...@.@.@.@.@.@...@.@...@.........@.........@.@.....@.@.@.@...@.@.@.....@...@.....@... +@.@@@.@.@@@.@@@.@.@.@@@.@.@@@.@@@.@@@@@.@@@@@@@@@@@@@@@.@@@.@.@@@.@.@.@@@.@.@.@.@@@@@.@@@.@@@.@.@@@. +@.....@.@...@...@.@.@...@...@...@.@.........@.......@.@.@.@.@...@.@.....@.@...@.....@.@.....@.@.@... +@.@@@@@.@.@@@.@.@@@.@.@.@.@@@@@@@.@.@.@.@@@@@@@.@@@@@.@.@.@@@@@@@.@@@@@.@.@@@@@.@@@.@.@@@.@@@@@.@.@@ +@.@.....@.....@...@.@.@.@.......@.@.@.@.@.........@...@.@.......@.....@.@.....@.@...@...@...@...@... +@.@.@@@.@@@.@@@@@.@.@.@@@@@@@@@.@.@.@@@@@.@@@@@@@.@@@.@.@@@@@@@.@@@.@@@.@@@@@.@@@.@@@.@@@@@@@@@.@@@. +@.@...@.@.....@.......@...@.......@...@.........@...@.....@.....@...@...@...@.@.@...........@.....@. +@.@@@.@@@@@@@@@@@@@@@@@@@.@@@.@@@@@.@@@@@.@@@@@@@@@.@@@.@@@.@@@@@@@.@.@@@.@@@.@.@@@@@@@@@@@.@@@@@@@. +@...@...........@.......@.....@...@...@...@.....@...@.....@.....@.....@.......@.....@.....@......... +@.@@@@@@@.@.@@@@@@@.@@@.@@@@@@@.@.@@@.@.@@@.@@@.@.@@@.@@@@@@@@@.@@@@@.@.@.@@@@@@@.@.@.@@@@@.@@@@@@@@ +@.@...@...@.@.......@.....@...@.@.....@...@.@...@...@...@.......@...@.@.@.@.@.....@.@...@...@....... +@.@@@.@.@@@@@.@@@@@@@.@.@@@.@.@.@@@@@@@@@.@.@@@.@.@@@@@.@.@@@@@@@.@.@@@.@@@.@.@.@@@.@@@.@@@.@@@@@.@@ +@.....@.....@.@.@.@...@.....@...@.........@.@...@.....@.@...@.....@.@.......@.@.@.@.@...........@... +@@@@@@@@@@@.@.@.@.@@@.@@@.@@@@@@@.@@@@@@@@@.@.@@@@@@@.@.@@@.@.@@@@@.@.@@@@@@@.@@@.@@@.@@@@@@@@@.@@@. +@...........@...@.......@.......@...@.......@.@.......@...@.@.@.@...@.....@...@.....@.@.........@... +@.@@@@@@@@@@@@@.@.@@@@@@@@@@@@@.@@@.@.@@@@@.@.@.@@@@@@@.@@@.@.@.@@@@@.@.@.@.@@@.@@@.@.@@@.@@@@@@@.@@ +@.........@.....@.@...@.......@.....@.@...@.@...@.........@.@.......@.@.@.@.....@...@...@.......@... +@.@@@@@@@.@.@@@@@.@.@@@.@@@@@.@@@@@@@.@.@.@@@@@@@@@@@@@@@.@.@@@.@@@.@.@@@.@@@@@@@.@.@@@@@.@@@@@.@@@. +@.......@.....@.....@...@...@...@.....@.@...........@...@.@...@.@.@...@.......@...@.@.....@...@.@... +@.@@@@@@@@@.@@@.@@@@@.@@@@@.@@@.@.@@@@@.@@@@@@@@@@@.@.@.@.@@@.@.@.@@@@@@@@@@@.@.@@@@@@@@@@@.@@@.@.@@ +@.@.......@.@...@.@...@.@.........@.....@.......@...@.@.@.@...@...@.@.....@...@.@...@.....@...@.@... +@.@.@@@.@@@.@.@@@.@.@@@.@@@@@@@@@@@.@.@@@.@.@@@@@.@@@.@.@.@.@@@.@@@.@.@@@.@@@@@.@.@.@@@.@.@.@@@.@@@. +@.@...@...@.@.@...@...@.............@.@...@.@.....@...@.@.....@.@.....@.@.@.....@.@.@...@...@.@...@. +@@@@@.@@@.@@@.@.@@@@@.@.@@@@@.@.@@@@@@@.@.@@@.@@@@@.@@@.@@@@@.@@@.@.@@@.@.@.@@@@@.@@@.@@@@@.@.@@@.@. +@...@...@.@.@.@.........@.....@.@.@...@.@...@.....@...@...@.......@.@.@.....@.............@.@...@... +@@@.@@@.@.@.@.@@@@@@@@@@@.@@@@@@@.@.@@@@@.@@@@@@@.@@@.@.@@@@@.@@@@@@@.@@@.@@@.@@@@@@@@@@@.@@@.@@@@@. +@.@.....@...@.......@.....@.....@.......@...@.......@.@.....@.@...@.....@.@.@.@.@.........@...@..... +@.@@@@@@@@@.@@@.@@@.@@@.@@@.@.@@@@@@@.@@@.@.@.@.@.@@@.@@@@@.@@@.@.@.@@@@@@@.@.@.@.@@@.@@@@@.@@@.@@@@ +@...@.........@.@.@.@.....@.@.........@...@...@.@.@.....@.......@.@.....@...@.@.@...@.@.......@...@. +@@@.@.@@@@@@@.@.@.@.@@@@@.@.@@@@@.@.@@@.@@@@@.@@@@@@@@@.@.@@@@@@@.@.@@@.@.@.@.@.@@@.@@@@@.@@@.@.@@@. +@...@.@.....@...@...@...@.@...@.@.@.@.....@...@.........@.@.......@.@.@...@.@.....@.@.....@...@...@. +@.@.@.@@@.@@@@@@@.@@@@@.@.@@@.@.@@@.@.@@@.@@@@@.@.@@@@@@@.@@@.@@@@@@@.@.@.@@@@@.@@@.@.@@@@@@@.@.@@@. +@.@.@...@.....@...@.....@...@...@...@...@.@.....@...@...@.@.@.@.....@...@.@.....@...@.@...@...@..... +@.@@@@@.@.@.@@@.@@@@@@@.@.@@@.@@@.@@@@@.@@@.@.@@@.@@@.@.@.@.@.@.@@@@@.@@@@@.@@@@@.@@@.@@@.@@@.@.@@@@ +@.....@.@.@.@...@.......@...@.@...@.......@.@...@.@...@.@...@...@.@.@...........@.@.......@.@...@... +@@@@@.@.@.@.@.@@@.@@@@@.@@@.@.@@@.@@@.@@@@@.@@@.@@@.@@@.@@@@@@@.@.@.@@@@@@@@@@@@@.@@@@@@@@@.@.@@@@@. +@.....@.@.@.@.@.@...@.@...@.@...@...@.......@...@...@...@.....@.@...........@.@.............@....... +@@@@@.@.@@@.@.@.@@@.@.@.@.@.@@@@@@@.@@@@@@@@@.@@@.@@@.@@@.@@@.@@@.@@@.@@@@@.@.@@@.@@@@@@@@@.@@@@@@@. +@.@...@.....@.@...@.@.@.@...@...............@.....@.@.@.....@...@.@.@.@.....@...@.@.......@.@...@... +@.@@@.@@@.@@@.@.@.@.@.@.@@@@@.@@@@@@@@@@@@@@@@@@@@@.@.@@@@@.@@@.@@@.@@@@@.@@@.@@@.@.@@@@@.@.@@@.@@@. +@.......@...@.@.@.@.@...@.......@.................@.@.@...@...@.......@...@...@...@.@.....@.......@. +@.@@@@@.@@@.@.@@@.@.@.@@@@@@@.@.@.@@@@@@@.@.@@@.@.@.@.@.@.@.@@@@@@@@@.@.@@@@@.@.@@@.@.@@@.@@@@@@@.@. +@...@...@...@.@...@.@.......@.@.@...@...@.@.@...@.@.@...@...@.@...@.....@.....@.@...@...@.@...@...@. +@.@.@@@@@.@@@.@@@.@.@@@@@@@.@.@.@@@.@.@.@@@@@.@@@.@.@.@@@@@@@.@.@@@.@@@@@.@@@@@.@@@@@@@.@.@.@.@.@.@@ +@.@.......@.@.@...@.@.....@.@.@.....@.@.......@.....@.@.@.........@.@.@.................@.@.@...@... +@.@@@@@@@@@.@.@.@@@.@.@.@@@.@@@@@.@@@.@@@@@@@@@@@@@@@.@.@@@.@@@@@.@.@.@.@@@@@@@@@@@@@@@.@@@.@@@@@@@. +@...@.......@.@.@.@.@.@...@.....@.@.@.....@.......@.......@.@...@...@.@...@...@...........@.@.@...@. +@.@@@@@@@@@.@.@.@.@.@@@.@.@@@@@.@.@.@@@@@.@.@@@@@.@@@@@@@.@.@@@.@@@@@.@.@@@.@@@@@@@@@@@@@@@.@.@.@@@. +@.@.........@.@...@.....@...@.@.@.@.@...@.....@...@...@...@.....@.....@.@.....@.............@....... +@.@.@@@@@.@@@.@.@@@@@@@.@@@.@.@.@.@.@.@.@@@@@@@.@@@.@.@@@@@.@@@@@.@@@@@.@.@@@@@.@@@@@@@@@@@@@@@.@.@@ +@...@.@.....@.@.@.....@.@.@...@.@.@...@...@...@.@...@.@.......@...@...@.@.....@.....@.....@.....@.@. +@@@@@.@.@@@@@.@.@@@.@@@@@.@@@.@.@.@@@@@@@.@.@.@.@@@.@@@@@.@@@.@.@@@.@.@.@@@.@@@@@@@.@.@.@.@.@@@.@@@. +@.@.......@...@...@...@.......@.@...@.....@.@...@...@.....@...@.....@.......@.......@.@.@.@...@..... +@.@.@@@.@@@@@@@.@@@.@.@@@@@@@@@.@@@.@.@@@.@.@@@@@.@@@.@@@@@.@@@.@@@@@@@@@@@@@.@@@@@@@.@@@.@@@.@.@@@@ +@.....@...@...@.....@.............@...@...@.........@.@...@.@.@...@.....@...@.....@...@.@.@...@.@... +@.@@@@@@@@@.@.@.@@@@@@@@@@@.@.@@@@@@@@@.@@@@@@@@@.@@@.@@@.@.@.@@@.@@@@@.@.@.@@@.@.@.@@@.@.@.@@@.@@@. +@.@.........@...@.....@.@.@.@.@.......@...@.@.........@...@.@.@...@.....@.@.....@.@.@.....@...@.@... +@.@@@.@@@@@@@@@@@.@@@.@.@.@@@@@@@@@.@.@@@.@.@@@.@@@@@.@.@.@.@.@@@.@.@@@@@.@@@@@@@@@.@.@@@@@@@@@.@.@@ +@.@.@.@...@.......@.....@.@.........@...@.....@...@.@.@.@.@.....@.@.@.....@.........@.........@...@. +@.@.@.@.@@@.@@@@@@@@@@@.@.@@@.@.@.@.@@@.@.@.@@@@@.@.@.@.@@@.@@@@@.@.@.@@@.@.@.@@@@@@@@@.@@@@@@@@@.@. +@.@.@.@...@.......@.........@.@.@.@...@.@.@.@.@.@.@.@.@...@...@.....@...@.@.@.@.@.........@...@...@. +@.@.@@@.@.@@@@@@@.@@@@@@@@@.@@@@@.@@@.@.@@@@@.@.@.@.@@@@@.@@@.@@@@@.@@@.@@@.@.@.@.@.@@@@@.@@@.@@@.@. +@.....@.@.....@.......@.@.....@.....@.@.......@...@.....@...@.@.......@.....@.@.@.@...@...@.....@... +@.@@@.@@@@@@@.@@@.@@@.@.@.@@@@@@@@@@@.@@@@@@@.@.@@@@@.@.@@@.@.@@@@@@@@@@@@@@@.@.@@@@@.@@@.@.@.@@@@@@ +@.@...@.......@...@...@...@.......@...@...@.@.@.....@.@.....@.@...............@.....@...@...@.@..... +@@@@@.@.@@@@@.@@@@@.@@@.@@@.@@@@@.@.@@@.@.@.@.@.@.@@@.@@@@@.@.@@@.@@@@@@@@@@@@@@@.@.@.@@@@@@@@@.@@@. +@.@.@.@.@...@.......@...@...@.....@.....@.@...@.@.@...@...@.@...@.....@.........@.@.@.@.....@...@... +@.@.@.@.@@@.@@@@@@@@@.@@@.@.@@@@@.@.@@@@@.@.@@@.@@@@@.@.@.@@@.@@@.@@@.@@@@@.@.@@@@@.@.@@@@@.@.@@@.@@ +@...@.@.@...@.......@.....@.@...@.@...@...@...@.@.....@.@.....@.....@.@.....@...@...@.@.........@... +@@@.@.@.@.@@@.@@@@@.@@@.@@@@@@@.@.@.@@@.@@@@@@@.@.@.@@@.@@@@@@@@@@@@@.@.@@@@@.@@@.@.@.@.@@@@@@@@@.@@ +@...@...@.....@.......@.@.......@.@.@.......@...@.@...@.@...@.........@.....@.@...@.@.@.......@..... +@@@.@@@@@.@@@@@.@@@@@@@@@@@.@@@.@.@.@@@.@@@@@.@@@@@.@.@.@.@.@.@@@@@@@@@.@@@.@@@.@.@@@.@@@@@@@.@@@@@. +@.......@.@...@.............@.@.@.@.@...@.....@...@.@.@.@.@.@...@.....@.@.....@.@.@...@...@.@.@..... +@.@@@@@@@.@.@.@@@@@@@@@@@.@@@.@@@.@@@.@@@.@@@@@.@.@@@.@.@.@.@@@.@@@.@@@.@@@.@.@.@@@@@.@.@.@.@.@.@@@. +@.......@.@.@...........@...@.....@.....@.@...@.@...@.@.@.@.....@...@...@...@.@.....@...@.@...@.@... +@@@.@@@.@.@@@.@.@@@@@.@.@@@.@.@@@@@.@@@@@.@.@@@.@@@@@.@.@.@@@.@.@.@@@.@@@.@@@.@.@@@.@@@@@.@@@.@.@@@@ +@.@.@...@...@.@...@...@...@.........@.....@.....@.......@...@.@.@.....@.@...@.@...@.....@.@...@..... +@.@.@@@.@@@.@@@@@@@.@@@@@.@@@@@.@@@@@@@.@@@.@@@@@.@@@.@@@.@.@@@.@.@@@@@.@@@.@.@@@@@.@@@.@.@@@.@@@@@. +@.@.@.@...@.@.........@.....@.@...@...@.@...@.......@...@.@.@.@.@.@.....@...@.....@...@.@.@.....@... +@.@.@.@@@.@.@@@@@.@@@@@@@@@.@.@@@@@.@.@.@.@.@@@@@@@@@@@.@@@.@.@.@.@@@@@.@.@@@@@.@.@@@.@@@.@.@@@@@.@. +@.@...@...@.@...@.......@.....@.....@.@.@.@.......@...@.....@.@.@...@...@...@.@.@.@...@...@.@.....@. +@.@.@@@@@.@.@.@.@@@.@.@@@@@@@.@.@@@@@.@.@@@@@@@@@.@@@.@@@@@@@.@.@@@.@@@.@@@.@.@@@.@.@@@.@@@.@.@@@@@. +@.@.@.....@.@.@...@.@.@.@.@.....@.....@.@.........@...........@.@.........@.@...@.@.@...@...@.@...@. +@.@.@@@.@@@.@.@@@.@.@@@.@.@.@@@.@.@@@@@.@.@@@@@@@@@.@@@.@@@@@@@.@@@@@@@@@@@.@.@@@.@.@.@@@@@@@.@.@@@. +@.....@.........@...@.........@.@...@.........@.......@.....................@.......@.........@..... diff --git a/JPSPlusGoalBounding/Maps/maze-100-1.map.pre b/JPSPlusGoalBounding/Maps/maze-100-1.map.pre new file mode 100644 index 0000000..4380c9e Binary files /dev/null and b/JPSPlusGoalBounding/Maps/maze-100-1.map.pre differ diff --git a/JPSPlusGoalBounding/Maps/maze-100-1.map.scen b/JPSPlusGoalBounding/Maps/maze-100-1.map.scen new file mode 100644 index 0000000..fc5c8ce --- /dev/null +++ b/JPSPlusGoalBounding/Maps/maze-100-1.map.scen @@ -0,0 +1,2431 @@ +version 1 +1 maze-100-1.map 100 100 35 75 36 71 5 +1 maze-100-1.map 100 100 14 99 11 96 6 +1 maze-100-1.map 100 100 1 17 1 22 5 +1 maze-100-1.map 100 100 37 6 38 11 6 +1 maze-100-1.map 100 100 31 63 27 61 6 +1 maze-100-1.map 100 100 93 86 92 89 4 +1 maze-100-1.map 100 100 39 8 42 11 6 +1 maze-100-1.map 100 100 1 78 5 78 6 +1 maze-100-1.map 100 100 91 50 85 51 7 +1 maze-100-1.map 100 100 18 69 15 71 5 +2 maze-100-1.map 100 100 71 11 71 7 8 +2 maze-100-1.map 100 100 9 55 8 59 9 +2 maze-100-1.map 100 100 41 43 45 44 9 +2 maze-100-1.map 100 100 17 20 23 17 11 +2 maze-100-1.map 100 100 56 9 59 1 11 +2 maze-100-1.map 100 100 91 29 85 33 10 +2 maze-100-1.map 100 100 1 30 6 33 8 +2 maze-100-1.map 100 100 4 29 10 27 10 +2 maze-100-1.map 100 100 71 4 71 11 11 +2 maze-100-1.map 100 100 85 99 89 93 10 +3 maze-100-1.map 100 100 93 79 87 75 14 +3 maze-100-1.map 100 100 75 67 71 59 12 +3 maze-100-1.map 100 100 1 68 3 75 13 +3 maze-100-1.map 100 100 29 81 26 81 15 +3 maze-100-1.map 100 100 39 6 42 3 12 +3 maze-100-1.map 100 100 82 9 83 3 15 +3 maze-100-1.map 100 100 3 69 3 77 12 +3 maze-100-1.map 100 100 32 89 37 89 15 +3 maze-100-1.map 100 100 93 67 99 63 14 +3 maze-100-1.map 100 100 27 49 22 55 15 +4 maze-100-1.map 100 100 93 62 96 75 18 +4 maze-100-1.map 100 100 97 59 91 66 17 +4 maze-100-1.map 100 100 99 51 95 41 18 +4 maze-100-1.map 100 100 41 13 33 7 18 +4 maze-100-1.map 100 100 19 32 23 25 17 +4 maze-100-1.map 100 100 24 79 21 72 16 +4 maze-100-1.map 100 100 98 11 93 13 19 +4 maze-100-1.map 100 100 17 89 19 96 17 +4 maze-100-1.map 100 100 36 55 47 59 19 +4 maze-100-1.map 100 100 85 21 99 23 16 +5 maze-100-1.map 100 100 17 1 4 1 21 +5 maze-100-1.map 100 100 15 75 23 72 23 +5 maze-100-1.map 100 100 29 56 37 69 23 +5 maze-100-1.map 100 100 21 9 15 9 22 +5 maze-100-1.map 100 100 97 47 93 39 20 +5 maze-100-1.map 100 100 25 88 39 85 23 +5 maze-100-1.map 100 100 43 28 28 35 22 +5 maze-100-1.map 100 100 57 33 67 35 20 +5 maze-100-1.map 100 100 82 89 79 78 22 +5 maze-100-1.map 100 100 25 49 19 47 20 +6 maze-100-1.map 100 100 71 33 77 22 25 +6 maze-100-1.map 100 100 71 29 65 27 24 +6 maze-100-1.map 100 100 62 21 59 32 26 +6 maze-100-1.map 100 100 67 88 75 88 24 +6 maze-100-1.map 100 100 65 13 76 1 27 +6 maze-100-1.map 100 100 69 17 61 11 26 +6 maze-100-1.map 100 100 43 81 35 75 26 +6 maze-100-1.map 100 100 7 68 5 82 26 +6 maze-100-1.map 100 100 5 45 3 35 24 +6 maze-100-1.map 100 100 26 77 11 74 26 +7 maze-100-1.map 100 100 76 5 75 19 31 +7 maze-100-1.map 100 100 7 15 11 29 30 +7 maze-100-1.map 100 100 85 61 77 51 30 +7 maze-100-1.map 100 100 29 25 15 29 30 +7 maze-100-1.map 100 100 29 37 28 31 29 +7 maze-100-1.map 100 100 29 89 17 83 30 +7 maze-100-1.map 100 100 29 57 39 67 28 +7 maze-100-1.map 100 100 13 26 17 32 28 +7 maze-100-1.map 100 100 77 20 77 35 31 +7 maze-100-1.map 100 100 37 7 23 7 30 +8 maze-100-1.map 100 100 25 74 15 79 35 +8 maze-100-1.map 100 100 51 2 56 11 34 +8 maze-100-1.map 100 100 61 37 59 23 32 +8 maze-100-1.map 100 100 25 25 9 33 32 +8 maze-100-1.map 100 100 41 45 49 47 34 +8 maze-100-1.map 100 100 73 91 79 97 32 +8 maze-100-1.map 100 100 85 68 65 80 32 +8 maze-100-1.map 100 100 62 85 73 95 35 +8 maze-100-1.map 100 100 47 29 41 19 32 +8 maze-100-1.map 100 100 83 82 80 99 32 +9 maze-100-1.map 100 100 61 79 49 71 36 +9 maze-100-1.map 100 100 81 13 88 29 37 +9 maze-100-1.map 100 100 31 6 25 21 39 +9 maze-100-1.map 100 100 33 51 39 67 38 +9 maze-100-1.map 100 100 25 81 21 87 38 +9 maze-100-1.map 100 100 37 31 23 39 38 +9 maze-100-1.map 100 100 81 27 67 37 36 +9 maze-100-1.map 100 100 33 53 46 57 39 +9 maze-100-1.map 100 100 24 5 13 19 37 +9 maze-100-1.map 100 100 51 98 57 88 38 +10 maze-100-1.map 100 100 88 51 98 71 42 +10 maze-100-1.map 100 100 29 89 10 83 43 +10 maze-100-1.map 100 100 57 88 69 79 41 +10 maze-100-1.map 100 100 64 83 57 91 41 +10 maze-100-1.map 100 100 85 56 77 63 43 +10 maze-100-1.map 100 100 85 41 84 61 41 +10 maze-100-1.map 100 100 63 93 77 89 42 +10 maze-100-1.map 100 100 59 54 46 53 40 +10 maze-100-1.map 100 100 29 37 18 51 43 +10 maze-100-1.map 100 100 27 60 21 41 41 +11 maze-100-1.map 100 100 19 63 31 61 46 +11 maze-100-1.map 100 100 11 93 27 85 44 +11 maze-100-1.map 100 100 78 13 75 33 47 +11 maze-100-1.map 100 100 35 18 57 11 45 +11 maze-100-1.map 100 100 76 63 83 46 46 +11 maze-100-1.map 100 100 37 7 22 17 45 +11 maze-100-1.map 100 100 36 83 24 87 44 +11 maze-100-1.map 100 100 35 41 34 67 45 +11 maze-100-1.map 100 100 9 59 1 73 46 +11 maze-100-1.map 100 100 46 51 58 53 46 +12 maze-100-1.map 100 100 24 1 39 13 51 +12 maze-100-1.map 100 100 31 61 23 62 51 +12 maze-100-1.map 100 100 81 47 97 72 51 +12 maze-100-1.map 100 100 77 57 99 59 48 +12 maze-100-1.map 100 100 73 19 68 9 51 +12 maze-100-1.map 100 100 63 95 75 81 50 +12 maze-100-1.map 100 100 18 29 39 18 50 +12 maze-100-1.map 100 100 21 26 5 33 49 +12 maze-100-1.map 100 100 81 21 92 11 49 +12 maze-100-1.map 100 100 57 35 46 7 51 +13 maze-100-1.map 100 100 33 56 49 63 53 +13 maze-100-1.map 100 100 16 39 46 37 54 +13 maze-100-1.map 100 100 11 31 15 42 55 +13 maze-100-1.map 100 100 15 17 3 6 55 +13 maze-100-1.map 100 100 75 76 93 76 54 +13 maze-100-1.map 100 100 97 82 89 89 55 +13 maze-100-1.map 100 100 84 77 71 75 55 +13 maze-100-1.map 100 100 5 59 15 34 55 +13 maze-100-1.map 100 100 27 69 23 42 55 +13 maze-100-1.map 100 100 24 69 19 54 52 +14 maze-100-1.map 100 100 49 79 46 91 57 +14 maze-100-1.map 100 100 51 91 53 96 57 +14 maze-100-1.map 100 100 15 42 12 33 58 +14 maze-100-1.map 100 100 82 65 92 69 58 +14 maze-100-1.map 100 100 5 81 5 50 59 +14 maze-100-1.map 100 100 23 8 29 17 57 +14 maze-100-1.map 100 100 32 31 9 40 58 +14 maze-100-1.map 100 100 17 98 35 99 59 +14 maze-100-1.map 100 100 89 95 95 79 58 +14 maze-100-1.map 100 100 97 58 73 71 59 +15 maze-100-1.map 100 100 17 81 11 59 60 +15 maze-100-1.map 100 100 17 56 23 54 62 +15 maze-100-1.map 100 100 58 9 77 11 63 +15 maze-100-1.map 100 100 57 15 59 23 62 +15 maze-100-1.map 100 100 1 32 20 31 60 +15 maze-100-1.map 100 100 27 86 17 98 62 +15 maze-100-1.map 100 100 46 7 71 7 63 +15 maze-100-1.map 100 100 99 49 91 23 62 +15 maze-100-1.map 100 100 66 31 85 20 60 +15 maze-100-1.map 100 100 82 83 73 95 61 +16 maze-100-1.map 100 100 83 57 65 74 67 +16 maze-100-1.map 100 100 61 67 41 97 66 +16 maze-100-1.map 100 100 11 69 19 47 66 +16 maze-100-1.map 100 100 40 43 55 40 66 +16 maze-100-1.map 100 100 97 34 97 13 67 +16 maze-100-1.map 100 100 80 69 98 67 66 +16 maze-100-1.map 100 100 75 57 79 42 67 +16 maze-100-1.map 100 100 48 61 63 81 67 +16 maze-100-1.map 100 100 57 69 59 85 66 +16 maze-100-1.map 100 100 30 89 9 96 66 +17 maze-100-1.map 100 100 61 34 49 1 71 +17 maze-100-1.map 100 100 93 33 97 58 69 +17 maze-100-1.map 100 100 53 1 68 19 69 +17 maze-100-1.map 100 100 13 23 25 25 70 +17 maze-100-1.map 100 100 99 45 83 19 70 +17 maze-100-1.map 100 100 99 77 87 59 70 +17 maze-100-1.map 100 100 40 79 11 81 69 +17 maze-100-1.map 100 100 67 60 45 53 69 +17 maze-100-1.map 100 100 23 91 1 82 71 +17 maze-100-1.map 100 100 79 81 61 93 70 +18 maze-100-1.map 100 100 99 52 98 19 74 +18 maze-100-1.map 100 100 49 31 55 1 72 +18 maze-100-1.map 100 100 25 46 44 43 72 +18 maze-100-1.map 100 100 83 30 52 19 72 +18 maze-100-1.map 100 100 89 57 91 39 72 +18 maze-100-1.map 100 100 81 20 99 52 74 +18 maze-100-1.map 100 100 69 11 99 21 72 +18 maze-100-1.map 100 100 41 71 29 45 74 +18 maze-100-1.map 100 100 79 69 97 76 73 +18 maze-100-1.map 100 100 72 81 81 81 73 +19 maze-100-1.map 100 100 71 7 87 33 78 +19 maze-100-1.map 100 100 43 1 17 3 76 +19 maze-100-1.map 100 100 93 47 78 13 77 +19 maze-100-1.map 100 100 48 69 49 85 77 +19 maze-100-1.map 100 100 31 26 57 21 79 +19 maze-100-1.map 100 100 7 55 4 41 77 +19 maze-100-1.map 100 100 45 58 59 59 79 +19 maze-100-1.map 100 100 41 26 9 39 77 +19 maze-100-1.map 100 100 59 16 49 6 76 +19 maze-100-1.map 100 100 44 55 47 76 78 +20 maze-100-1.map 100 100 65 4 99 16 82 +20 maze-100-1.map 100 100 47 31 27 39 80 +20 maze-100-1.map 100 100 34 11 9 19 83 +20 maze-100-1.map 100 100 17 49 26 35 81 +20 maze-100-1.map 100 100 77 44 83 56 80 +20 maze-100-1.map 100 100 39 39 20 37 81 +20 maze-100-1.map 100 100 98 35 93 21 81 +20 maze-100-1.map 100 100 69 37 49 13 80 +20 maze-100-1.map 100 100 8 37 5 69 81 +20 maze-100-1.map 100 100 73 29 99 17 82 +21 maze-100-1.map 100 100 81 14 94 1 86 +21 maze-100-1.map 100 100 71 10 88 33 86 +21 maze-100-1.map 100 100 9 41 2 33 85 +21 maze-100-1.map 100 100 51 97 87 65 84 +21 maze-100-1.map 100 100 83 57 99 65 84 +21 maze-100-1.map 100 100 36 49 21 39 87 +21 maze-100-1.map 100 100 62 87 53 67 87 +21 maze-100-1.map 100 100 74 49 68 65 84 +21 maze-100-1.map 100 100 83 76 95 79 87 +21 maze-100-1.map 100 100 69 95 59 85 84 +22 maze-100-1.map 100 100 87 66 55 93 89 +22 maze-100-1.map 100 100 63 68 97 76 88 +22 maze-100-1.map 100 100 62 43 46 35 90 +22 maze-100-1.map 100 100 53 7 57 17 90 +22 maze-100-1.map 100 100 21 5 26 5 91 +22 maze-100-1.map 100 100 30 97 1 93 89 +22 maze-100-1.map 100 100 21 37 37 49 88 +22 maze-100-1.map 100 100 95 32 65 5 89 +22 maze-100-1.map 100 100 5 47 39 17 88 +22 maze-100-1.map 100 100 90 1 83 18 88 +23 maze-100-1.map 100 100 54 97 77 71 93 +23 maze-100-1.map 100 100 91 60 88 71 94 +23 maze-100-1.map 100 100 49 31 59 4 95 +23 maze-100-1.map 100 100 41 5 9 18 95 +23 maze-100-1.map 100 100 9 67 14 49 93 +23 maze-100-1.map 100 100 95 11 75 21 94 +23 maze-100-1.map 100 100 61 59 49 45 94 +23 maze-100-1.map 100 100 95 11 99 29 94 +23 maze-100-1.map 100 100 73 54 57 88 92 +23 maze-100-1.map 100 100 27 57 48 41 95 +24 maze-100-1.map 100 100 38 85 3 94 98 +24 maze-100-1.map 100 100 89 11 86 27 99 +24 maze-100-1.map 100 100 49 13 4 33 99 +24 maze-100-1.map 100 100 7 48 5 29 97 +24 maze-100-1.map 100 100 63 97 85 79 96 +24 maze-100-1.map 100 100 63 1 97 37 98 +24 maze-100-1.map 100 100 79 41 69 62 97 +24 maze-100-1.map 100 100 47 90 63 58 98 +24 maze-100-1.map 100 100 45 47 23 36 97 +24 maze-100-1.map 100 100 52 15 33 31 97 +25 maze-100-1.map 100 100 49 5 79 31 100 +25 maze-100-1.map 100 100 15 75 17 83 102 +25 maze-100-1.map 100 100 55 6 79 16 100 +25 maze-100-1.map 100 100 67 15 93 14 101 +25 maze-100-1.map 100 100 42 9 7 20 102 +25 maze-100-1.map 100 100 29 48 43 61 101 +25 maze-100-1.map 100 100 65 89 55 86 101 +25 maze-100-1.map 100 100 19 33 57 15 100 +25 maze-100-1.map 100 100 97 35 99 3 102 +25 maze-100-1.map 100 100 71 89 83 72 101 +26 maze-100-1.map 100 100 17 5 25 17 104 +26 maze-100-1.map 100 100 57 55 41 63 104 +26 maze-100-1.map 100 100 44 23 19 52 106 +26 maze-100-1.map 100 100 15 42 5 19 105 +26 maze-100-1.map 100 100 61 75 77 88 105 +26 maze-100-1.map 100 100 25 39 54 45 107 +26 maze-100-1.map 100 100 33 87 17 91 104 +26 maze-100-1.map 100 100 89 44 77 21 107 +26 maze-100-1.map 100 100 65 4 37 19 105 +26 maze-100-1.map 100 100 13 65 7 66 107 +27 maze-100-1.map 100 100 47 90 61 81 109 +27 maze-100-1.map 100 100 97 14 57 9 111 +27 maze-100-1.map 100 100 47 82 33 67 109 +27 maze-100-1.map 100 100 59 95 81 84 109 +27 maze-100-1.map 100 100 19 5 17 9 110 +27 maze-100-1.map 100 100 2 61 35 27 109 +27 maze-100-1.map 100 100 99 10 70 29 110 +27 maze-100-1.map 100 100 27 59 41 41 108 +27 maze-100-1.map 100 100 1 14 34 5 108 +27 maze-100-1.map 100 100 97 11 71 31 110 +28 maze-100-1.map 100 100 2 29 37 5 115 +28 maze-100-1.map 100 100 74 59 75 74 114 +28 maze-100-1.map 100 100 55 79 43 61 114 +28 maze-100-1.map 100 100 91 73 87 81 112 +28 maze-100-1.map 100 100 82 75 48 99 112 +28 maze-100-1.map 100 100 53 37 63 58 113 +28 maze-100-1.map 100 100 63 71 73 45 112 +28 maze-100-1.map 100 100 13 23 14 49 113 +28 maze-100-1.map 100 100 2 39 43 21 115 +28 maze-100-1.map 100 100 40 69 53 74 114 +29 maze-100-1.map 100 100 76 79 95 97 117 +29 maze-100-1.map 100 100 7 81 17 46 119 +29 maze-100-1.map 100 100 81 61 72 77 119 +29 maze-100-1.map 100 100 71 17 94 11 117 +29 maze-100-1.map 100 100 45 27 39 19 118 +29 maze-100-1.map 100 100 49 92 89 75 117 +29 maze-100-1.map 100 100 59 4 70 35 116 +29 maze-100-1.map 100 100 58 83 67 96 116 +29 maze-100-1.map 100 100 54 31 34 31 116 +29 maze-100-1.map 100 100 67 49 51 38 119 +30 maze-100-1.map 100 100 45 38 18 69 120 +30 maze-100-1.map 100 100 43 62 53 49 123 +30 maze-100-1.map 100 100 27 81 6 63 123 +30 maze-100-1.map 100 100 51 23 45 33 120 +30 maze-100-1.map 100 100 86 25 86 9 120 +30 maze-100-1.map 100 100 64 79 99 65 121 +30 maze-100-1.map 100 100 27 2 7 13 123 +30 maze-100-1.map 100 100 57 76 71 73 123 +30 maze-100-1.map 100 100 7 19 40 21 121 +30 maze-100-1.map 100 100 53 56 45 99 123 +31 maze-100-1.map 100 100 42 55 45 95 127 +31 maze-100-1.map 100 100 13 65 50 25 125 +31 maze-100-1.map 100 100 33 33 17 27 126 +31 maze-100-1.map 100 100 83 69 71 94 127 +31 maze-100-1.map 100 100 53 3 19 45 124 +31 maze-100-1.map 100 100 7 56 37 18 126 +31 maze-100-1.map 100 100 29 26 27 33 127 +31 maze-100-1.map 100 100 20 23 30 35 124 +31 maze-100-1.map 100 100 21 61 43 24 127 +31 maze-100-1.map 100 100 69 49 78 69 125 +32 maze-100-1.map 100 100 60 75 84 95 128 +32 maze-100-1.map 100 100 89 63 51 99 130 +32 maze-100-1.map 100 100 63 30 99 44 128 +32 maze-100-1.map 100 100 66 89 89 70 130 +32 maze-100-1.map 100 100 86 75 95 62 130 +32 maze-100-1.map 100 100 9 97 11 74 131 +32 maze-100-1.map 100 100 2 51 2 31 130 +32 maze-100-1.map 100 100 65 59 39 67 130 +32 maze-100-1.map 100 100 55 71 73 81 128 +32 maze-100-1.map 100 100 63 83 64 55 131 +33 maze-100-1.map 100 100 54 47 43 99 133 +33 maze-100-1.map 100 100 21 45 47 45 134 +33 maze-100-1.map 100 100 37 69 61 77 132 +33 maze-100-1.map 100 100 79 13 54 25 135 +33 maze-100-1.map 100 100 19 89 27 77 132 +33 maze-100-1.map 100 100 71 83 58 59 133 +33 maze-100-1.map 100 100 73 54 73 93 135 +33 maze-100-1.map 100 100 52 45 44 65 134 +33 maze-100-1.map 100 100 32 71 21 91 133 +33 maze-100-1.map 100 100 1 92 25 79 135 +34 maze-100-1.map 100 100 47 1 99 13 136 +34 maze-100-1.map 100 100 15 75 9 96 137 +34 maze-100-1.map 100 100 16 59 36 33 136 +34 maze-100-1.map 100 100 75 92 67 54 136 +34 maze-100-1.map 100 100 4 7 9 5 139 +34 maze-100-1.map 100 100 45 19 9 11 136 +34 maze-100-1.map 100 100 65 52 48 87 136 +34 maze-100-1.map 100 100 62 85 40 61 138 +34 maze-100-1.map 100 100 2 85 39 73 137 +34 maze-100-1.map 100 100 19 32 61 40 138 +35 maze-100-1.map 100 100 61 51 31 56 141 +35 maze-100-1.map 100 100 99 63 85 87 142 +35 maze-100-1.map 100 100 59 11 89 45 140 +35 maze-100-1.map 100 100 35 71 27 93 142 +35 maze-100-1.map 100 100 23 73 1 97 142 +35 maze-100-1.map 100 100 57 65 77 98 143 +35 maze-100-1.map 100 100 29 6 25 25 143 +35 maze-100-1.map 100 100 72 79 85 37 143 +35 maze-100-1.map 100 100 48 17 5 49 143 +35 maze-100-1.map 100 100 33 11 5 5 142 +36 maze-100-1.map 100 100 65 7 9 33 146 +36 maze-100-1.map 100 100 36 25 85 16 144 +36 maze-100-1.map 100 100 49 96 33 65 145 +36 maze-100-1.map 100 100 1 64 47 10 144 +36 maze-100-1.map 100 100 77 92 85 89 147 +36 maze-100-1.map 100 100 59 59 65 44 147 +36 maze-100-1.map 100 100 5 77 16 83 147 +36 maze-100-1.map 100 100 31 74 23 93 145 +36 maze-100-1.map 100 100 11 77 21 27 144 +36 maze-100-1.map 100 100 75 17 55 29 144 +37 maze-100-1.map 100 100 58 1 90 1 150 +37 maze-100-1.map 100 100 49 23 6 57 149 +37 maze-100-1.map 100 100 53 69 83 98 149 +37 maze-100-1.map 100 100 9 41 20 21 151 +37 maze-100-1.map 100 100 31 85 3 69 148 +37 maze-100-1.map 100 100 64 45 71 51 149 +37 maze-100-1.map 100 100 41 22 19 49 151 +37 maze-100-1.map 100 100 45 39 57 67 148 +37 maze-100-1.map 100 100 69 39 76 71 149 +37 maze-100-1.map 100 100 59 83 43 53 150 +38 maze-100-1.map 100 100 39 55 55 51 152 +38 maze-100-1.map 100 100 97 51 65 16 155 +38 maze-100-1.map 100 100 7 27 43 25 154 +38 maze-100-1.map 100 100 12 3 21 20 152 +38 maze-100-1.map 100 100 22 25 68 19 152 +38 maze-100-1.map 100 100 57 75 83 82 155 +38 maze-100-1.map 100 100 4 63 8 25 152 +38 maze-100-1.map 100 100 47 99 97 57 152 +38 maze-100-1.map 100 100 44 63 61 96 154 +38 maze-100-1.map 100 100 57 73 48 97 155 +39 maze-100-1.map 100 100 78 53 69 85 157 +39 maze-100-1.map 100 100 57 2 4 37 158 +39 maze-100-1.map 100 100 13 44 61 34 156 +39 maze-100-1.map 100 100 51 85 54 45 159 +39 maze-100-1.map 100 100 33 67 55 93 156 +39 maze-100-1.map 100 100 49 29 18 69 159 +39 maze-100-1.map 100 100 87 17 93 48 159 +39 maze-100-1.map 100 100 3 14 16 11 156 +39 maze-100-1.map 100 100 10 45 55 5 159 +39 maze-100-1.map 100 100 15 29 33 11 156 +40 maze-100-1.map 100 100 69 84 86 37 160 +40 maze-100-1.map 100 100 29 29 41 31 162 +40 maze-100-1.map 100 100 30 53 43 92 160 +40 maze-100-1.map 100 100 63 11 42 21 161 +40 maze-100-1.map 100 100 47 8 11 59 163 +40 maze-100-1.map 100 100 39 48 12 69 162 +40 maze-100-1.map 100 100 7 7 1 16 163 +40 maze-100-1.map 100 100 90 37 88 65 160 +40 maze-100-1.map 100 100 49 59 56 75 161 +40 maze-100-1.map 100 100 30 43 41 99 163 +41 maze-100-1.map 100 100 99 55 63 15 164 +41 maze-100-1.map 100 100 50 17 67 7 165 +41 maze-100-1.map 100 100 75 97 57 62 167 +41 maze-100-1.map 100 100 4 79 30 73 166 +41 maze-100-1.map 100 100 55 43 39 96 165 +41 maze-100-1.map 100 100 26 7 15 41 167 +41 maze-100-1.map 100 100 41 17 21 14 165 +41 maze-100-1.map 100 100 71 31 81 10 167 +41 maze-100-1.map 100 100 50 59 49 53 167 +41 maze-100-1.map 100 100 19 35 11 33 166 +42 maze-100-1.map 100 100 1 16 31 13 169 +42 maze-100-1.map 100 100 46 19 25 62 170 +42 maze-100-1.map 100 100 76 55 84 77 170 +42 maze-100-1.map 100 100 97 58 53 79 171 +42 maze-100-1.map 100 100 51 29 16 63 171 +42 maze-100-1.map 100 100 22 49 54 61 168 +42 maze-100-1.map 100 100 99 25 90 19 169 +42 maze-100-1.map 100 100 79 3 15 41 170 +42 maze-100-1.map 100 100 7 31 71 35 168 +42 maze-100-1.map 100 100 29 61 53 36 169 +43 maze-100-1.map 100 100 2 89 12 79 174 +43 maze-100-1.map 100 100 59 43 33 35 174 +43 maze-100-1.map 100 100 99 91 73 93 172 +43 maze-100-1.map 100 100 55 93 41 47 172 +43 maze-100-1.map 100 100 30 47 70 57 172 +43 maze-100-1.map 100 100 45 71 81 70 175 +43 maze-100-1.map 100 100 53 54 77 78 174 +43 maze-100-1.map 100 100 44 63 77 90 174 +43 maze-100-1.map 100 100 17 11 41 21 174 +43 maze-100-1.map 100 100 89 91 97 76 173 +44 maze-100-1.map 100 100 20 39 37 18 176 +44 maze-100-1.map 100 100 97 71 61 94 177 +44 maze-100-1.map 100 100 95 35 55 22 179 +44 maze-100-1.map 100 100 51 85 97 94 177 +44 maze-100-1.map 100 100 35 61 57 51 176 +44 maze-100-1.map 100 100 20 63 55 33 179 +44 maze-100-1.map 100 100 14 29 62 15 178 +44 maze-100-1.map 100 100 57 8 46 23 178 +44 maze-100-1.map 100 100 79 30 76 1 178 +44 maze-100-1.map 100 100 61 61 83 85 178 +45 maze-100-1.map 100 100 80 25 63 9 181 +45 maze-100-1.map 100 100 19 35 47 13 182 +45 maze-100-1.map 100 100 46 19 37 50 182 +45 maze-100-1.map 100 100 57 21 92 15 183 +45 maze-100-1.map 100 100 79 13 15 27 182 +45 maze-100-1.map 100 100 68 99 47 50 182 +45 maze-100-1.map 100 100 43 48 41 94 182 +45 maze-100-1.map 100 100 69 60 69 84 180 +45 maze-100-1.map 100 100 99 50 47 9 183 +45 maze-100-1.map 100 100 11 95 1 67 182 +46 maze-100-1.map 100 100 77 90 95 69 187 +46 maze-100-1.map 100 100 10 99 1 67 187 +46 maze-100-1.map 100 100 11 50 69 7 187 +46 maze-100-1.map 100 100 53 11 5 69 186 +46 maze-100-1.map 100 100 33 83 6 43 185 +46 maze-100-1.map 100 100 21 47 59 48 185 +46 maze-100-1.map 100 100 57 61 77 87 186 +46 maze-100-1.map 100 100 13 39 77 15 184 +46 maze-100-1.map 100 100 49 91 47 43 186 +46 maze-100-1.map 100 100 85 56 89 87 187 +47 maze-100-1.map 100 100 5 73 50 27 189 +47 maze-100-1.map 100 100 9 59 64 9 191 +47 maze-100-1.map 100 100 62 23 5 29 189 +47 maze-100-1.map 100 100 25 44 15 31 191 +47 maze-100-1.map 100 100 13 40 62 17 188 +47 maze-100-1.map 100 100 37 83 2 65 189 +47 maze-100-1.map 100 100 51 55 53 95 190 +47 maze-100-1.map 100 100 17 10 13 58 188 +47 maze-100-1.map 100 100 37 23 99 39 190 +47 maze-100-1.map 100 100 58 25 90 21 190 +48 maze-100-1.map 100 100 80 79 82 63 194 +48 maze-100-1.map 100 100 49 92 97 85 195 +48 maze-100-1.map 100 100 81 23 17 25 194 +48 maze-100-1.map 100 100 53 54 25 69 193 +48 maze-100-1.map 100 100 74 13 6 39 192 +48 maze-100-1.map 100 100 48 99 71 63 195 +48 maze-100-1.map 100 100 98 87 47 93 193 +48 maze-100-1.map 100 100 71 13 4 41 195 +48 maze-100-1.map 100 100 45 53 74 79 195 +48 maze-100-1.map 100 100 57 36 1 53 195 +49 maze-100-1.map 100 100 7 43 81 33 196 +49 maze-100-1.map 100 100 17 46 37 5 197 +49 maze-100-1.map 100 100 53 82 48 39 198 +49 maze-100-1.map 100 100 61 9 85 3 198 +49 maze-100-1.map 100 100 27 5 9 55 196 +49 maze-100-1.map 100 100 5 84 6 87 196 +49 maze-100-1.map 100 100 53 55 29 64 199 +49 maze-100-1.map 100 100 29 71 53 60 197 +49 maze-100-1.map 100 100 6 43 31 37 199 +49 maze-100-1.map 100 100 47 63 60 45 197 +50 maze-100-1.map 100 100 83 75 42 87 201 +50 maze-100-1.map 100 100 59 15 81 5 200 +50 maze-100-1.map 100 100 28 77 25 28 202 +50 maze-100-1.map 100 100 61 52 87 79 201 +50 maze-100-1.map 100 100 44 73 59 85 201 +50 maze-100-1.map 100 100 45 53 17 53 200 +50 maze-100-1.map 100 100 43 19 17 58 203 +50 maze-100-1.map 100 100 33 60 59 97 201 +50 maze-100-1.map 100 100 65 91 55 61 200 +50 maze-100-1.map 100 100 39 23 37 9 200 +51 maze-100-1.map 100 100 50 89 75 79 205 +51 maze-100-1.map 100 100 79 86 88 99 206 +51 maze-100-1.map 100 100 65 19 4 35 205 +51 maze-100-1.map 100 100 77 26 40 25 204 +51 maze-100-1.map 100 100 51 31 92 11 205 +51 maze-100-1.map 100 100 41 23 33 19 204 +51 maze-100-1.map 100 100 55 20 30 33 204 +51 maze-100-1.map 100 100 59 87 71 49 206 +51 maze-100-1.map 100 100 88 55 75 92 204 +51 maze-100-1.map 100 100 79 90 98 59 206 +52 maze-100-1.map 100 100 41 61 64 45 209 +52 maze-100-1.map 100 100 23 26 61 29 209 +52 maze-100-1.map 100 100 97 5 53 21 208 +52 maze-100-1.map 100 100 12 75 38 17 208 +52 maze-100-1.map 100 100 57 3 1 70 211 +52 maze-100-1.map 100 100 5 39 71 1 208 +52 maze-100-1.map 100 100 31 9 11 56 211 +52 maze-100-1.map 100 100 57 83 95 85 208 +52 maze-100-1.map 100 100 21 49 15 29 210 +52 maze-100-1.map 100 100 51 59 77 89 208 +53 maze-100-1.map 100 100 71 62 95 95 215 +53 maze-100-1.map 100 100 3 85 1 70 213 +53 maze-100-1.map 100 100 42 17 34 13 214 +53 maze-100-1.map 100 100 43 25 63 53 212 +53 maze-100-1.map 100 100 54 21 16 15 212 +53 maze-100-1.map 100 100 54 11 23 39 215 +53 maze-100-1.map 100 100 87 70 57 62 214 +53 maze-100-1.map 100 100 33 5 45 11 214 +53 maze-100-1.map 100 100 43 81 6 63 215 +53 maze-100-1.map 100 100 98 83 88 51 214 +54 maze-100-1.map 100 100 3 40 27 13 217 +54 maze-100-1.map 100 100 41 80 11 45 219 +54 maze-100-1.map 100 100 35 79 2 45 217 +54 maze-100-1.map 100 100 60 19 52 27 216 +54 maze-100-1.map 100 100 60 65 99 65 219 +54 maze-100-1.map 100 100 82 89 86 51 216 +54 maze-100-1.map 100 100 11 27 15 3 216 +54 maze-100-1.map 100 100 23 15 3 44 219 +54 maze-100-1.map 100 100 32 49 45 49 217 +54 maze-100-1.map 100 100 28 21 45 12 218 +55 maze-100-1.map 100 100 75 99 94 93 221 +55 maze-100-1.map 100 100 89 93 47 67 220 +55 maze-100-1.map 100 100 9 39 18 87 223 +55 maze-100-1.map 100 100 17 69 63 43 220 +55 maze-100-1.map 100 100 47 11 86 13 221 +55 maze-100-1.map 100 100 5 39 25 41 222 +55 maze-100-1.map 100 100 31 24 99 43 221 +55 maze-100-1.map 100 100 41 39 31 27 222 +55 maze-100-1.map 100 100 43 47 40 69 221 +55 maze-100-1.map 100 100 45 19 91 21 220 +56 maze-100-1.map 100 100 14 93 11 63 227 +56 maze-100-1.map 100 100 63 62 99 67 225 +56 maze-100-1.map 100 100 87 53 53 77 226 +56 maze-100-1.map 100 100 62 59 27 59 225 +56 maze-100-1.map 100 100 19 67 61 51 226 +56 maze-100-1.map 100 100 85 89 44 63 225 +56 maze-100-1.map 100 100 47 89 82 99 225 +56 maze-100-1.map 100 100 91 47 57 34 225 +56 maze-100-1.map 100 100 57 86 75 45 227 +56 maze-100-1.map 100 100 39 29 63 58 227 +57 maze-100-1.map 100 100 83 29 85 30 231 +57 maze-100-1.map 100 100 77 74 29 58 228 +57 maze-100-1.map 100 100 57 45 48 59 231 +57 maze-100-1.map 100 100 43 72 53 97 231 +57 maze-100-1.map 100 100 12 23 17 79 231 +57 maze-100-1.map 100 100 3 46 59 30 228 +57 maze-100-1.map 100 100 71 97 84 59 231 +57 maze-100-1.map 100 100 65 57 99 94 231 +57 maze-100-1.map 100 100 57 18 86 25 230 +57 maze-100-1.map 100 100 50 91 67 74 230 +58 maze-100-1.map 100 100 35 46 52 45 232 +58 maze-100-1.map 100 100 11 56 42 13 234 +58 maze-100-1.map 100 100 1 77 14 17 235 +58 maze-100-1.map 100 100 68 99 45 39 235 +58 maze-100-1.map 100 100 37 85 8 35 233 +58 maze-100-1.map 100 100 39 8 7 51 235 +58 maze-100-1.map 100 100 39 58 93 79 233 +58 maze-100-1.map 100 100 85 24 45 19 235 +58 maze-100-1.map 100 100 21 56 11 41 233 +58 maze-100-1.map 100 100 71 63 59 71 232 +59 maze-100-1.map 100 100 49 2 17 79 239 +59 maze-100-1.map 100 100 13 26 5 1 239 +59 maze-100-1.map 100 100 96 37 13 38 236 +59 maze-100-1.map 100 100 73 24 8 35 236 +59 maze-100-1.map 100 100 95 27 5 33 236 +59 maze-100-1.map 100 100 34 37 53 3 239 +59 maze-100-1.map 100 100 20 93 1 62 238 +59 maze-100-1.map 100 100 13 80 12 13 238 +59 maze-100-1.map 100 100 87 26 49 20 236 +59 maze-100-1.map 100 100 24 87 19 32 238 +60 maze-100-1.map 100 100 41 73 75 79 240 +60 maze-100-1.map 100 100 77 45 51 74 241 +60 maze-100-1.map 100 100 65 71 70 89 241 +60 maze-100-1.map 100 100 47 37 46 11 241 +60 maze-100-1.map 100 100 37 53 83 73 242 +60 maze-100-1.map 100 100 85 85 43 59 240 +60 maze-100-1.map 100 100 46 47 68 97 242 +60 maze-100-1.map 100 100 63 20 5 49 243 +60 maze-100-1.map 100 100 21 37 54 31 241 +60 maze-100-1.map 100 100 28 35 67 35 243 +61 maze-100-1.map 100 100 81 27 97 15 244 +61 maze-100-1.map 100 100 81 59 83 83 246 +61 maze-100-1.map 100 100 55 89 25 48 245 +61 maze-100-1.map 100 100 22 57 7 48 246 +61 maze-100-1.map 100 100 13 19 59 31 246 +61 maze-100-1.map 100 100 3 43 79 6 247 +61 maze-100-1.map 100 100 15 17 64 13 245 +61 maze-100-1.map 100 100 37 45 71 76 247 +61 maze-100-1.map 100 100 17 46 47 43 245 +61 maze-100-1.map 100 100 27 52 4 41 246 +62 maze-100-1.map 100 100 89 79 35 55 250 +62 maze-100-1.map 100 100 57 23 19 81 248 +62 maze-100-1.map 100 100 57 1 25 13 248 +62 maze-100-1.map 100 100 11 60 29 97 251 +62 maze-100-1.map 100 100 56 29 13 78 250 +62 maze-100-1.map 100 100 7 83 32 35 251 +62 maze-100-1.map 100 100 46 13 50 41 248 +62 maze-100-1.map 100 100 23 83 41 22 251 +62 maze-100-1.map 100 100 13 5 34 31 251 +62 maze-100-1.map 100 100 94 81 59 63 251 +63 maze-100-1.map 100 100 25 87 13 65 254 +63 maze-100-1.map 100 100 77 2 30 33 252 +63 maze-100-1.map 100 100 90 83 83 91 253 +63 maze-100-1.map 100 100 24 57 45 7 253 +63 maze-100-1.map 100 100 33 24 43 48 254 +63 maze-100-1.map 100 100 47 8 27 57 253 +63 maze-100-1.map 100 100 47 31 73 23 254 +63 maze-100-1.map 100 100 95 20 41 22 252 +63 maze-100-1.map 100 100 99 96 47 65 255 +63 maze-100-1.map 100 100 37 68 65 93 253 +64 maze-100-1.map 100 100 7 37 61 29 258 +64 maze-100-1.map 100 100 61 78 68 71 256 +64 maze-100-1.map 100 100 62 61 47 26 258 +64 maze-100-1.map 100 100 51 23 99 13 258 +64 maze-100-1.map 100 100 41 42 73 81 259 +64 maze-100-1.map 100 100 53 69 95 79 256 +64 maze-100-1.map 100 100 7 43 7 98 257 +64 maze-100-1.map 100 100 95 13 6 35 259 +64 maze-100-1.map 100 100 32 21 53 18 258 +64 maze-100-1.map 100 100 99 89 77 44 257 +65 maze-100-1.map 100 100 20 39 67 11 263 +65 maze-100-1.map 100 100 73 75 39 44 261 +65 maze-100-1.map 100 100 78 31 91 12 260 +65 maze-100-1.map 100 100 41 66 89 68 262 +65 maze-100-1.map 100 100 50 35 27 55 263 +65 maze-100-1.map 100 100 65 95 40 53 261 +65 maze-100-1.map 100 100 3 44 77 16 262 +65 maze-100-1.map 100 100 77 49 96 99 263 +65 maze-100-1.map 100 100 88 81 87 41 263 +65 maze-100-1.map 100 100 14 41 23 67 261 +66 maze-100-1.map 100 100 29 41 71 76 267 +66 maze-100-1.map 100 100 21 52 55 88 266 +66 maze-100-1.map 100 100 84 77 50 45 264 +66 maze-100-1.map 100 100 47 25 73 21 266 +66 maze-100-1.map 100 100 25 33 55 85 266 +66 maze-100-1.map 100 100 66 29 15 47 267 +66 maze-100-1.map 100 100 43 47 79 65 266 +66 maze-100-1.map 100 100 43 29 16 75 265 +66 maze-100-1.map 100 100 5 33 99 36 267 +66 maze-100-1.map 100 100 39 17 33 82 267 +67 maze-100-1.map 100 100 45 35 32 43 269 +67 maze-100-1.map 100 100 53 71 21 69 270 +67 maze-100-1.map 100 100 7 36 21 1 271 +67 maze-100-1.map 100 100 51 27 70 51 269 +67 maze-100-1.map 100 100 41 38 83 95 271 +67 maze-100-1.map 100 100 49 19 95 41 268 +67 maze-100-1.map 100 100 65 55 85 61 270 +67 maze-100-1.map 100 100 63 43 75 76 269 +67 maze-100-1.map 100 100 84 69 50 41 268 +67 maze-100-1.map 100 100 53 42 87 93 269 +68 maze-100-1.map 100 100 17 45 93 51 274 +68 maze-100-1.map 100 100 97 43 1 37 274 +68 maze-100-1.map 100 100 13 17 63 19 272 +68 maze-100-1.map 100 100 96 55 49 95 273 +68 maze-100-1.map 100 100 5 81 79 9 274 +68 maze-100-1.map 100 100 97 7 11 42 275 +68 maze-100-1.map 100 100 33 20 52 31 272 +68 maze-100-1.map 100 100 43 68 85 37 275 +68 maze-100-1.map 100 100 41 3 47 30 273 +68 maze-100-1.map 100 100 39 65 83 91 274 +69 maze-100-1.map 100 100 29 32 57 91 277 +69 maze-100-1.map 100 100 45 43 53 11 276 +69 maze-100-1.map 100 100 73 6 23 8 278 +69 maze-100-1.map 100 100 63 79 38 35 277 +69 maze-100-1.map 100 100 73 27 9 15 276 +69 maze-100-1.map 100 100 29 33 57 90 279 +69 maze-100-1.map 100 100 9 6 38 17 278 +69 maze-100-1.map 100 100 47 72 83 35 277 +69 maze-100-1.map 100 100 89 39 47 67 278 +69 maze-100-1.map 100 100 35 53 81 76 277 +70 maze-100-1.map 100 100 73 40 94 7 282 +70 maze-100-1.map 100 100 21 77 65 39 282 +70 maze-100-1.map 100 100 61 43 82 99 281 +70 maze-100-1.map 100 100 20 27 11 91 283 +70 maze-100-1.map 100 100 77 65 51 63 280 +70 maze-100-1.map 100 100 1 48 80 23 280 +70 maze-100-1.map 100 100 65 71 67 60 281 +70 maze-100-1.map 100 100 54 57 27 25 283 +70 maze-100-1.map 100 100 50 11 17 50 282 +70 maze-100-1.map 100 100 69 51 87 61 280 +71 maze-100-1.map 100 100 39 33 65 39 284 +71 maze-100-1.map 100 100 28 25 54 57 284 +71 maze-100-1.map 100 100 23 31 81 27 286 +71 maze-100-1.map 100 100 23 98 9 58 284 +71 maze-100-1.map 100 100 67 69 85 91 284 +71 maze-100-1.map 100 100 69 31 3 51 286 +71 maze-100-1.map 100 100 40 91 39 29 285 +71 maze-100-1.map 100 100 40 99 97 87 287 +71 maze-100-1.map 100 100 3 55 65 31 286 +71 maze-100-1.map 100 100 6 33 91 45 287 +72 maze-100-1.map 100 100 69 85 24 43 289 +72 maze-100-1.map 100 100 51 58 19 36 288 +72 maze-100-1.map 100 100 69 3 7 73 288 +72 maze-100-1.map 100 100 8 25 21 68 288 +72 maze-100-1.map 100 100 10 9 73 5 291 +72 maze-100-1.map 100 100 5 55 96 13 291 +72 maze-100-1.map 100 100 79 46 51 64 290 +72 maze-100-1.map 100 100 12 9 59 23 291 +72 maze-100-1.map 100 100 20 21 18 71 290 +72 maze-100-1.map 100 100 45 73 68 93 289 +73 maze-100-1.map 100 100 79 16 19 19 295 +73 maze-100-1.map 100 100 81 85 89 97 292 +73 maze-100-1.map 100 100 69 8 25 22 292 +73 maze-100-1.map 100 100 89 10 13 38 294 +73 maze-100-1.map 100 100 86 65 60 45 294 +73 maze-100-1.map 100 100 23 23 11 95 292 +73 maze-100-1.map 100 100 37 39 71 91 294 +73 maze-100-1.map 100 100 35 89 3 29 292 +73 maze-100-1.map 100 100 29 53 89 91 294 +73 maze-100-1.map 100 100 80 89 75 42 294 +74 maze-100-1.map 100 100 5 54 28 3 298 +74 maze-100-1.map 100 100 65 53 80 39 299 +74 maze-100-1.map 100 100 63 3 25 14 297 +74 maze-100-1.map 100 100 61 7 45 38 299 +74 maze-100-1.map 100 100 53 23 31 64 299 +74 maze-100-1.map 100 100 7 7 77 37 296 +74 maze-100-1.map 100 100 37 36 77 87 297 +74 maze-100-1.map 100 100 30 35 58 77 296 +74 maze-100-1.map 100 100 24 31 11 75 299 +74 maze-100-1.map 100 100 81 65 34 43 297 +75 maze-100-1.map 100 100 7 55 23 60 303 +75 maze-100-1.map 100 100 49 36 87 73 303 +75 maze-100-1.map 100 100 93 51 8 23 301 +75 maze-100-1.map 100 100 25 17 74 9 301 +75 maze-100-1.map 100 100 93 6 11 41 303 +75 maze-100-1.map 100 100 85 27 17 21 302 +75 maze-100-1.map 100 100 73 99 22 33 303 +75 maze-100-1.map 100 100 83 19 27 31 300 +75 maze-100-1.map 100 100 58 57 68 65 300 +75 maze-100-1.map 100 100 5 46 91 3 301 +76 maze-100-1.map 100 100 49 51 5 33 306 +76 maze-100-1.map 100 100 25 87 7 27 306 +76 maze-100-1.map 100 100 71 13 16 73 305 +76 maze-100-1.map 100 100 79 30 23 38 304 +76 maze-100-1.map 100 100 20 47 61 38 304 +76 maze-100-1.map 100 100 27 47 63 25 306 +76 maze-100-1.map 100 100 19 52 57 37 305 +76 maze-100-1.map 100 100 59 19 27 11 304 +76 maze-100-1.map 100 100 49 35 66 37 307 +76 maze-100-1.map 100 100 43 74 80 79 306 +77 maze-100-1.map 100 100 21 9 92 23 309 +77 maze-100-1.map 100 100 99 1 83 27 310 +77 maze-100-1.map 100 100 27 65 41 62 309 +77 maze-100-1.map 100 100 9 40 53 48 310 +77 maze-100-1.map 100 100 30 27 39 77 309 +77 maze-100-1.map 100 100 88 73 61 45 311 +77 maze-100-1.map 100 100 3 57 99 46 311 +77 maze-100-1.map 100 100 7 76 77 11 311 +77 maze-100-1.map 100 100 85 7 61 25 310 +77 maze-100-1.map 100 100 42 33 70 21 308 +78 maze-100-1.map 100 100 37 30 95 15 313 +78 maze-100-1.map 100 100 33 34 67 99 315 +78 maze-100-1.map 100 100 40 25 10 85 312 +78 maze-100-1.map 100 100 15 33 1 81 314 +78 maze-100-1.map 100 100 49 70 41 21 315 +78 maze-100-1.map 100 100 36 97 9 45 313 +78 maze-100-1.map 100 100 63 77 71 51 314 +78 maze-100-1.map 100 100 5 39 52 45 313 +78 maze-100-1.map 100 100 55 60 89 53 315 +78 maze-100-1.map 100 100 67 29 4 49 315 +79 maze-100-1.map 100 100 42 11 75 3 317 +79 maze-100-1.map 100 100 55 65 34 27 319 +79 maze-100-1.map 100 100 63 32 20 21 316 +79 maze-100-1.map 100 100 49 52 4 37 316 +79 maze-100-1.map 100 100 59 99 18 51 319 +79 maze-100-1.map 100 100 25 43 37 53 318 +79 maze-100-1.map 100 100 44 87 72 49 316 +79 maze-100-1.map 100 100 16 85 51 23 319 +79 maze-100-1.map 100 100 15 57 11 23 318 +79 maze-100-1.map 100 100 43 92 19 58 318 +80 maze-100-1.map 100 100 45 33 81 76 323 +80 maze-100-1.map 100 100 17 23 64 47 323 +80 maze-100-1.map 100 100 3 14 44 19 322 +80 maze-100-1.map 100 100 16 53 47 67 321 +80 maze-100-1.map 100 100 94 51 7 55 323 +80 maze-100-1.map 100 100 16 13 45 35 321 +80 maze-100-1.map 100 100 17 62 7 19 323 +80 maze-100-1.map 100 100 93 93 71 45 322 +80 maze-100-1.map 100 100 14 9 75 19 321 +80 maze-100-1.map 100 100 42 59 86 53 322 +81 maze-100-1.map 100 100 93 31 3 75 326 +81 maze-100-1.map 100 100 41 90 69 47 327 +81 maze-100-1.map 100 100 39 37 57 36 325 +81 maze-100-1.map 100 100 69 48 59 57 327 +81 maze-100-1.map 100 100 41 33 75 7 324 +81 maze-100-1.map 100 100 64 85 43 30 326 +81 maze-100-1.map 100 100 83 13 76 31 325 +81 maze-100-1.map 100 100 23 8 99 20 324 +81 maze-100-1.map 100 100 24 93 19 29 327 +81 maze-100-1.map 100 100 96 57 41 73 327 +82 maze-100-1.map 100 100 27 25 13 93 330 +82 maze-100-1.map 100 100 72 35 48 41 330 +82 maze-100-1.map 100 100 28 9 26 49 330 +82 maze-100-1.map 100 100 33 73 40 15 329 +82 maze-100-1.map 100 100 57 43 91 59 330 +82 maze-100-1.map 100 100 49 83 15 63 330 +82 maze-100-1.map 100 100 21 20 40 43 328 +82 maze-100-1.map 100 100 53 12 26 85 330 +82 maze-100-1.map 100 100 37 61 75 48 329 +82 maze-100-1.map 100 100 78 83 23 39 331 +83 maze-100-1.map 100 100 39 16 11 99 335 +83 maze-100-1.map 100 100 13 3 51 6 333 +83 maze-100-1.map 100 100 83 36 47 95 333 +83 maze-100-1.map 100 100 36 69 98 91 332 +83 maze-100-1.map 100 100 94 1 2 61 332 +83 maze-100-1.map 100 100 17 10 87 29 333 +83 maze-100-1.map 100 100 82 47 34 67 334 +83 maze-100-1.map 100 100 50 35 26 11 332 +83 maze-100-1.map 100 100 85 3 83 31 334 +83 maze-100-1.map 100 100 19 47 73 79 334 +84 maze-100-1.map 100 100 17 19 65 29 338 +84 maze-100-1.map 100 100 7 82 49 40 336 +84 maze-100-1.map 100 100 9 47 90 9 339 +84 maze-100-1.map 100 100 13 56 56 41 338 +84 maze-100-1.map 100 100 43 27 93 39 338 +84 maze-100-1.map 100 100 9 64 91 43 339 +84 maze-100-1.map 100 100 34 51 92 67 338 +84 maze-100-1.map 100 100 32 31 20 93 336 +84 maze-100-1.map 100 100 43 56 47 27 337 +84 maze-100-1.map 100 100 13 63 13 89 338 +85 maze-100-1.map 100 100 97 84 55 45 343 +85 maze-100-1.map 100 100 45 97 15 62 341 +85 maze-100-1.map 100 100 67 36 43 35 343 +85 maze-100-1.map 100 100 57 21 5 75 342 +85 maze-100-1.map 100 100 59 12 41 37 343 +85 maze-100-1.map 100 100 31 62 74 39 342 +85 maze-100-1.map 100 100 27 12 18 49 340 +85 maze-100-1.map 100 100 3 76 94 19 340 +85 maze-100-1.map 100 100 41 67 31 33 340 +85 maze-100-1.map 100 100 24 59 70 3 342 +86 maze-100-1.map 100 100 10 11 31 85 345 +86 maze-100-1.map 100 100 71 59 33 66 345 +86 maze-100-1.map 100 100 13 5 35 33 346 +86 maze-100-1.map 100 100 55 39 10 57 347 +86 maze-100-1.map 100 100 67 9 20 65 345 +86 maze-100-1.map 100 100 53 7 53 56 345 +86 maze-100-1.map 100 100 29 64 71 5 347 +86 maze-100-1.map 100 100 14 31 4 95 346 +86 maze-100-1.map 100 100 1 14 45 30 344 +86 maze-100-1.map 100 100 31 13 15 79 346 +87 maze-100-1.map 100 100 23 29 62 63 349 +87 maze-100-1.map 100 100 86 45 19 13 349 +87 maze-100-1.map 100 100 86 5 77 28 348 +87 maze-100-1.map 100 100 36 3 61 21 351 +87 maze-100-1.map 100 100 89 7 7 21 348 +87 maze-100-1.map 100 100 18 69 65 11 349 +87 maze-100-1.map 100 100 19 59 12 9 351 +87 maze-100-1.map 100 100 27 76 65 16 350 +87 maze-100-1.map 100 100 31 23 17 89 348 +87 maze-100-1.map 100 100 34 59 93 83 351 +88 maze-100-1.map 100 100 9 33 73 54 355 +88 maze-100-1.map 100 100 2 23 46 31 352 +88 maze-100-1.map 100 100 63 41 9 54 355 +88 maze-100-1.map 100 100 87 6 10 53 354 +88 maze-100-1.map 100 100 1 16 52 15 354 +88 maze-100-1.map 100 100 95 99 41 40 353 +88 maze-100-1.map 100 100 81 43 52 37 353 +88 maze-100-1.map 100 100 26 39 91 77 355 +88 maze-100-1.map 100 100 59 42 53 8 354 +88 maze-100-1.map 100 100 83 77 25 40 353 +89 maze-100-1.map 100 100 13 39 59 60 359 +89 maze-100-1.map 100 100 97 39 25 37 358 +89 maze-100-1.map 100 100 92 1 19 20 358 +89 maze-100-1.map 100 100 67 29 7 82 359 +89 maze-100-1.map 100 100 37 41 30 35 357 +89 maze-100-1.map 100 100 95 66 57 43 357 +89 maze-100-1.map 100 100 27 83 65 2 359 +89 maze-100-1.map 100 100 4 71 49 31 357 +89 maze-100-1.map 100 100 76 81 29 35 357 +89 maze-100-1.map 100 100 25 45 71 29 358 +90 maze-100-1.map 100 100 41 9 90 25 363 +90 maze-100-1.map 100 100 34 27 13 87 361 +90 maze-100-1.map 100 100 75 4 29 65 361 +90 maze-100-1.map 100 100 3 5 63 30 363 +90 maze-100-1.map 100 100 11 91 53 10 361 +90 maze-100-1.map 100 100 81 49 49 41 360 +90 maze-100-1.map 100 100 29 61 83 72 363 +90 maze-100-1.map 100 100 9 29 44 83 361 +90 maze-100-1.map 100 100 67 45 47 97 360 +90 maze-100-1.map 100 100 92 29 41 32 360 +91 maze-100-1.map 100 100 29 49 99 92 367 +91 maze-100-1.map 100 100 33 28 41 90 364 +91 maze-100-1.map 100 100 97 18 25 22 366 +91 maze-100-1.map 100 100 85 38 37 47 365 +91 maze-100-1.map 100 100 71 23 23 48 367 +91 maze-100-1.map 100 100 61 35 49 48 365 +91 maze-100-1.map 100 100 79 35 27 1 366 +91 maze-100-1.map 100 100 38 81 17 13 367 +91 maze-100-1.map 100 100 34 43 98 89 364 +91 maze-100-1.map 100 100 52 45 1 73 367 +92 maze-100-1.map 100 100 25 17 93 11 370 +92 maze-100-1.map 100 100 30 61 81 93 369 +92 maze-100-1.map 100 100 53 1 30 73 371 +92 maze-100-1.map 100 100 21 41 93 16 371 +92 maze-100-1.map 100 100 93 51 21 38 371 +92 maze-100-1.map 100 100 89 37 53 43 370 +92 maze-100-1.map 100 100 63 35 23 43 368 +92 maze-100-1.map 100 100 83 59 29 42 371 +92 maze-100-1.map 100 100 57 49 7 45 370 +92 maze-100-1.map 100 100 85 16 45 45 371 +93 maze-100-1.map 100 100 75 74 21 61 375 +93 maze-100-1.map 100 100 5 79 1 5 374 +93 maze-100-1.map 100 100 2 89 45 12 372 +93 maze-100-1.map 100 100 17 23 48 77 375 +93 maze-100-1.map 100 100 19 75 91 22 375 +93 maze-100-1.map 100 100 21 65 73 6 373 +93 maze-100-1.map 100 100 71 1 19 69 372 +93 maze-100-1.map 100 100 45 44 86 57 374 +93 maze-100-1.map 100 100 77 31 23 77 372 +93 maze-100-1.map 100 100 52 97 12 69 374 +94 maze-100-1.map 100 100 75 92 16 69 376 +94 maze-100-1.map 100 100 83 61 41 75 376 +94 maze-100-1.map 100 100 11 85 51 9 376 +94 maze-100-1.map 100 100 6 5 60 11 376 +94 maze-100-1.map 100 100 71 64 35 61 379 +94 maze-100-1.map 100 100 12 69 26 5 378 +94 maze-100-1.map 100 100 29 29 55 94 379 +94 maze-100-1.map 100 100 15 51 2 77 377 +94 maze-100-1.map 100 100 33 25 49 76 379 +94 maze-100-1.map 100 100 27 15 97 10 377 +95 maze-100-1.map 100 100 57 33 18 3 383 +95 maze-100-1.map 100 100 33 83 76 9 381 +95 maze-100-1.map 100 100 76 23 19 62 382 +95 maze-100-1.map 100 100 36 69 93 86 380 +95 maze-100-1.map 100 100 89 77 23 47 380 +95 maze-100-1.map 100 100 51 33 87 33 380 +95 maze-100-1.map 100 100 12 13 58 41 380 +95 maze-100-1.map 100 100 39 47 28 19 381 +95 maze-100-1.map 100 100 11 36 53 70 382 +95 maze-100-1.map 100 100 1 79 1 13 382 +96 maze-100-1.map 100 100 98 17 41 6 386 +96 maze-100-1.map 100 100 39 43 91 34 385 +96 maze-100-1.map 100 100 95 36 33 11 387 +96 maze-100-1.map 100 100 23 33 85 63 384 +96 maze-100-1.map 100 100 15 13 87 17 384 +96 maze-100-1.map 100 100 10 71 33 67 387 +96 maze-100-1.map 100 100 43 9 63 32 387 +96 maze-100-1.map 100 100 97 75 46 33 385 +96 maze-100-1.map 100 100 94 83 55 37 385 +96 maze-100-1.map 100 100 15 27 61 82 385 +97 maze-100-1.map 100 100 40 3 24 75 388 +97 maze-100-1.map 100 100 58 1 10 81 388 +97 maze-100-1.map 100 100 13 10 15 63 389 +97 maze-100-1.map 100 100 97 27 25 16 389 +97 maze-100-1.map 100 100 83 53 55 37 388 +97 maze-100-1.map 100 100 31 5 95 25 388 +97 maze-100-1.map 100 100 57 8 11 98 388 +97 maze-100-1.map 100 100 25 52 84 63 390 +97 maze-100-1.map 100 100 41 17 63 73 390 +97 maze-100-1.map 100 100 69 17 39 87 388 +98 maze-100-1.map 100 100 95 37 39 8 393 +98 maze-100-1.map 100 100 39 65 92 89 395 +98 maze-100-1.map 100 100 87 27 35 2 393 +98 maze-100-1.map 100 100 89 67 27 70 393 +98 maze-100-1.map 100 100 49 7 60 63 395 +98 maze-100-1.map 100 100 45 47 65 15 392 +98 maze-100-1.map 100 100 97 19 51 41 392 +98 maze-100-1.map 100 100 39 61 23 27 394 +98 maze-100-1.map 100 100 35 46 67 63 393 +98 maze-100-1.map 100 100 23 37 94 55 395 +99 maze-100-1.map 100 100 51 49 7 83 398 +99 maze-100-1.map 100 100 62 19 31 91 397 +99 maze-100-1.map 100 100 23 61 85 72 397 +99 maze-100-1.map 100 100 17 47 63 73 396 +99 maze-100-1.map 100 100 1 67 89 17 398 +99 maze-100-1.map 100 100 65 17 6 71 397 +99 maze-100-1.map 100 100 15 48 51 71 397 +99 maze-100-1.map 100 100 42 33 99 85 397 +99 maze-100-1.map 100 100 35 84 9 19 399 +99 maze-100-1.map 100 100 60 21 35 90 396 +100 maze-100-1.map 100 100 25 47 16 5 403 +100 maze-100-1.map 100 100 15 69 41 75 400 +100 maze-100-1.map 100 100 73 75 21 67 400 +100 maze-100-1.map 100 100 66 87 21 67 403 +100 maze-100-1.map 100 100 56 31 61 51 403 +100 maze-100-1.map 100 100 9 59 65 57 402 +100 maze-100-1.map 100 100 20 63 23 71 401 +100 maze-100-1.map 100 100 71 95 25 63 402 +100 maze-100-1.map 100 100 31 13 97 41 402 +100 maze-100-1.map 100 100 33 83 43 11 402 +101 maze-100-1.map 100 100 11 23 67 50 405 +101 maze-100-1.map 100 100 65 87 47 30 407 +101 maze-100-1.map 100 100 7 67 88 3 405 +101 maze-100-1.map 100 100 35 3 74 33 405 +101 maze-100-1.map 100 100 3 92 55 5 407 +101 maze-100-1.map 100 100 63 23 55 50 407 +101 maze-100-1.map 100 100 37 3 85 33 406 +101 maze-100-1.map 100 100 87 59 64 47 405 +101 maze-100-1.map 100 100 17 53 77 87 406 +101 maze-100-1.map 100 100 81 15 50 45 407 +102 maze-100-1.map 100 100 61 33 63 41 410 +102 maze-100-1.map 100 100 31 98 50 27 410 +102 maze-100-1.map 100 100 46 49 73 18 410 +102 maze-100-1.map 100 100 47 88 35 31 411 +102 maze-100-1.map 100 100 82 75 47 23 409 +102 maze-100-1.map 100 100 21 65 89 70 409 +102 maze-100-1.map 100 100 23 53 97 45 410 +102 maze-100-1.map 100 100 33 73 59 32 411 +102 maze-100-1.map 100 100 45 28 3 82 410 +102 maze-100-1.map 100 100 82 57 57 49 411 +103 maze-100-1.map 100 100 60 37 64 45 412 +103 maze-100-1.map 100 100 50 5 61 73 413 +103 maze-100-1.map 100 100 61 69 45 6 415 +103 maze-100-1.map 100 100 15 63 77 22 413 +103 maze-100-1.map 100 100 53 53 65 5 412 +103 maze-100-1.map 100 100 31 3 99 15 412 +103 maze-100-1.map 100 100 59 21 14 1 415 +103 maze-100-1.map 100 100 58 57 5 77 413 +103 maze-100-1.map 100 100 45 27 79 89 412 +103 maze-100-1.map 100 100 75 35 45 45 412 +104 maze-100-1.map 100 100 7 93 37 31 416 +104 maze-100-1.map 100 100 69 53 52 15 419 +104 maze-100-1.map 100 100 49 15 61 57 418 +104 maze-100-1.map 100 100 12 85 25 11 419 +104 maze-100-1.map 100 100 40 77 30 35 416 +104 maze-100-1.map 100 100 59 33 31 77 416 +104 maze-100-1.map 100 100 89 66 49 26 416 +104 maze-100-1.map 100 100 19 91 43 26 419 +104 maze-100-1.map 100 100 73 41 57 39 418 +104 maze-100-1.map 100 100 69 17 34 73 419 +105 maze-100-1.map 100 100 17 54 13 75 421 +105 maze-100-1.map 100 100 55 18 67 50 420 +105 maze-100-1.map 100 100 45 93 11 32 421 +105 maze-100-1.map 100 100 35 86 68 23 422 +105 maze-100-1.map 100 100 87 27 33 85 420 +105 maze-100-1.map 100 100 62 21 55 36 422 +105 maze-100-1.map 100 100 15 27 53 78 423 +105 maze-100-1.map 100 100 99 19 17 65 420 +105 maze-100-1.map 100 100 44 21 41 68 422 +105 maze-100-1.map 100 100 80 29 30 83 422 +106 maze-100-1.map 100 100 98 5 23 72 426 +106 maze-100-1.map 100 100 48 77 47 5 427 +106 maze-100-1.map 100 100 64 35 41 47 427 +106 maze-100-1.map 100 100 46 69 6 41 426 +106 maze-100-1.map 100 100 39 23 41 69 424 +106 maze-100-1.map 100 100 39 15 51 86 427 +106 maze-100-1.map 100 100 39 76 67 38 424 +106 maze-100-1.map 100 100 55 40 68 19 426 +106 maze-100-1.map 100 100 8 97 9 18 426 +106 maze-100-1.map 100 100 3 98 55 25 425 +107 maze-100-1.map 100 100 97 57 19 53 430 +107 maze-100-1.map 100 100 67 42 49 43 431 +107 maze-100-1.map 100 100 75 16 18 85 428 +107 maze-100-1.map 100 100 3 93 17 20 431 +107 maze-100-1.map 100 100 72 27 46 49 430 +107 maze-100-1.map 100 100 25 53 95 70 431 +107 maze-100-1.map 100 100 25 5 63 41 430 +107 maze-100-1.map 100 100 25 33 97 56 429 +107 maze-100-1.map 100 100 25 44 10 3 430 +107 maze-100-1.map 100 100 39 43 94 11 431 +108 maze-100-1.map 100 100 77 26 51 50 432 +108 maze-100-1.map 100 100 17 95 31 35 434 +108 maze-100-1.map 100 100 29 22 89 8 432 +108 maze-100-1.map 100 100 35 89 74 21 435 +108 maze-100-1.map 100 100 77 16 35 82 434 +108 maze-100-1.map 100 100 83 91 17 55 434 +108 maze-100-1.map 100 100 81 31 9 84 435 +108 maze-100-1.map 100 100 31 86 77 20 434 +108 maze-100-1.map 100 100 79 27 52 43 435 +108 maze-100-1.map 100 100 19 63 97 31 434 +109 maze-100-1.map 100 100 3 15 17 78 437 +109 maze-100-1.map 100 100 46 93 14 49 438 +109 maze-100-1.map 100 100 98 23 48 53 438 +109 maze-100-1.map 100 100 1 95 59 1 436 +109 maze-100-1.map 100 100 21 67 65 26 437 +109 maze-100-1.map 100 100 18 93 59 35 437 +109 maze-100-1.map 100 100 16 13 29 97 439 +109 maze-100-1.map 100 100 61 2 60 55 436 +109 maze-100-1.map 100 100 53 55 81 27 436 +109 maze-100-1.map 100 100 11 63 61 63 438 +110 maze-100-1.map 100 100 17 20 23 91 441 +110 maze-100-1.map 100 100 93 19 37 50 443 +110 maze-100-1.map 100 100 28 79 27 65 443 +110 maze-100-1.map 100 100 1 16 76 19 440 +110 maze-100-1.map 100 100 91 15 39 51 440 +110 maze-100-1.map 100 100 99 9 41 1 442 +110 maze-100-1.map 100 100 22 83 17 69 443 +110 maze-100-1.map 100 100 43 29 29 96 441 +110 maze-100-1.map 100 100 99 31 39 37 442 +110 maze-100-1.map 100 100 95 20 41 49 441 +111 maze-100-1.map 100 100 63 54 68 1 446 +111 maze-100-1.map 100 100 23 45 38 87 445 +111 maze-100-1.map 100 100 83 18 55 47 445 +111 maze-100-1.map 100 100 87 71 40 23 447 +111 maze-100-1.map 100 100 54 91 6 39 444 +111 maze-100-1.map 100 100 89 68 46 21 444 +111 maze-100-1.map 100 100 1 55 58 83 447 +111 maze-100-1.map 100 100 9 5 95 34 447 +111 maze-100-1.map 100 100 54 43 85 28 444 +111 maze-100-1.map 100 100 33 2 96 51 446 +112 maze-100-1.map 100 100 69 25 9 95 450 +112 maze-100-1.map 100 100 85 1 9 79 450 +112 maze-100-1.map 100 100 62 49 73 47 451 +112 maze-100-1.map 100 100 34 95 41 29 451 +112 maze-100-1.map 100 100 9 19 21 91 448 +112 maze-100-1.map 100 100 8 69 57 67 449 +112 maze-100-1.map 100 100 51 33 67 45 448 +112 maze-100-1.map 100 100 75 27 16 87 451 +112 maze-100-1.map 100 100 67 17 18 93 451 +112 maze-100-1.map 100 100 33 2 43 47 449 +113 maze-100-1.map 100 100 5 94 71 6 452 +113 maze-100-1.map 100 100 43 17 43 95 454 +113 maze-100-1.map 100 100 90 83 19 39 453 +113 maze-100-1.map 100 100 58 25 66 61 452 +113 maze-100-1.map 100 100 13 35 71 99 454 +113 maze-100-1.map 100 100 69 33 29 85 452 +113 maze-100-1.map 100 100 1 12 20 75 454 +113 maze-100-1.map 100 100 95 47 41 49 452 +113 maze-100-1.map 100 100 47 75 4 55 453 +113 maze-100-1.map 100 100 15 2 21 71 453 +114 maze-100-1.map 100 100 77 8 6 97 456 +114 maze-100-1.map 100 100 65 4 1 89 459 +114 maze-100-1.map 100 100 17 43 63 87 458 +114 maze-100-1.map 100 100 57 25 2 85 459 +114 maze-100-1.map 100 100 63 63 65 10 457 +114 maze-100-1.map 100 100 55 67 61 34 459 +114 maze-100-1.map 100 100 11 52 59 94 456 +114 maze-100-1.map 100 100 30 37 75 48 456 +114 maze-100-1.map 100 100 19 62 97 67 457 +114 maze-100-1.map 100 100 51 66 6 63 456 +115 maze-100-1.map 100 100 7 52 39 58 460 +115 maze-100-1.map 100 100 21 54 15 83 463 +115 maze-100-1.map 100 100 90 17 43 11 461 +115 maze-100-1.map 100 100 41 31 67 45 460 +115 maze-100-1.map 100 100 79 57 27 60 463 +115 maze-100-1.map 100 100 65 35 54 43 463 +115 maze-100-1.map 100 100 10 9 4 89 460 +115 maze-100-1.map 100 100 92 99 29 65 461 +115 maze-100-1.map 100 100 98 39 3 3 463 +115 maze-100-1.map 100 100 61 28 21 87 463 +116 maze-100-1.map 100 100 68 63 18 39 466 +116 maze-100-1.map 100 100 40 45 32 91 464 +116 maze-100-1.map 100 100 95 20 45 53 465 +116 maze-100-1.map 100 100 27 57 81 43 464 +116 maze-100-1.map 100 100 23 33 1 92 467 +116 maze-100-1.map 100 100 23 49 35 85 464 +116 maze-100-1.map 100 100 97 53 29 66 465 +116 maze-100-1.map 100 100 63 57 7 83 466 +116 maze-100-1.map 100 100 97 59 16 69 467 +116 maze-100-1.map 100 100 47 57 7 33 464 +117 maze-100-1.map 100 100 54 15 43 63 469 +117 maze-100-1.map 100 100 84 53 29 31 471 +117 maze-100-1.map 100 100 69 66 22 49 470 +117 maze-100-1.map 100 100 19 85 27 61 468 +117 maze-100-1.map 100 100 35 97 37 33 470 +117 maze-100-1.map 100 100 39 83 31 3 468 +117 maze-100-1.map 100 100 10 5 25 67 469 +117 maze-100-1.map 100 100 23 1 93 38 469 +117 maze-100-1.map 100 100 37 32 87 60 470 +117 maze-100-1.map 100 100 59 74 23 18 470 +118 maze-100-1.map 100 100 33 73 51 35 472 +118 maze-100-1.map 100 100 11 8 75 51 473 +118 maze-100-1.map 100 100 17 62 29 81 475 +118 maze-100-1.map 100 100 55 81 3 47 474 +118 maze-100-1.map 100 100 26 17 3 95 473 +118 maze-100-1.map 100 100 89 7 33 2 475 +118 maze-100-1.map 100 100 31 86 91 11 475 +118 maze-100-1.map 100 100 49 62 13 13 475 +118 maze-100-1.map 100 100 65 27 8 3 475 +118 maze-100-1.map 100 100 89 61 26 57 473 +119 maze-100-1.map 100 100 5 87 76 11 479 +119 maze-100-1.map 100 100 87 26 59 53 479 +119 maze-100-1.map 100 100 27 64 81 47 479 +119 maze-100-1.map 100 100 91 47 9 6 477 +119 maze-100-1.map 100 100 75 3 1 93 476 +119 maze-100-1.map 100 100 53 60 89 32 478 +119 maze-100-1.map 100 100 84 15 45 83 479 +119 maze-100-1.map 100 100 53 74 3 76 476 +119 maze-100-1.map 100 100 27 90 99 45 479 +119 maze-100-1.map 100 100 63 73 60 13 479 +120 maze-100-1.map 100 100 53 85 4 63 481 +120 maze-100-1.map 100 100 94 83 22 57 480 +120 maze-100-1.map 100 100 57 14 57 85 481 +120 maze-100-1.map 100 100 76 7 3 84 482 +120 maze-100-1.map 100 100 25 25 73 73 480 +120 maze-100-1.map 100 100 73 30 57 61 481 +120 maze-100-1.map 100 100 35 59 9 41 480 +120 maze-100-1.map 100 100 33 47 19 31 482 +120 maze-100-1.map 100 100 85 53 17 51 482 +120 maze-100-1.map 100 100 27 58 89 19 481 +121 maze-100-1.map 100 100 89 73 28 29 485 +121 maze-100-1.map 100 100 44 65 15 16 486 +121 maze-100-1.map 100 100 53 35 43 1 484 +121 maze-100-1.map 100 100 77 15 3 97 484 +121 maze-100-1.map 100 100 97 33 7 3 484 +121 maze-100-1.map 100 100 81 6 51 34 484 +121 maze-100-1.map 100 100 83 96 21 27 485 +121 maze-100-1.map 100 100 13 2 39 39 487 +121 maze-100-1.map 100 100 4 1 19 65 485 +121 maze-100-1.map 100 100 39 89 21 65 486 +122 maze-100-1.map 100 100 60 65 13 11 489 +122 maze-100-1.map 100 100 33 40 17 25 489 +122 maze-100-1.map 100 100 76 37 51 71 491 +122 maze-100-1.map 100 100 89 53 19 61 490 +122 maze-100-1.map 100 100 37 51 92 7 489 +122 maze-100-1.map 100 100 24 99 25 7 489 +122 maze-100-1.map 100 100 24 57 85 3 489 +122 maze-100-1.map 100 100 65 15 25 93 490 +122 maze-100-1.map 100 100 51 33 9 94 489 +122 maze-100-1.map 100 100 35 7 68 51 491 +123 maze-100-1.map 100 100 19 69 89 9 494 +123 maze-100-1.map 100 100 68 81 5 37 493 +123 maze-100-1.map 100 100 24 69 13 83 495 +123 maze-100-1.map 100 100 93 97 49 19 494 +123 maze-100-1.map 100 100 51 74 55 22 492 +123 maze-100-1.map 100 100 67 20 59 72 492 +123 maze-100-1.map 100 100 89 14 31 3 495 +123 maze-100-1.map 100 100 57 21 59 85 494 +123 maze-100-1.map 100 100 52 37 97 31 493 +123 maze-100-1.map 100 100 53 27 95 73 492 +124 maze-100-1.map 100 100 39 3 84 3 499 +124 maze-100-1.map 100 100 85 66 13 40 498 +124 maze-100-1.map 100 100 41 41 5 25 496 +124 maze-100-1.map 100 100 19 42 34 47 498 +124 maze-100-1.map 100 100 17 1 41 46 497 +124 maze-100-1.map 100 100 29 74 37 1 497 +124 maze-100-1.map 100 100 18 49 45 78 496 +124 maze-100-1.map 100 100 49 61 69 8 497 +124 maze-100-1.map 100 100 99 98 11 71 499 +124 maze-100-1.map 100 100 41 29 83 56 497 +125 maze-100-1.map 100 100 3 59 67 85 502 +125 maze-100-1.map 100 100 65 77 21 53 500 +125 maze-100-1.map 100 100 90 85 19 60 502 +125 maze-100-1.map 100 100 23 95 25 52 501 +125 maze-100-1.map 100 100 66 7 50 93 500 +125 maze-100-1.map 100 100 15 95 71 31 500 +125 maze-100-1.map 100 100 19 62 39 73 501 +125 maze-100-1.map 100 100 6 91 21 55 503 +125 maze-100-1.map 100 100 82 41 17 69 501 +125 maze-100-1.map 100 100 48 13 35 53 501 +126 maze-100-1.map 100 100 19 65 87 41 504 +126 maze-100-1.map 100 100 3 1 39 89 504 +126 maze-100-1.map 100 100 51 69 12 77 507 +126 maze-100-1.map 100 100 24 59 91 82 506 +126 maze-100-1.map 100 100 51 66 25 10 506 +126 maze-100-1.map 100 100 55 53 61 27 504 +126 maze-100-1.map 100 100 19 44 35 65 507 +126 maze-100-1.map 100 100 15 86 92 41 504 +126 maze-100-1.map 100 100 53 95 9 57 506 +126 maze-100-1.map 100 100 21 97 41 7 506 +127 maze-100-1.map 100 100 1 16 93 25 511 +127 maze-100-1.map 100 100 31 84 52 45 510 +127 maze-100-1.map 100 100 91 21 67 50 511 +127 maze-100-1.map 100 100 1 97 42 9 509 +127 maze-100-1.map 100 100 53 10 52 95 508 +127 maze-100-1.map 100 100 17 25 79 85 510 +127 maze-100-1.map 100 100 60 99 1 54 510 +127 maze-100-1.map 100 100 10 9 61 83 509 +127 maze-100-1.map 100 100 19 32 83 89 509 +127 maze-100-1.map 100 100 65 61 86 25 511 +128 maze-100-1.map 100 100 71 75 9 40 513 +128 maze-100-1.map 100 100 13 64 25 55 513 +128 maze-100-1.map 100 100 23 62 42 77 514 +128 maze-100-1.map 100 100 39 83 54 45 513 +128 maze-100-1.map 100 100 39 93 65 13 514 +128 maze-100-1.map 100 100 47 83 8 79 513 +128 maze-100-1.map 100 100 55 71 4 49 513 +128 maze-100-1.map 100 100 10 65 47 57 515 +128 maze-100-1.map 100 100 87 83 47 27 512 +128 maze-100-1.map 100 100 31 84 7 3 515 +129 maze-100-1.map 100 100 91 3 1 16 519 +129 maze-100-1.map 100 100 61 61 77 21 516 +129 maze-100-1.map 100 100 79 97 19 42 517 +129 maze-100-1.map 100 100 55 25 63 99 518 +129 maze-100-1.map 100 100 35 73 98 29 519 +129 maze-100-1.map 100 100 15 5 54 61 519 +129 maze-100-1.map 100 100 9 95 64 27 519 +129 maze-100-1.map 100 100 36 69 8 23 518 +129 maze-100-1.map 100 100 88 3 27 3 517 +129 maze-100-1.map 100 100 1 27 15 62 519 +130 maze-100-1.map 100 100 57 73 57 1 520 +130 maze-100-1.map 100 100 93 87 24 69 523 +130 maze-100-1.map 100 100 57 41 98 25 521 +130 maze-100-1.map 100 100 99 66 45 21 521 +130 maze-100-1.map 100 100 99 47 37 72 523 +130 maze-100-1.map 100 100 16 77 46 71 522 +130 maze-100-1.map 100 100 69 25 52 91 523 +130 maze-100-1.map 100 100 1 7 14 83 523 +130 maze-100-1.map 100 100 12 99 28 65 520 +130 maze-100-1.map 100 100 21 4 63 41 521 +131 maze-100-1.map 100 100 39 73 40 51 527 +131 maze-100-1.map 100 100 6 71 83 12 524 +131 maze-100-1.map 100 100 27 99 77 23 526 +131 maze-100-1.map 100 100 62 17 47 78 524 +131 maze-100-1.map 100 100 73 45 43 29 526 +131 maze-100-1.map 100 100 81 93 45 6 527 +131 maze-100-1.map 100 100 43 12 23 98 524 +131 maze-100-1.map 100 100 42 9 62 61 524 +131 maze-100-1.map 100 100 28 91 81 9 527 +131 maze-100-1.map 100 100 67 15 51 76 527 +132 maze-100-1.map 100 100 45 80 66 29 530 +132 maze-100-1.map 100 100 9 54 41 73 529 +132 maze-100-1.map 100 100 15 66 33 77 529 +132 maze-100-1.map 100 100 65 59 95 33 528 +132 maze-100-1.map 100 100 5 81 57 89 528 +132 maze-100-1.map 100 100 79 9 55 93 528 +132 maze-100-1.map 100 100 53 69 71 25 530 +132 maze-100-1.map 100 100 43 6 11 87 529 +132 maze-100-1.map 100 100 60 67 69 29 531 +132 maze-100-1.map 100 100 25 88 55 38 528 +133 maze-100-1.map 100 100 43 92 61 34 534 +133 maze-100-1.map 100 100 28 97 47 37 535 +133 maze-100-1.map 100 100 53 83 7 80 533 +133 maze-100-1.map 100 100 16 59 73 64 534 +133 maze-100-1.map 100 100 11 52 37 42 534 +133 maze-100-1.map 100 100 1 83 77 33 534 +133 maze-100-1.map 100 100 43 62 31 7 535 +133 maze-100-1.map 100 100 41 55 16 21 535 +133 maze-100-1.map 100 100 71 24 59 74 532 +133 maze-100-1.map 100 100 79 15 29 97 532 +134 maze-100-1.map 100 100 48 63 9 73 537 +134 maze-100-1.map 100 100 17 55 92 83 537 +134 maze-100-1.map 100 100 89 23 23 93 536 +134 maze-100-1.map 100 100 73 27 61 72 539 +134 maze-100-1.map 100 100 31 95 21 49 536 +134 maze-100-1.map 100 100 11 45 71 85 536 +134 maze-100-1.map 100 100 12 87 35 3 539 +134 maze-100-1.map 100 100 69 47 45 29 538 +134 maze-100-1.map 100 100 26 17 53 92 536 +134 maze-100-1.map 100 100 16 77 47 85 539 +135 maze-100-1.map 100 100 6 39 77 97 543 +135 maze-100-1.map 100 100 16 63 93 33 541 +135 maze-100-1.map 100 100 58 85 7 82 542 +135 maze-100-1.map 100 100 1 96 44 43 540 +135 maze-100-1.map 100 100 78 71 10 29 540 +135 maze-100-1.map 100 100 69 41 23 63 540 +135 maze-100-1.map 100 100 8 79 55 77 543 +135 maze-100-1.map 100 100 54 67 73 33 541 +135 maze-100-1.map 100 100 22 89 65 34 540 +135 maze-100-1.map 100 100 54 77 77 5 541 +136 maze-100-1.map 100 100 73 85 55 22 547 +136 maze-100-1.map 100 100 94 59 14 25 546 +136 maze-100-1.map 100 100 7 89 25 66 545 +136 maze-100-1.map 100 100 10 71 83 5 547 +136 maze-100-1.map 100 100 89 31 53 72 545 +136 maze-100-1.map 100 100 29 67 1 89 546 +136 maze-100-1.map 100 100 92 31 53 71 547 +136 maze-100-1.map 100 100 28 69 5 99 547 +136 maze-100-1.map 100 100 13 47 29 43 544 +136 maze-100-1.map 100 100 61 48 99 55 547 +137 maze-100-1.map 100 100 4 51 41 65 551 +137 maze-100-1.map 100 100 37 58 83 31 551 +137 maze-100-1.map 100 100 37 61 83 31 548 +137 maze-100-1.map 100 100 39 87 59 54 549 +137 maze-100-1.map 100 100 48 59 3 73 549 +137 maze-100-1.map 100 100 43 49 7 90 551 +137 maze-100-1.map 100 100 9 91 94 7 549 +137 maze-100-1.map 100 100 63 29 53 68 549 +137 maze-100-1.map 100 100 31 3 67 49 550 +137 maze-100-1.map 100 100 95 10 59 59 549 +138 maze-100-1.map 100 100 35 97 85 25 554 +138 maze-100-1.map 100 100 87 45 67 55 554 +138 maze-100-1.map 100 100 53 3 68 91 553 +138 maze-100-1.map 100 100 60 83 71 30 554 +138 maze-100-1.map 100 100 87 6 1 11 555 +138 maze-100-1.map 100 100 43 11 55 89 554 +138 maze-100-1.map 100 100 9 81 2 17 553 +138 maze-100-1.map 100 100 45 81 93 38 555 +138 maze-100-1.map 100 100 89 14 54 33 552 +138 maze-100-1.map 100 100 21 8 64 85 552 +139 maze-100-1.map 100 100 67 14 65 81 559 +139 maze-100-1.map 100 100 24 11 45 59 557 +139 maze-100-1.map 100 100 7 93 99 57 556 +139 maze-100-1.map 100 100 44 61 77 23 559 +139 maze-100-1.map 100 100 63 71 46 19 557 +139 maze-100-1.map 100 100 47 83 71 27 556 +139 maze-100-1.map 100 100 57 93 7 73 558 +139 maze-100-1.map 100 100 7 20 65 93 557 +139 maze-100-1.map 100 100 66 29 57 65 559 +139 maze-100-1.map 100 100 11 53 79 90 557 +140 maze-100-1.map 100 100 11 25 87 92 563 +140 maze-100-1.map 100 100 49 2 89 73 561 +140 maze-100-1.map 100 100 11 50 79 67 561 +140 maze-100-1.map 100 100 83 69 57 1 562 +140 maze-100-1.map 100 100 31 20 54 77 562 +140 maze-100-1.map 100 100 79 9 55 72 561 +140 maze-100-1.map 100 100 59 92 85 19 561 +140 maze-100-1.map 100 100 91 17 53 57 562 +140 maze-100-1.map 100 100 67 14 63 79 563 +140 maze-100-1.map 100 100 73 79 21 18 561 +141 maze-100-1.map 100 100 79 16 41 87 565 +141 maze-100-1.map 100 100 95 5 63 51 566 +141 maze-100-1.map 100 100 78 25 51 84 564 +141 maze-100-1.map 100 100 59 11 75 99 564 +141 maze-100-1.map 100 100 8 75 59 78 564 +141 maze-100-1.map 100 100 91 43 3 86 565 +141 maze-100-1.map 100 100 92 1 19 96 564 +141 maze-100-1.map 100 100 75 91 69 9 564 +141 maze-100-1.map 100 100 13 73 44 63 565 +141 maze-100-1.map 100 100 23 13 31 56 565 +142 maze-100-1.map 100 100 4 95 17 59 571 +142 maze-100-1.map 100 100 97 65 13 35 570 +142 maze-100-1.map 100 100 51 9 73 74 571 +142 maze-100-1.map 100 100 43 1 36 97 571 +142 maze-100-1.map 100 100 18 5 65 49 571 +142 maze-100-1.map 100 100 95 58 19 45 571 +142 maze-100-1.map 100 100 49 3 91 79 570 +142 maze-100-1.map 100 100 36 89 71 57 569 +142 maze-100-1.map 100 100 3 51 33 41 568 +142 maze-100-1.map 100 100 59 23 68 99 569 +143 maze-100-1.map 100 100 9 88 57 44 574 +143 maze-100-1.map 100 100 1 56 87 93 575 +143 maze-100-1.map 100 100 65 82 7 81 575 +143 maze-100-1.map 100 100 53 85 39 6 573 +143 maze-100-1.map 100 100 67 58 37 87 573 +143 maze-100-1.map 100 100 25 93 43 51 572 +143 maze-100-1.map 100 100 11 98 83 12 574 +143 maze-100-1.map 100 100 1 70 77 88 572 +143 maze-100-1.map 100 100 67 77 39 24 575 +143 maze-100-1.map 100 100 88 41 28 29 572 +144 maze-100-1.map 100 100 57 9 83 91 576 +144 maze-100-1.map 100 100 16 19 77 93 579 +144 maze-100-1.map 100 100 71 38 64 79 576 +144 maze-100-1.map 100 100 71 11 80 73 579 +144 maze-100-1.map 100 100 44 95 75 31 579 +144 maze-100-1.map 100 100 40 99 71 25 579 +144 maze-100-1.map 100 100 91 5 35 87 578 +144 maze-100-1.map 100 100 21 29 76 59 579 +144 maze-100-1.map 100 100 35 47 61 40 579 +144 maze-100-1.map 100 100 12 5 65 52 576 +145 maze-100-1.map 100 100 93 53 19 45 582 +145 maze-100-1.map 100 100 40 91 43 5 581 +145 maze-100-1.map 100 100 10 43 99 60 582 +145 maze-100-1.map 100 100 63 79 28 7 581 +145 maze-100-1.map 100 100 74 95 69 24 580 +145 maze-100-1.map 100 100 20 29 84 59 582 +145 maze-100-1.map 100 100 3 94 2 11 580 +145 maze-100-1.map 100 100 90 63 51 5 581 +145 maze-100-1.map 100 100 3 37 89 94 583 +145 maze-100-1.map 100 100 83 5 1 24 581 +146 maze-100-1.map 100 100 35 45 23 15 586 +146 maze-100-1.map 100 100 17 16 39 70 586 +146 maze-100-1.map 100 100 73 95 67 20 585 +146 maze-100-1.map 100 100 23 16 35 44 586 +146 maze-100-1.map 100 100 42 1 55 84 586 +146 maze-100-1.map 100 100 99 69 37 25 586 +146 maze-100-1.map 100 100 58 85 73 22 584 +146 maze-100-1.map 100 100 77 16 69 99 585 +146 maze-100-1.map 100 100 4 19 79 64 584 +146 maze-100-1.map 100 100 55 25 80 89 587 +147 maze-100-1.map 100 100 62 63 23 87 591 +147 maze-100-1.map 100 100 34 41 61 35 589 +147 maze-100-1.map 100 100 61 46 11 82 590 +147 maze-100-1.map 100 100 77 98 19 20 588 +147 maze-100-1.map 100 100 35 67 79 36 591 +147 maze-100-1.map 100 100 67 85 17 78 591 +147 maze-100-1.map 100 100 99 60 7 29 591 +147 maze-100-1.map 100 100 7 68 68 97 588 +147 maze-100-1.map 100 100 74 15 51 55 589 +147 maze-100-1.map 100 100 40 15 95 67 589 +148 maze-100-1.map 100 100 93 5 67 49 594 +148 maze-100-1.map 100 100 75 83 57 27 594 +148 maze-100-1.map 100 100 73 37 77 90 593 +148 maze-100-1.map 100 100 21 91 1 20 593 +148 maze-100-1.map 100 100 71 21 75 85 592 +148 maze-100-1.map 100 100 73 94 7 7 595 +148 maze-100-1.map 100 100 58 19 75 96 592 +148 maze-100-1.map 100 100 79 95 69 35 594 +148 maze-100-1.map 100 100 40 71 69 4 592 +148 maze-100-1.map 100 100 97 33 51 79 592 +149 maze-100-1.map 100 100 91 2 59 75 599 +149 maze-100-1.map 100 100 80 39 21 26 596 +149 maze-100-1.map 100 100 77 73 77 5 596 +149 maze-100-1.map 100 100 47 63 23 1 598 +149 maze-100-1.map 100 100 22 99 15 59 597 +149 maze-100-1.map 100 100 61 61 22 87 597 +149 maze-100-1.map 100 100 63 91 71 24 597 +149 maze-100-1.map 100 100 20 71 61 91 599 +149 maze-100-1.map 100 100 36 23 85 59 597 +149 maze-100-1.map 100 100 37 42 11 20 596 +150 maze-100-1.map 100 100 39 58 97 14 602 +150 maze-100-1.map 100 100 23 16 88 71 602 +150 maze-100-1.map 100 100 96 97 37 19 601 +150 maze-100-1.map 100 100 98 79 13 28 600 +150 maze-100-1.map 100 100 45 81 57 47 602 +150 maze-100-1.map 100 100 13 73 61 99 602 +150 maze-100-1.map 100 100 85 41 12 31 603 +150 maze-100-1.map 100 100 91 47 55 82 603 +150 maze-100-1.map 100 100 1 37 92 65 601 +150 maze-100-1.map 100 100 67 57 83 9 600 +151 maze-100-1.map 100 100 37 5 74 79 607 +151 maze-100-1.map 100 100 91 54 49 6 604 +151 maze-100-1.map 100 100 49 76 93 1 607 +151 maze-100-1.map 100 100 16 3 25 93 605 +151 maze-100-1.map 100 100 6 5 43 69 605 +151 maze-100-1.map 100 100 14 99 83 5 605 +151 maze-100-1.map 100 100 98 33 49 91 607 +151 maze-100-1.map 100 100 73 54 11 83 607 +151 maze-100-1.map 100 100 73 41 70 75 605 +151 maze-100-1.map 100 100 39 7 61 85 604 +152 maze-100-1.map 100 100 73 75 73 35 608 +152 maze-100-1.map 100 100 58 27 65 97 609 +152 maze-100-1.map 100 100 3 85 55 55 610 +152 maze-100-1.map 100 100 63 54 82 1 608 +152 maze-100-1.map 100 100 53 77 65 27 610 +152 maze-100-1.map 100 100 73 95 76 29 609 +152 maze-100-1.map 100 100 28 95 89 9 609 +152 maze-100-1.map 100 100 53 54 1 82 608 +152 maze-100-1.map 100 100 72 83 13 79 611 +152 maze-100-1.map 100 100 83 30 37 53 609 +153 maze-100-1.map 100 100 25 8 43 74 614 +153 maze-100-1.map 100 100 67 97 19 9 612 +153 maze-100-1.map 100 100 43 9 72 99 615 +153 maze-100-1.map 100 100 87 31 43 89 614 +153 maze-100-1.map 100 100 89 83 14 35 615 +153 maze-100-1.map 100 100 83 89 3 77 612 +153 maze-100-1.map 100 100 63 75 20 27 615 +153 maze-100-1.map 100 100 84 77 67 9 613 +153 maze-100-1.map 100 100 29 9 33 50 615 +153 maze-100-1.map 100 100 53 95 92 23 615 +154 maze-100-1.map 100 100 1 5 43 65 618 +154 maze-100-1.map 100 100 13 21 85 91 618 +154 maze-100-1.map 100 100 89 15 63 63 618 +154 maze-100-1.map 100 100 47 76 25 87 617 +154 maze-100-1.map 100 100 72 81 11 79 617 +154 maze-100-1.map 100 100 82 59 5 43 617 +154 maze-100-1.map 100 100 37 64 13 10 616 +154 maze-100-1.map 100 100 13 43 75 57 616 +154 maze-100-1.map 100 100 69 81 85 28 619 +154 maze-100-1.map 100 100 42 9 58 97 618 +155 maze-100-1.map 100 100 23 97 5 17 622 +155 maze-100-1.map 100 100 15 89 57 55 620 +155 maze-100-1.map 100 100 82 19 75 79 623 +155 maze-100-1.map 100 100 77 44 14 35 620 +155 maze-100-1.map 100 100 29 49 77 1 620 +155 maze-100-1.map 100 100 46 15 85 43 621 +155 maze-100-1.map 100 100 34 41 73 10 620 +155 maze-100-1.map 100 100 65 51 35 74 623 +155 maze-100-1.map 100 100 63 79 40 9 621 +155 maze-100-1.map 100 100 13 2 49 70 622 +156 maze-100-1.map 100 100 97 82 13 50 624 +156 maze-100-1.map 100 100 15 34 65 75 625 +156 maze-100-1.map 100 100 75 3 71 92 627 +156 maze-100-1.map 100 100 27 79 51 75 624 +156 maze-100-1.map 100 100 71 15 86 79 627 +156 maze-100-1.map 100 100 31 3 63 88 627 +156 maze-100-1.map 100 100 31 23 92 93 625 +156 maze-100-1.map 100 100 31 45 75 3 626 +156 maze-100-1.map 100 100 93 82 40 17 624 +156 maze-100-1.map 100 100 99 2 49 92 624 +157 maze-100-1.map 100 100 52 77 99 45 631 +157 maze-100-1.map 100 100 27 14 66 89 628 +157 maze-100-1.map 100 100 93 97 2 61 629 +157 maze-100-1.map 100 100 91 47 51 81 630 +157 maze-100-1.map 100 100 83 95 14 81 629 +157 maze-100-1.map 100 100 87 81 36 17 629 +157 maze-100-1.map 100 100 76 35 61 99 629 +157 maze-100-1.map 100 100 78 71 29 5 631 +157 maze-100-1.map 100 100 77 25 78 73 629 +157 maze-100-1.map 100 100 96 57 57 3 629 +158 maze-100-1.map 100 100 12 21 83 80 634 +158 maze-100-1.map 100 100 35 64 75 31 635 +158 maze-100-1.map 100 100 97 13 35 58 635 +158 maze-100-1.map 100 100 72 29 68 79 632 +158 maze-100-1.map 100 100 25 19 73 70 633 +158 maze-100-1.map 100 100 27 98 56 61 634 +158 maze-100-1.map 100 100 42 53 77 21 633 +158 maze-100-1.map 100 100 53 19 93 55 632 +158 maze-100-1.map 100 100 9 95 65 59 632 +158 maze-100-1.map 100 100 53 93 87 49 634 +159 maze-100-1.map 100 100 44 3 73 95 639 +159 maze-100-1.map 100 100 43 13 39 64 637 +159 maze-100-1.map 100 100 67 4 85 83 637 +159 maze-100-1.map 100 100 36 69 94 29 638 +159 maze-100-1.map 100 100 71 79 68 33 637 +159 maze-100-1.map 100 100 65 92 33 21 639 +159 maze-100-1.map 100 100 69 13 90 63 639 +159 maze-100-1.map 100 100 91 51 6 57 639 +159 maze-100-1.map 100 100 97 93 1 63 638 +159 maze-100-1.map 100 100 55 41 23 97 636 +160 maze-100-1.map 100 100 31 47 58 19 641 +160 maze-100-1.map 100 100 96 73 1 58 640 +160 maze-100-1.map 100 100 83 47 3 19 640 +160 maze-100-1.map 100 100 41 97 87 45 642 +160 maze-100-1.map 100 100 5 9 29 48 643 +160 maze-100-1.map 100 100 37 83 43 66 643 +160 maze-100-1.map 100 100 95 33 33 59 640 +160 maze-100-1.map 100 100 83 92 26 19 642 +160 maze-100-1.map 100 100 75 59 9 47 642 +160 maze-100-1.map 100 100 49 7 81 61 642 +161 maze-100-1.map 100 100 81 19 72 81 647 +161 maze-100-1.map 100 100 63 65 1 35 644 +161 maze-100-1.map 100 100 37 61 85 49 644 +161 maze-100-1.map 100 100 54 93 9 3 647 +161 maze-100-1.map 100 100 85 41 50 3 647 +161 maze-100-1.map 100 100 48 87 96 41 646 +161 maze-100-1.map 100 100 64 79 63 36 644 +161 maze-100-1.map 100 100 93 73 7 8 647 +161 maze-100-1.map 100 100 72 73 25 21 647 +161 maze-100-1.map 100 100 67 96 29 22 646 +162 maze-100-1.map 100 100 69 22 84 87 648 +162 maze-100-1.map 100 100 93 5 59 94 649 +162 maze-100-1.map 100 100 35 44 88 27 650 +162 maze-100-1.map 100 100 57 93 87 49 650 +162 maze-100-1.map 100 100 43 97 91 3 650 +162 maze-100-1.map 100 100 69 73 91 24 649 +162 maze-100-1.map 100 100 77 90 85 29 649 +162 maze-100-1.map 100 100 77 92 30 15 648 +162 maze-100-1.map 100 100 53 12 99 80 650 +162 maze-100-1.map 100 100 8 29 77 42 648 +163 maze-100-1.map 100 100 89 68 43 11 655 +163 maze-100-1.map 100 100 98 49 55 75 655 +163 maze-100-1.map 100 100 81 57 11 28 655 +163 maze-100-1.map 100 100 23 84 64 83 652 +163 maze-100-1.map 100 100 25 83 59 97 652 +163 maze-100-1.map 100 100 96 95 1 43 655 +163 maze-100-1.map 100 100 53 20 79 57 655 +163 maze-100-1.map 100 100 17 71 74 81 653 +163 maze-100-1.map 100 100 63 21 85 85 654 +163 maze-100-1.map 100 100 75 70 39 13 653 +164 maze-100-1.map 100 100 55 81 33 73 658 +164 maze-100-1.map 100 100 54 1 85 57 657 +164 maze-100-1.map 100 100 77 75 61 29 658 +164 maze-100-1.map 100 100 86 1 53 72 656 +164 maze-100-1.map 100 100 25 71 41 69 658 +164 maze-100-1.map 100 100 74 87 95 13 659 +164 maze-100-1.map 100 100 11 83 47 66 657 +164 maze-100-1.map 100 100 77 26 71 96 658 +164 maze-100-1.map 100 100 41 94 12 5 658 +164 maze-100-1.map 100 100 67 11 98 59 659 +165 maze-100-1.map 100 100 17 89 62 59 661 +165 maze-100-1.map 100 100 55 20 72 59 660 +165 maze-100-1.map 100 100 99 94 8 61 660 +165 maze-100-1.map 100 100 59 85 25 85 662 +165 maze-100-1.map 100 100 15 23 74 65 663 +165 maze-100-1.map 100 100 86 71 76 23 660 +165 maze-100-1.map 100 100 83 82 20 79 662 +165 maze-100-1.map 100 100 89 16 53 90 662 +165 maze-100-1.map 100 100 79 22 89 69 661 +165 maze-100-1.map 100 100 51 73 1 8 661 +166 maze-100-1.map 100 100 69 75 67 32 665 +166 maze-100-1.map 100 100 27 82 34 67 666 +166 maze-100-1.map 100 100 96 63 23 16 666 +166 maze-100-1.map 100 100 10 45 84 53 666 +166 maze-100-1.map 100 100 95 93 6 35 667 +166 maze-100-1.map 100 100 86 51 21 20 666 +166 maze-100-1.map 100 100 83 65 73 18 667 +166 maze-100-1.map 100 100 56 99 93 43 665 +166 maze-100-1.map 100 100 40 79 41 97 667 +166 maze-100-1.map 100 100 91 78 73 16 664 +167 maze-100-1.map 100 100 79 19 72 97 671 +167 maze-100-1.map 100 100 21 4 31 57 669 +167 maze-100-1.map 100 100 96 41 77 76 670 +167 maze-100-1.map 100 100 81 2 56 81 668 +167 maze-100-1.map 100 100 11 24 64 65 668 +167 maze-100-1.map 100 100 76 87 24 83 670 +167 maze-100-1.map 100 100 13 60 75 48 668 +167 maze-100-1.map 100 100 93 41 35 55 668 +167 maze-100-1.map 100 100 84 39 55 4 668 +167 maze-100-1.map 100 100 63 63 23 90 671 +168 maze-100-1.map 100 100 91 59 27 14 675 +168 maze-100-1.map 100 100 91 41 34 59 675 +168 maze-100-1.map 100 100 39 6 71 94 674 +168 maze-100-1.map 100 100 76 31 81 63 673 +168 maze-100-1.map 100 100 52 5 77 49 675 +168 maze-100-1.map 100 100 63 29 43 74 673 +168 maze-100-1.map 100 100 71 65 7 57 672 +168 maze-100-1.map 100 100 77 76 65 29 673 +168 maze-100-1.map 100 100 92 57 26 11 674 +168 maze-100-1.map 100 100 91 33 7 59 674 +169 maze-100-1.map 100 100 45 85 13 95 678 +169 maze-100-1.map 100 100 97 95 10 17 679 +169 maze-100-1.map 100 100 1 13 62 89 677 +169 maze-100-1.map 100 100 95 34 77 83 677 +169 maze-100-1.map 100 100 47 88 84 49 676 +169 maze-100-1.map 100 100 29 3 77 92 677 +169 maze-100-1.map 100 100 3 53 88 53 679 +169 maze-100-1.map 100 100 83 85 33 14 677 +169 maze-100-1.map 100 100 73 74 94 31 676 +169 maze-100-1.map 100 100 99 5 29 58 679 +170 maze-100-1.map 100 100 97 87 69 8 683 +170 maze-100-1.map 100 100 61 41 98 87 683 +170 maze-100-1.map 100 100 93 46 31 53 681 +170 maze-100-1.map 100 100 81 53 23 15 680 +170 maze-100-1.map 100 100 96 21 37 63 681 +170 maze-100-1.map 100 100 3 86 48 69 682 +170 maze-100-1.map 100 100 60 13 95 72 682 +170 maze-100-1.map 100 100 63 27 43 75 680 +170 maze-100-1.map 100 100 51 54 24 87 680 +170 maze-100-1.map 100 100 91 73 73 27 680 +171 maze-100-1.map 100 100 55 13 67 73 684 +171 maze-100-1.map 100 100 89 95 7 77 684 +171 maze-100-1.map 100 100 75 79 98 53 687 +171 maze-100-1.map 100 100 60 7 88 41 684 +171 maze-100-1.map 100 100 93 15 66 87 687 +171 maze-100-1.map 100 100 88 39 9 61 687 +171 maze-100-1.map 100 100 45 83 46 67 685 +171 maze-100-1.map 100 100 53 82 84 7 686 +171 maze-100-1.map 100 100 50 3 94 93 684 +171 maze-100-1.map 100 100 97 33 72 83 685 +172 maze-100-1.map 100 100 23 87 35 59 688 +172 maze-100-1.map 100 100 92 91 56 15 690 +172 maze-100-1.map 100 100 88 81 57 6 688 +172 maze-100-1.map 100 100 50 89 30 85 690 +172 maze-100-1.map 100 100 99 33 69 90 691 +172 maze-100-1.map 100 100 35 83 47 56 691 +172 maze-100-1.map 100 100 92 67 19 10 688 +172 maze-100-1.map 100 100 55 27 89 36 691 +172 maze-100-1.map 100 100 73 74 91 11 689 +172 maze-100-1.map 100 100 91 26 81 80 690 +173 maze-100-1.map 100 100 59 21 91 49 692 +173 maze-100-1.map 100 100 79 79 97 23 694 +173 maze-100-1.map 100 100 70 41 9 53 693 +173 maze-100-1.map 100 100 37 76 63 89 695 +173 maze-100-1.map 100 100 40 99 39 74 692 +173 maze-100-1.map 100 100 17 76 93 58 694 +173 maze-100-1.map 100 100 69 8 71 61 695 +173 maze-100-1.map 100 100 42 63 9 95 695 +173 maze-100-1.map 100 100 50 71 11 88 694 +173 maze-100-1.map 100 100 78 3 82 51 692 +174 maze-100-1.map 100 100 15 16 86 57 698 +174 maze-100-1.map 100 100 5 23 69 43 696 +174 maze-100-1.map 100 100 93 83 8 69 697 +174 maze-100-1.map 100 100 87 15 63 96 697 +174 maze-100-1.map 100 100 68 69 5 19 699 +174 maze-100-1.map 100 100 63 33 93 73 698 +174 maze-100-1.map 100 100 77 59 10 21 697 +174 maze-100-1.map 100 100 79 77 98 23 697 +174 maze-100-1.map 100 100 23 15 87 58 697 +174 maze-100-1.map 100 100 87 60 23 16 696 +175 maze-100-1.map 100 100 41 75 99 27 702 +175 maze-100-1.map 100 100 71 94 95 20 702 +175 maze-100-1.map 100 100 63 99 10 85 703 +175 maze-100-1.map 100 100 66 67 57 36 700 +175 maze-100-1.map 100 100 61 91 87 9 700 +175 maze-100-1.map 100 100 61 28 84 75 700 +175 maze-100-1.map 100 100 61 2 96 73 702 +175 maze-100-1.map 100 100 17 8 97 77 701 +175 maze-100-1.map 100 100 1 51 69 63 700 +175 maze-100-1.map 100 100 74 79 19 87 703 +176 maze-100-1.map 100 100 36 41 97 27 707 +176 maze-100-1.map 100 100 64 39 93 83 707 +176 maze-100-1.map 100 100 81 84 61 28 706 +176 maze-100-1.map 100 100 69 43 6 19 705 +176 maze-100-1.map 100 100 45 58 83 3 707 +176 maze-100-1.map 100 100 77 53 65 37 704 +176 maze-100-1.map 100 100 7 45 75 45 704 +176 maze-100-1.map 100 100 90 97 55 8 704 +176 maze-100-1.map 100 100 84 69 97 53 707 +176 maze-100-1.map 100 100 81 98 29 81 705 +177 maze-100-1.map 100 100 38 1 81 85 709 +177 maze-100-1.map 100 100 67 11 68 65 709 +177 maze-100-1.map 100 100 76 59 7 80 710 +177 maze-100-1.map 100 100 97 67 82 29 709 +177 maze-100-1.map 100 100 13 11 97 72 711 +177 maze-100-1.map 100 100 79 57 79 36 709 +177 maze-100-1.map 100 100 75 75 3 3 708 +177 maze-100-1.map 100 100 3 46 93 87 709 +177 maze-100-1.map 100 100 84 53 61 40 708 +177 maze-100-1.map 100 100 95 25 37 41 710 +178 maze-100-1.map 100 100 96 95 17 79 715 +178 maze-100-1.map 100 100 23 3 71 97 714 +178 maze-100-1.map 100 100 35 5 98 91 715 +178 maze-100-1.map 100 100 31 81 84 93 715 +178 maze-100-1.map 100 100 99 91 19 79 712 +178 maze-100-1.map 100 100 11 81 35 55 714 +178 maze-100-1.map 100 100 45 97 45 81 712 +178 maze-100-1.map 100 100 28 19 91 66 712 +178 maze-100-1.map 100 100 90 37 64 9 714 +178 maze-100-1.map 100 100 85 91 97 43 712 +179 maze-100-1.map 100 100 71 96 99 27 719 +179 maze-100-1.map 100 100 88 39 24 5 718 +179 maze-100-1.map 100 100 68 87 97 25 717 +179 maze-100-1.map 100 100 93 15 85 88 717 +179 maze-100-1.map 100 100 60 7 73 49 717 +179 maze-100-1.map 100 100 82 83 93 11 717 +179 maze-100-1.map 100 100 93 67 9 73 718 +179 maze-100-1.map 100 100 96 1 27 41 719 +179 maze-100-1.map 100 100 23 97 58 83 719 +179 maze-100-1.map 100 100 39 69 6 1 719 +180 maze-100-1.map 100 100 75 4 73 67 723 +180 maze-100-1.map 100 100 19 77 95 90 723 +180 maze-100-1.map 100 100 16 11 89 55 721 +180 maze-100-1.map 100 100 13 2 37 67 721 +180 maze-100-1.map 100 100 91 81 57 27 720 +180 maze-100-1.map 100 100 61 90 8 93 722 +180 maze-100-1.map 100 100 87 61 71 1 720 +180 maze-100-1.map 100 100 98 85 78 11 722 +180 maze-100-1.map 100 100 97 65 91 22 723 +180 maze-100-1.map 100 100 88 21 96 95 720 +181 maze-100-1.map 100 100 74 83 31 83 727 +181 maze-100-1.map 100 100 83 76 93 48 726 +181 maze-100-1.map 100 100 20 91 37 57 725 +181 maze-100-1.map 100 100 99 7 79 85 726 +181 maze-100-1.map 100 100 66 99 89 3 725 +181 maze-100-1.map 100 100 97 10 93 75 727 +181 maze-100-1.map 100 100 72 39 87 37 725 +181 maze-100-1.map 100 100 97 21 80 63 725 +181 maze-100-1.map 100 100 95 73 27 23 726 +181 maze-100-1.map 100 100 95 44 93 76 726 +182 maze-100-1.map 100 100 71 7 93 91 730 +182 maze-100-1.map 100 100 39 69 2 17 731 +182 maze-100-1.map 100 100 81 98 5 1 729 +182 maze-100-1.map 100 100 87 3 34 57 729 +182 maze-100-1.map 100 100 68 93 99 50 730 +182 maze-100-1.map 100 100 15 17 91 87 730 +182 maze-100-1.map 100 100 48 93 11 87 729 +182 maze-100-1.map 100 100 21 13 78 47 729 +182 maze-100-1.map 100 100 67 45 56 31 731 +182 maze-100-1.map 100 100 83 72 1 15 729 +183 maze-100-1.map 100 100 32 11 97 67 733 +183 maze-100-1.map 100 100 77 75 3 13 732 +183 maze-100-1.map 100 100 85 71 92 3 735 +183 maze-100-1.map 100 100 83 96 1 9 735 +183 maze-100-1.map 100 100 67 75 59 27 732 +183 maze-100-1.map 100 100 62 23 77 43 735 +183 maze-100-1.map 100 100 43 80 56 71 732 +183 maze-100-1.map 100 100 16 19 71 69 733 +183 maze-100-1.map 100 100 22 7 91 34 732 +183 maze-100-1.map 100 100 1 24 41 67 733 +184 maze-100-1.map 100 100 63 88 18 93 736 +184 maze-100-1.map 100 100 91 79 13 5 736 +184 maze-100-1.map 100 100 36 5 85 61 739 +184 maze-100-1.map 100 100 85 45 81 70 737 +184 maze-100-1.map 100 100 60 13 92 93 738 +184 maze-100-1.map 100 100 59 17 67 75 738 +184 maze-100-1.map 100 100 17 91 44 99 739 +184 maze-100-1.map 100 100 87 6 29 54 736 +184 maze-100-1.map 100 100 72 67 25 16 736 +184 maze-100-1.map 100 100 49 80 34 99 738 +185 maze-100-1.map 100 100 78 25 78 59 742 +185 maze-100-1.map 100 100 27 23 97 89 740 +185 maze-100-1.map 100 100 90 99 95 35 743 +185 maze-100-1.map 100 100 28 45 16 87 742 +185 maze-100-1.map 100 100 15 97 35 59 742 +185 maze-100-1.map 100 100 71 15 69 49 740 +185 maze-100-1.map 100 100 88 43 85 79 741 +185 maze-100-1.map 100 100 45 91 22 95 741 +185 maze-100-1.map 100 100 19 77 99 81 740 +185 maze-100-1.map 100 100 66 9 73 43 741 +186 maze-100-1.map 100 100 37 43 35 79 746 +186 maze-100-1.map 100 100 23 16 75 43 747 +186 maze-100-1.map 100 100 87 81 25 12 745 +186 maze-100-1.map 100 100 31 6 77 44 746 +186 maze-100-1.map 100 100 18 83 87 66 744 +186 maze-100-1.map 100 100 28 7 64 71 744 +186 maze-100-1.map 100 100 35 44 35 86 746 +186 maze-100-1.map 100 100 3 76 68 69 744 +186 maze-100-1.map 100 100 34 67 39 77 745 +186 maze-100-1.map 100 100 36 71 34 51 746 +187 maze-100-1.map 100 100 80 39 21 77 751 +187 maze-100-1.map 100 100 75 44 71 7 749 +187 maze-100-1.map 100 100 39 9 83 44 749 +187 maze-100-1.map 100 100 29 59 14 99 749 +187 maze-100-1.map 100 100 87 35 21 79 750 +187 maze-100-1.map 100 100 75 63 79 13 750 +187 maze-100-1.map 100 100 93 81 74 15 749 +187 maze-100-1.map 100 100 88 99 98 39 748 +187 maze-100-1.map 100 100 96 67 27 77 751 +187 maze-100-1.map 100 100 25 15 65 64 751 +188 maze-100-1.map 100 100 75 49 13 7 752 +188 maze-100-1.map 100 100 69 74 9 89 755 +188 maze-100-1.map 100 100 78 97 15 83 753 +188 maze-100-1.map 100 100 86 61 75 23 755 +188 maze-100-1.map 100 100 80 55 30 17 752 +188 maze-100-1.map 100 100 9 83 69 91 752 +188 maze-100-1.map 100 100 4 13 35 62 752 +188 maze-100-1.map 100 100 72 33 99 66 754 +188 maze-100-1.map 100 100 14 1 29 46 754 +188 maze-100-1.map 100 100 44 73 9 86 752 +189 maze-100-1.map 100 100 73 46 23 7 757 +189 maze-100-1.map 100 100 8 73 76 63 756 +189 maze-100-1.map 100 100 81 71 41 82 757 +189 maze-100-1.map 100 100 35 55 1 99 758 +189 maze-100-1.map 100 100 99 15 82 47 759 +189 maze-100-1.map 100 100 93 78 27 87 757 +189 maze-100-1.map 100 100 1 99 69 84 759 +189 maze-100-1.map 100 100 80 17 71 60 758 +189 maze-100-1.map 100 100 41 6 98 87 756 +189 maze-100-1.map 100 100 29 45 15 83 756 +190 maze-100-1.map 100 100 99 96 61 27 763 +190 maze-100-1.map 100 100 7 13 64 69 761 +190 maze-100-1.map 100 100 99 74 87 31 761 +190 maze-100-1.map 100 100 94 65 64 27 760 +190 maze-100-1.map 100 100 93 7 83 84 763 +190 maze-100-1.map 100 100 29 23 75 63 762 +190 maze-100-1.map 100 100 91 36 7 12 760 +190 maze-100-1.map 100 100 95 95 95 19 760 +190 maze-100-1.map 100 100 91 96 10 79 760 +190 maze-100-1.map 100 100 13 5 89 94 761 +191 maze-100-1.map 100 100 53 97 4 99 765 +191 maze-100-1.map 100 100 28 41 10 91 764 +191 maze-100-1.map 100 100 35 69 5 89 766 +191 maze-100-1.map 100 100 28 77 93 71 765 +191 maze-100-1.map 100 100 87 74 87 13 765 +191 maze-100-1.map 100 100 43 9 95 79 766 +191 maze-100-1.map 100 100 3 14 79 71 765 +191 maze-100-1.map 100 100 97 89 73 32 767 +191 maze-100-1.map 100 100 75 70 89 18 764 +191 maze-100-1.map 100 100 41 83 94 77 767 +192 maze-100-1.map 100 100 80 79 39 84 770 +192 maze-100-1.map 100 100 88 3 79 81 771 +192 maze-100-1.map 100 100 13 85 81 69 768 +192 maze-100-1.map 100 100 88 73 4 13 770 +192 maze-100-1.map 100 100 36 15 85 35 771 +192 maze-100-1.map 100 100 21 97 73 91 770 +192 maze-100-1.map 100 100 61 95 5 94 769 +192 maze-100-1.map 100 100 86 41 43 6 770 +192 maze-100-1.map 100 100 87 17 72 97 769 +192 maze-100-1.map 100 100 68 33 84 41 768 +193 maze-100-1.map 100 100 78 67 37 78 774 +193 maze-100-1.map 100 100 34 13 91 35 773 +193 maze-100-1.map 100 100 85 93 11 93 774 +193 maze-100-1.map 100 100 25 21 65 64 773 +193 maze-100-1.map 100 100 63 67 15 73 774 +193 maze-100-1.map 100 100 97 23 92 83 773 +193 maze-100-1.map 100 100 3 99 28 55 775 +193 maze-100-1.map 100 100 35 14 87 81 773 +193 maze-100-1.map 100 100 85 15 67 73 772 +193 maze-100-1.map 100 100 89 19 86 91 773 +194 maze-100-1.map 100 100 43 57 23 97 776 +194 maze-100-1.map 100 100 43 6 96 79 776 +194 maze-100-1.map 100 100 83 41 95 36 779 +194 maze-100-1.map 100 100 46 95 33 99 779 +194 maze-100-1.map 100 100 15 99 79 99 776 +194 maze-100-1.map 100 100 7 99 73 70 779 +194 maze-100-1.map 100 100 18 5 94 95 778 +194 maze-100-1.map 100 100 99 75 37 1 776 +194 maze-100-1.map 100 100 71 97 38 73 779 +194 maze-100-1.map 100 100 8 93 80 93 776 +195 maze-100-1.map 100 100 35 75 80 85 783 +195 maze-100-1.map 100 100 95 11 99 70 781 +195 maze-100-1.map 100 100 91 62 39 84 780 +195 maze-100-1.map 100 100 73 43 3 7 782 +195 maze-100-1.map 100 100 39 71 2 89 783 +195 maze-100-1.map 100 100 3 85 77 75 780 +195 maze-100-1.map 100 100 80 67 5 26 780 +195 maze-100-1.map 100 100 75 59 22 83 783 +195 maze-100-1.map 100 100 69 33 67 65 782 +195 maze-100-1.map 100 100 92 57 3 1 781 +196 maze-100-1.map 100 100 73 29 73 64 785 +196 maze-100-1.map 100 100 64 83 27 97 785 +196 maze-100-1.map 100 100 96 55 31 93 785 +196 maze-100-1.map 100 100 27 83 93 71 786 +196 maze-100-1.map 100 100 95 17 87 60 787 +196 maze-100-1.map 100 100 25 98 73 99 785 +196 maze-100-1.map 100 100 93 14 77 55 787 +196 maze-100-1.map 100 100 13 73 63 75 784 +196 maze-100-1.map 100 100 75 62 69 30 786 +196 maze-100-1.map 100 100 19 83 89 88 787 +197 maze-100-1.map 100 100 21 87 87 99 790 +197 maze-100-1.map 100 100 99 38 85 42 790 +197 maze-100-1.map 100 100 39 1 77 56 791 +197 maze-100-1.map 100 100 98 93 92 43 788 +197 maze-100-1.map 100 100 91 31 67 67 788 +197 maze-100-1.map 100 100 95 63 93 38 791 +197 maze-100-1.map 100 100 89 43 89 51 788 +197 maze-100-1.map 100 100 93 98 92 1 788 +197 maze-100-1.map 100 100 97 82 99 37 789 +197 maze-100-1.map 100 100 34 97 47 87 791 +198 maze-100-1.map 100 100 91 62 5 17 793 +198 maze-100-1.map 100 100 88 35 63 33 795 +198 maze-100-1.map 100 100 89 9 94 59 795 +198 maze-100-1.map 100 100 37 97 35 57 794 +198 maze-100-1.map 100 100 99 41 77 56 795 +198 maze-100-1.map 100 100 85 69 13 93 792 +198 maze-100-1.map 100 100 99 86 30 79 792 +198 maze-100-1.map 100 100 85 72 45 76 792 +198 maze-100-1.map 100 100 89 88 83 11 795 +198 maze-100-1.map 100 100 97 58 29 85 793 +199 maze-100-1.map 100 100 17 97 71 95 796 +199 maze-100-1.map 100 100 85 42 24 1 798 +199 maze-100-1.map 100 100 84 41 99 32 798 +199 maze-100-1.map 100 100 98 41 82 61 798 +199 maze-100-1.map 100 100 86 39 25 83 799 +199 maze-100-1.map 100 100 99 15 89 85 796 +199 maze-100-1.map 100 100 69 40 32 21 796 +199 maze-100-1.map 100 100 76 59 96 47 796 +199 maze-100-1.map 100 100 32 71 94 77 796 +199 maze-100-1.map 100 100 26 87 91 52 798 +200 maze-100-1.map 100 100 87 89 9 81 802 +200 maze-100-1.map 100 100 1 94 78 93 800 +200 maze-100-1.map 100 100 87 60 20 1 802 +200 maze-100-1.map 100 100 20 73 73 49 801 +200 maze-100-1.map 100 100 29 90 97 99 803 +200 maze-100-1.map 100 100 22 75 93 90 802 +200 maze-100-1.map 100 100 3 87 27 42 803 +200 maze-100-1.map 100 100 86 45 81 51 801 +200 maze-100-1.map 100 100 93 6 93 97 801 +200 maze-100-1.map 100 100 31 99 37 69 800 +201 maze-100-1.map 100 100 88 95 81 9 807 +201 maze-100-1.map 100 100 65 92 1 98 806 +201 maze-100-1.map 100 100 45 83 79 69 804 +201 maze-100-1.map 100 100 90 85 36 3 804 +201 maze-100-1.map 100 100 85 99 17 83 804 +201 maze-100-1.map 100 100 73 72 22 89 806 +201 maze-100-1.map 100 100 95 11 89 57 804 +201 maze-100-1.map 100 100 87 69 1 89 806 +201 maze-100-1.map 100 100 98 29 86 41 806 +201 maze-100-1.map 100 100 99 79 31 79 804 +202 maze-100-1.map 100 100 41 7 69 46 809 +202 maze-100-1.map 100 100 98 69 30 91 810 +202 maze-100-1.map 100 100 29 83 95 64 811 +202 maze-100-1.map 100 100 78 71 13 93 811 +202 maze-100-1.map 100 100 81 42 92 41 810 +202 maze-100-1.map 100 100 85 27 71 44 809 +202 maze-100-1.map 100 100 70 97 4 87 810 +202 maze-100-1.map 100 100 27 77 68 71 811 +202 maze-100-1.map 100 100 65 29 89 59 810 +202 maze-100-1.map 100 100 27 98 77 92 810 +203 maze-100-1.map 100 100 93 16 79 42 812 +203 maze-100-1.map 100 100 85 38 99 47 815 +203 maze-100-1.map 100 100 32 89 86 41 814 +203 maze-100-1.map 100 100 92 67 94 5 812 +203 maze-100-1.map 100 100 99 92 16 87 814 +203 maze-100-1.map 100 100 79 57 26 89 813 +203 maze-100-1.map 100 100 11 99 89 87 814 +203 maze-100-1.map 100 100 79 59 34 91 815 +203 maze-100-1.map 100 100 97 67 3 9 812 +203 maze-100-1.map 100 100 99 81 97 51 812 +204 maze-100-1.map 100 100 97 5 71 67 816 +204 maze-100-1.map 100 100 79 41 99 38 819 +204 maze-100-1.map 100 100 92 47 83 39 819 +204 maze-100-1.map 100 100 33 81 68 65 817 +204 maze-100-1.map 100 100 27 97 43 73 816 +204 maze-100-1.map 100 100 39 3 69 49 816 +204 maze-100-1.map 100 100 20 85 93 63 817 +204 maze-100-1.map 100 100 27 97 33 44 817 +204 maze-100-1.map 100 100 87 37 20 5 819 +204 maze-100-1.map 100 100 68 71 95 35 817 +205 maze-100-1.map 100 100 3 10 95 99 823 +205 maze-100-1.map 100 100 91 95 94 15 823 +205 maze-100-1.map 100 100 26 99 66 91 822 +205 maze-100-1.map 100 100 80 85 19 93 821 +205 maze-100-1.map 100 100 31 99 33 45 820 +205 maze-100-1.map 100 100 91 95 93 14 821 +205 maze-100-1.map 100 100 74 43 73 31 821 +205 maze-100-1.map 100 100 15 85 79 51 822 +205 maze-100-1.map 100 100 31 92 87 58 822 +205 maze-100-1.map 100 100 3 82 77 68 822 +206 maze-100-1.map 100 100 91 88 67 25 825 +206 maze-100-1.map 100 100 71 41 71 31 826 +206 maze-100-1.map 100 100 62 27 91 97 825 +206 maze-100-1.map 100 100 87 84 97 29 825 +206 maze-100-1.map 100 100 90 37 94 49 824 +206 maze-100-1.map 100 100 94 55 11 83 825 +206 maze-100-1.map 100 100 20 1 65 71 827 +206 maze-100-1.map 100 100 9 85 99 63 824 +206 maze-100-1.map 100 100 83 53 93 51 824 +206 maze-100-1.map 100 100 71 62 32 91 824 +207 maze-100-1.map 100 100 63 27 69 45 828 +207 maze-100-1.map 100 100 31 83 99 87 828 +207 maze-100-1.map 100 100 89 54 86 45 830 +207 maze-100-1.map 100 100 98 15 68 41 828 +207 maze-100-1.map 100 100 5 94 83 83 831 +207 maze-100-1.map 100 100 27 44 31 98 828 +207 maze-100-1.map 100 100 76 49 27 1 829 +207 maze-100-1.map 100 100 15 87 99 88 829 +207 maze-100-1.map 100 100 88 55 85 47 831 +207 maze-100-1.map 100 100 99 88 15 86 830 +208 maze-100-1.map 100 100 3 84 94 77 832 +208 maze-100-1.map 100 100 97 27 76 61 833 +208 maze-100-1.map 100 100 33 75 99 62 833 +208 maze-100-1.map 100 100 79 53 84 49 835 +208 maze-100-1.map 100 100 70 43 33 1 833 +208 maze-100-1.map 100 100 67 97 34 95 833 +208 maze-100-1.map 100 100 91 35 33 86 833 +208 maze-100-1.map 100 100 75 61 91 43 834 +208 maze-100-1.map 100 100 95 66 89 19 833 +208 maze-100-1.map 100 100 79 51 14 83 833 +209 maze-100-1.map 100 100 77 52 21 87 839 +209 maze-100-1.map 100 100 97 93 87 9 838 +209 maze-100-1.map 100 100 97 3 79 44 837 +209 maze-100-1.map 100 100 13 84 97 71 837 +209 maze-100-1.map 100 100 77 51 1 6 839 +209 maze-100-1.map 100 100 41 79 96 85 839 +209 maze-100-1.map 100 100 35 95 78 71 839 +209 maze-100-1.map 100 100 66 77 22 3 838 +209 maze-100-1.map 100 100 85 81 1 81 836 +209 maze-100-1.map 100 100 87 9 89 51 836 +210 maze-100-1.map 100 100 88 99 45 77 841 +210 maze-100-1.map 100 100 31 73 95 66 841 +210 maze-100-1.map 100 100 95 87 37 83 842 +210 maze-100-1.map 100 100 99 49 79 47 842 +210 maze-100-1.map 100 100 97 74 37 76 842 +210 maze-100-1.map 100 100 21 3 69 48 843 +210 maze-100-1.map 100 100 95 88 37 77 843 +210 maze-100-1.map 100 100 95 45 68 69 843 +210 maze-100-1.map 100 100 93 76 25 93 841 +210 maze-100-1.map 100 100 65 75 99 3 842 +211 maze-100-1.map 100 100 91 36 35 91 847 +211 maze-100-1.map 100 100 1 2 90 81 846 +211 maze-100-1.map 100 100 16 5 63 77 847 +211 maze-100-1.map 100 100 87 36 87 47 847 +211 maze-100-1.map 100 100 3 89 89 95 844 +211 maze-100-1.map 100 100 99 63 82 1 845 +211 maze-100-1.map 100 100 81 59 17 3 844 +211 maze-100-1.map 100 100 83 41 85 12 845 +211 maze-100-1.map 100 100 91 59 3 92 845 +211 maze-100-1.map 100 100 21 96 89 94 844 +212 maze-100-1.map 100 100 67 73 91 41 848 +212 maze-100-1.map 100 100 88 5 95 73 849 +212 maze-100-1.map 100 100 99 77 5 25 850 +212 maze-100-1.map 100 100 11 88 80 63 850 +212 maze-100-1.map 100 100 9 3 82 39 851 +212 maze-100-1.map 100 100 92 47 69 45 851 +212 maze-100-1.map 100 100 93 63 8 99 849 +212 maze-100-1.map 100 100 90 83 26 85 848 +212 maze-100-1.map 100 100 75 57 39 81 848 +212 maze-100-1.map 100 100 68 77 91 41 849 +213 maze-100-1.map 100 100 94 1 75 48 852 +213 maze-100-1.map 100 100 74 59 89 13 853 +213 maze-100-1.map 100 100 67 67 8 3 853 +213 maze-100-1.map 100 100 83 7 96 75 855 +213 maze-100-1.map 100 100 77 45 27 85 854 +213 maze-100-1.map 100 100 9 87 97 85 854 +213 maze-100-1.map 100 100 29 88 63 77 855 +213 maze-100-1.map 100 100 91 57 3 83 854 +213 maze-100-1.map 100 100 99 55 79 49 854 +213 maze-100-1.map 100 100 97 26 71 47 855 +214 maze-100-1.map 100 100 9 6 91 97 859 +214 maze-100-1.map 100 100 82 67 37 97 859 +214 maze-100-1.map 100 100 82 57 37 85 859 +214 maze-100-1.map 100 100 18 87 65 65 857 +214 maze-100-1.map 100 100 94 3 78 47 856 +214 maze-100-1.map 100 100 17 85 73 63 858 +214 maze-100-1.map 100 100 80 55 35 77 857 +214 maze-100-1.map 100 100 89 11 92 83 857 +214 maze-100-1.map 100 100 86 61 11 85 857 +214 maze-100-1.map 100 100 67 77 90 1 857 +215 maze-100-1.map 100 100 19 84 84 53 860 +215 maze-100-1.map 100 100 79 44 31 84 862 +215 maze-100-1.map 100 100 10 99 79 55 861 +215 maze-100-1.map 100 100 87 41 11 82 863 +215 maze-100-1.map 100 100 99 63 4 89 861 +215 maze-100-1.map 100 100 97 79 89 15 860 +215 maze-100-1.map 100 100 35 82 89 54 862 +215 maze-100-1.map 100 100 9 87 85 56 863 +215 maze-100-1.map 100 100 35 89 67 77 860 +215 maze-100-1.map 100 100 32 71 81 41 863 +216 maze-100-1.map 100 100 81 45 1 12 867 +216 maze-100-1.map 100 100 97 84 32 71 864 +216 maze-100-1.map 100 100 19 3 75 67 864 +216 maze-100-1.map 100 100 80 39 1 24 866 +216 maze-100-1.map 100 100 97 83 31 75 866 +216 maze-100-1.map 100 100 81 6 95 98 866 +216 maze-100-1.map 100 100 75 61 88 11 865 +216 maze-100-1.map 100 100 69 41 33 86 865 +216 maze-100-1.map 100 100 86 53 14 83 864 +216 maze-100-1.map 100 100 83 57 1 17 866 +217 maze-100-1.map 100 100 81 45 1 15 870 +217 maze-100-1.map 100 100 77 61 1 20 871 +217 maze-100-1.map 100 100 91 93 2 9 871 +217 maze-100-1.map 100 100 74 65 1 27 869 +217 maze-100-1.map 100 100 28 91 70 43 868 +217 maze-100-1.map 100 100 69 47 89 49 870 +217 maze-100-1.map 100 100 86 9 78 53 870 +217 maze-100-1.map 100 100 67 71 16 87 871 +217 maze-100-1.map 100 100 43 79 95 72 869 +217 maze-100-1.map 100 100 95 53 6 87 869 +218 maze-100-1.map 100 100 86 7 79 53 875 +218 maze-100-1.map 100 100 96 79 31 74 874 +218 maze-100-1.map 100 100 76 47 1 17 875 +218 maze-100-1.map 100 100 3 13 89 35 872 +218 maze-100-1.map 100 100 7 95 99 70 873 +218 maze-100-1.map 100 100 71 66 31 73 873 +218 maze-100-1.map 100 100 65 73 3 17 874 +218 maze-100-1.map 100 100 13 2 93 87 873 +218 maze-100-1.map 100 100 93 63 19 91 874 +218 maze-100-1.map 100 100 14 83 65 65 873 +219 maze-100-1.map 100 100 89 37 84 9 879 +219 maze-100-1.map 100 100 9 95 97 84 879 +219 maze-100-1.map 100 100 79 55 19 99 876 +219 maze-100-1.map 100 100 87 84 37 77 877 +219 maze-100-1.map 100 100 91 17 77 42 879 +219 maze-100-1.map 100 100 88 53 33 75 879 +219 maze-100-1.map 100 100 70 41 85 46 878 +219 maze-100-1.map 100 100 21 85 63 75 876 +219 maze-100-1.map 100 100 36 75 87 83 879 +219 maze-100-1.map 100 100 69 67 89 5 878 +220 maze-100-1.map 100 100 87 51 23 89 882 +220 maze-100-1.map 100 100 67 76 1 22 882 +220 maze-100-1.map 100 100 3 90 95 75 883 +220 maze-100-1.map 100 100 17 89 91 51 880 +220 maze-100-1.map 100 100 28 73 93 82 882 +220 maze-100-1.map 100 100 77 44 36 75 882 +220 maze-100-1.map 100 100 11 81 77 40 881 +220 maze-100-1.map 100 100 91 9 95 93 880 +220 maze-100-1.map 100 100 33 73 91 82 881 +220 maze-100-1.map 100 100 99 80 9 97 883 +221 maze-100-1.map 100 100 87 99 25 98 887 +221 maze-100-1.map 100 100 72 61 9 94 886 +221 maze-100-1.map 100 100 68 63 10 85 884 +221 maze-100-1.map 100 100 3 82 93 67 887 +221 maze-100-1.map 100 100 84 51 1 99 885 +221 maze-100-1.map 100 100 23 89 95 70 885 +221 maze-100-1.map 100 100 25 91 96 67 887 +221 maze-100-1.map 100 100 69 65 81 3 886 +221 maze-100-1.map 100 100 79 49 85 13 886 +221 maze-100-1.map 100 100 71 45 11 3 886 +222 maze-100-1.map 100 100 67 66 14 99 890 +222 maze-100-1.map 100 100 45 80 87 39 891 +222 maze-100-1.map 100 100 75 41 31 86 889 +222 maze-100-1.map 100 100 11 96 91 37 891 +222 maze-100-1.map 100 100 71 44 40 79 890 +222 maze-100-1.map 100 100 35 71 77 45 888 +222 maze-100-1.map 100 100 39 73 90 81 889 +222 maze-100-1.map 100 100 41 81 73 43 890 +222 maze-100-1.map 100 100 77 43 34 77 891 +222 maze-100-1.map 100 100 15 95 75 55 888 +223 maze-100-1.map 100 100 86 39 17 97 893 +223 maze-100-1.map 100 100 25 95 95 65 892 +223 maze-100-1.map 100 100 11 99 82 57 895 +223 maze-100-1.map 100 100 77 42 89 3 895 +223 maze-100-1.map 100 100 85 35 39 77 892 +223 maze-100-1.map 100 100 13 89 82 51 893 +223 maze-100-1.map 100 100 3 82 99 77 895 +223 maze-100-1.map 100 100 81 38 43 77 893 +223 maze-100-1.map 100 100 91 53 27 97 892 +223 maze-100-1.map 100 100 71 62 19 97 893 +224 maze-100-1.map 100 100 88 99 35 97 899 +224 maze-100-1.map 100 100 9 89 67 71 896 +224 maze-100-1.map 100 100 87 41 17 95 896 +224 maze-100-1.map 100 100 74 57 21 97 897 +224 maze-100-1.map 100 100 67 67 16 97 899 +224 maze-100-1.map 100 100 91 37 15 99 898 +224 maze-100-1.map 100 100 77 47 29 74 899 +224 maze-100-1.map 100 100 28 99 89 51 899 +224 maze-100-1.map 100 100 74 63 45 77 899 +224 maze-100-1.map 100 100 7 98 75 63 897 +225 maze-100-1.map 100 100 73 45 10 85 903 +225 maze-100-1.map 100 100 22 95 77 55 901 +225 maze-100-1.map 100 100 92 83 43 82 902 +225 maze-100-1.map 100 100 90 83 8 95 900 +225 maze-100-1.map 100 100 1 94 95 97 901 +225 maze-100-1.map 100 100 39 76 64 71 900 +225 maze-100-1.map 100 100 65 64 7 97 903 +225 maze-100-1.map 100 100 37 73 67 72 903 +225 maze-100-1.map 100 100 27 93 92 71 903 +225 maze-100-1.map 100 100 7 99 81 57 900 +226 maze-100-1.map 100 100 69 39 1 20 905 +226 maze-100-1.map 100 100 3 25 91 97 904 +226 maze-100-1.map 100 100 19 99 95 83 904 +226 maze-100-1.map 100 100 77 55 3 93 904 +226 maze-100-1.map 100 100 80 51 31 95 907 +226 maze-100-1.map 100 100 77 54 19 93 905 +226 maze-100-1.map 100 100 13 97 93 88 907 +226 maze-100-1.map 100 100 83 1 79 42 907 +226 maze-100-1.map 100 100 99 69 13 91 904 +226 maze-100-1.map 100 100 11 97 67 77 904 +227 maze-100-1.map 100 100 74 65 23 95 911 +227 maze-100-1.map 100 100 69 77 13 98 911 +227 maze-100-1.map 100 100 35 99 99 61 910 +227 maze-100-1.map 100 100 35 95 95 72 909 +227 maze-100-1.map 100 100 21 93 85 38 911 +227 maze-100-1.map 100 100 93 67 29 99 908 +227 maze-100-1.map 100 100 82 61 3 97 909 +227 maze-100-1.map 100 100 77 42 19 99 909 +227 maze-100-1.map 100 100 7 91 63 69 910 +227 maze-100-1.map 100 100 93 68 26 99 908 +228 maze-100-1.map 100 100 98 79 23 91 913 +228 maze-100-1.map 100 100 67 73 44 77 913 +228 maze-100-1.map 100 100 2 85 89 56 914 +228 maze-100-1.map 100 100 67 77 86 1 915 +228 maze-100-1.map 100 100 99 98 23 98 912 +228 maze-100-1.map 100 100 90 97 11 99 915 +228 maze-100-1.map 100 100 31 98 79 59 915 +228 maze-100-1.map 100 100 99 88 29 93 913 +228 maze-100-1.map 100 100 21 89 79 53 914 +228 maze-100-1.map 100 100 77 54 22 89 912 +229 maze-100-1.map 100 100 9 99 68 69 919 +229 maze-100-1.map 100 100 98 71 22 99 916 +229 maze-100-1.map 100 100 65 74 19 98 918 +229 maze-100-1.map 100 100 3 84 79 39 919 +229 maze-100-1.map 100 100 20 93 83 54 918 +229 maze-100-1.map 100 100 17 91 75 57 916 +229 maze-100-1.map 100 100 8 93 69 60 918 +229 maze-100-1.map 100 100 13 90 89 40 918 +229 maze-100-1.map 100 100 5 89 91 39 916 +229 maze-100-1.map 100 100 28 97 83 41 919 +230 maze-100-1.map 100 100 4 89 78 47 922 +230 maze-100-1.map 100 100 75 57 29 97 922 +230 maze-100-1.map 100 100 18 99 75 48 920 +230 maze-100-1.map 100 100 17 97 93 93 920 +230 maze-100-1.map 100 100 29 96 85 57 923 +230 maze-100-1.map 100 100 73 63 6 87 921 +230 maze-100-1.map 100 100 74 57 29 93 921 +230 maze-100-1.map 100 100 92 67 33 97 921 +230 maze-100-1.map 100 100 64 75 5 89 923 +230 maze-100-1.map 100 100 81 57 19 93 922 +231 maze-100-1.map 100 100 75 65 1 92 927 +231 maze-100-1.map 100 100 83 36 7 87 925 +231 maze-100-1.map 100 100 85 43 27 97 924 +231 maze-100-1.map 100 100 18 95 69 59 927 +231 maze-100-1.map 100 100 87 83 18 89 927 +231 maze-100-1.map 100 100 81 43 21 99 924 +231 maze-100-1.map 100 100 25 97 97 83 926 +231 maze-100-1.map 100 100 5 97 71 44 927 +231 maze-100-1.map 100 100 93 69 33 97 924 +231 maze-100-1.map 100 100 1 83 73 63 924 +232 maze-100-1.map 100 100 1 93 91 82 929 +232 maze-100-1.map 100 100 79 39 17 91 930 +232 maze-100-1.map 100 100 35 95 71 61 930 +232 maze-100-1.map 100 100 79 42 14 93 928 +232 maze-100-1.map 100 100 13 96 75 45 931 +232 maze-100-1.map 100 100 89 59 27 94 929 +232 maze-100-1.map 100 100 23 89 65 64 931 +232 maze-100-1.map 100 100 91 37 23 90 929 +232 maze-100-1.map 100 100 68 77 20 95 928 +232 maze-100-1.map 100 100 69 41 39 77 930 +233 maze-100-1.map 100 100 25 95 75 65 932 +233 maze-100-1.map 100 100 89 35 13 91 932 +233 maze-100-1.map 100 100 83 53 26 95 935 +233 maze-100-1.map 100 100 93 93 3 91 932 +233 maze-100-1.map 100 100 67 63 5 99 934 +233 maze-100-1.map 100 100 79 49 22 95 933 +233 maze-100-1.map 100 100 2 89 91 93 933 +233 maze-100-1.map 100 100 1 93 82 57 935 +233 maze-100-1.map 100 100 15 91 88 81 933 +233 maze-100-1.map 100 100 75 41 44 77 933 +234 maze-100-1.map 100 100 7 87 67 73 938 +234 maze-100-1.map 100 100 35 97 73 58 937 +234 maze-100-1.map 100 100 29 96 83 35 939 +234 maze-100-1.map 100 100 36 93 84 61 936 +234 maze-100-1.map 100 100 67 69 6 89 937 +234 maze-100-1.map 100 100 73 47 7 90 939 +234 maze-100-1.map 100 100 90 81 29 97 939 +234 maze-100-1.map 100 100 23 89 69 63 936 +234 maze-100-1.map 100 100 77 49 4 87 937 +234 maze-100-1.map 100 100 72 61 37 96 938 +235 maze-100-1.map 100 100 89 59 23 99 942 +235 maze-100-1.map 100 100 79 42 25 92 940 +235 maze-100-1.map 100 100 94 83 25 98 942 +235 maze-100-1.map 100 100 19 89 77 49 942 +235 maze-100-1.map 100 100 67 72 2 83 940 +235 maze-100-1.map 100 100 86 35 26 99 942 +235 maze-100-1.map 100 100 11 88 91 33 943 +235 maze-100-1.map 100 100 91 37 30 97 943 +235 maze-100-1.map 100 100 79 46 26 93 940 +235 maze-100-1.map 100 100 3 87 69 47 942 +236 maze-100-1.map 100 100 1 94 67 77 945 +236 maze-100-1.map 100 100 94 93 15 89 947 +236 maze-100-1.map 100 100 19 98 70 41 946 +236 maze-100-1.map 100 100 16 89 76 49 944 +236 maze-100-1.map 100 100 78 47 11 88 946 +236 maze-100-1.map 100 100 67 42 5 89 945 +236 maze-100-1.map 100 100 69 69 2 85 947 +236 maze-100-1.map 100 100 31 98 63 65 945 +236 maze-100-1.map 100 100 90 37 26 99 946 +236 maze-100-1.map 100 100 34 97 77 55 945 +237 maze-100-1.map 100 100 15 89 69 71 948 +237 maze-100-1.map 100 100 95 93 15 89 948 +237 maze-100-1.map 100 100 13 88 68 77 948 +237 maze-100-1.map 100 100 34 97 89 55 949 +237 maze-100-1.map 100 100 93 92 26 93 948 +237 maze-100-1.map 100 100 81 45 31 98 951 +237 maze-100-1.map 100 100 33 99 78 53 951 +237 maze-100-1.map 100 100 19 89 90 97 949 +237 maze-100-1.map 100 100 21 93 68 43 951 +237 maze-100-1.map 100 100 71 49 1 95 948 +238 maze-100-1.map 100 100 72 45 3 81 953 +238 maze-100-1.map 100 100 76 47 27 97 953 +238 maze-100-1.map 100 100 68 77 29 97 955 +238 maze-100-1.map 100 100 35 93 63 69 952 +238 maze-100-1.map 100 100 23 89 70 43 955 +238 maze-100-1.map 100 100 69 43 5 93 954 +238 maze-100-1.map 100 100 23 98 64 65 952 +238 maze-100-1.map 100 100 11 87 79 49 954 +238 maze-100-1.map 100 100 63 68 37 95 955 +238 maze-100-1.map 100 100 34 95 78 45 952 +239 maze-100-1.map 100 100 80 45 35 93 957 +239 maze-100-1.map 100 100 66 75 32 95 956 +239 maze-100-1.map 100 100 13 87 70 69 957 +239 maze-100-1.map 100 100 75 45 3 99 958 +239 maze-100-1.map 100 100 29 99 65 75 956 +239 maze-100-1.map 100 100 71 41 20 93 957 +239 maze-100-1.map 100 100 11 87 69 49 956 +239 maze-100-1.map 100 100 88 85 37 94 956 +239 maze-100-1.map 100 100 3 81 75 44 959 +239 maze-100-1.map 100 100 93 86 23 97 959 +240 maze-100-1.map 100 100 66 77 26 99 960 +240 maze-100-1.map 100 100 73 47 13 89 962 +240 maze-100-1.map 100 100 68 69 11 88 962 +240 maze-100-1.map 100 100 73 45 17 91 962 +240 maze-100-1.map 100 100 70 43 25 93 961 +240 maze-100-1.map 100 100 28 97 70 71 960 +240 maze-100-1.map 100 100 36 93 65 74 960 +240 maze-100-1.map 100 100 93 90 34 95 960 +240 maze-100-1.map 100 100 25 99 91 89 960 +240 maze-100-1.map 100 100 63 67 33 97 960 +241 maze-100-1.map 100 100 93 86 35 97 967 +241 maze-100-1.map 100 100 71 47 29 93 964 +241 maze-100-1.map 100 100 68 77 23 97 965 +241 maze-100-1.map 100 100 67 75 37 95 966 +241 maze-100-1.map 100 100 65 64 33 98 966 +241 maze-100-1.map 100 100 13 88 75 44 966 +241 maze-100-1.map 100 100 34 99 65 65 967 +241 maze-100-1.map 100 100 73 44 11 89 967 +241 maze-100-1.map 100 100 13 90 75 45 967 +241 maze-100-1.map 100 100 31 98 69 69 967 +242 maze-100-1.map 100 100 28 97 73 45 969 +242 maze-100-1.map 100 100 93 90 37 96 968 +242 maze-100-1.map 100 100 15 90 69 40 968 +242 maze-100-1.map 100 100 69 40 1 91 971 +242 maze-100-1.map 100 100 74 49 37 95 969 +242 maze-100-1.map 100 100 23 99 71 70 969 +242 maze-100-1.map 100 100 26 93 69 39 971 +242 maze-100-1.map 100 100 64 77 37 94 970 +242 maze-100-1.map 100 100 33 99 79 43 970 +242 maze-100-1.map 100 100 69 69 31 99 968 +243 maze-100-1.map 100 100 71 43 34 95 975 +243 maze-100-1.map 100 100 93 90 33 98 974 +243 maze-100-1.map 100 100 35 99 79 41 974 +243 maze-100-1.map 100 100 35 99 93 33 972 +243 maze-100-1.map 100 100 73 47 26 99 975 +243 maze-100-1.map 100 100 75 47 33 99 974 +243 maze-100-1.map 100 100 21 99 71 47 974 +243 maze-100-1.map 100 100 35 94 89 97 973 +243 maze-100-1.map 100 100 37 95 69 49 974 +243 maze-100-1.map 100 100 35 97 64 77 975 diff --git a/JPSPlusGoalBounding/Maps/random-100-33.map b/JPSPlusGoalBounding/Maps/random-100-33.map new file mode 100644 index 0000000..bb7c66e --- /dev/null +++ b/JPSPlusGoalBounding/Maps/random-100-33.map @@ -0,0 +1,104 @@ +type octile +height 100 +width 100 +map +...@..@.@..@....@.@@.@........@TT@@@@@.@TT@TT@..@@TTTTT@....@@@..@..@@..@...@@...@....@T@.@....@T@.. +@....@@.@....@@.@.......@....@TTTT@.@..@TT@TTT@...@@T@@@...@T@.@...@@...........@.....@T@..@....@@@. +..........@.@..@..@@..@....@.@TTT@..@..@T@@@@@...@T@@.@@@...@............@.......@..@.@@....@..@@@.. +..@.@......@..@..@.@......@@@T@@@..@....@.@T@...@T@@..@@@..@..@..@.@@@@....@..........@..@@......... +...@.....@......@.........@..@@@..@@..@@...@..@@.@T@...@@.......@..@...@.@.@.@.@@@@@...@.@.@...@.@.@ +.@.....@.@@.@@.@.....@.@.@..@T@@...@...@.........@T@@.............@..@@...@T@........@...@.@@@.@.... +@.@.......@..@.@@@..@.......@T@@...@...@...@@...@.@T@..@....@..@..@.....@..@.........@..@@...@.@.... +..@...@@@.@.@..@....@.....@..@.........@@.@@@.@....@.@...@...@....@.@.@@@..@.........@@@@..@........ +..@...@....@@@.......@@@.....@...@....@@....@@.@.@...@......@@@.......@T@..@...@@.@.@.....@....@..@. +@...@.@..@@TT@@@...@...@....@@.@...@..@..@.@@..@...@@..@..@...@@@..@@@T@@.@T@.......@.@.........@.@@ +....@......@@@TT@....@..@.@@@.@@.....@@..@@..@.@....@...@@@...@.......@..@TT@@.@.@@...@....@.@@@..@T +..@@@.....@T@TT@T@..@.@........@..................@@T@@.....@....@...@@...@T@...@.@@.@...@@...@.@..@ +........@..@TTT@@.........@.@......@.@..@@.@@@.@....@@.@....@.@.@T@......@.@@.......@..@@...@....... +.......@....@T@..@......@@@@..........@@..@.@...........@........@T@..@..@..@......@............@@@@ +@...........@T@@.....@..@..@@@@.....@...........@.@...@...@.......@......@...@.@..@T@..@@..@...@..@. +.@...@.@.....@....@@....@.@...@@........@@...@@..@..@..@@@......@.@.......@.@@.@@@@@.@...@...@...... +.@.@@@...@@...@@...@@@@......@T@..@@@.@@T@@.@@.@.@.....@..@@.@..............@@.....@...@.@@........@ +..@..@.....@...@@......@@.....@..@..@...@......@@@..@.@@..@......@.@.@@.@@....@.@@...@.@..@@.@..@@.. +@...@......@...@@...@....@@@....@@@..@....@..@.@.@@@..@..@....@.@@.@.@.@....@....@.....@.@.........@ +..@@@...@@..@...@@...@.@......@@.......@....@T@......@...@.@@@@........@@..@@.@.@@..@..@..@....@.... +.@.....@@@..@..@T@@...@..@@@.@..@....@.@@.@@.@.@..@@..@......@.....@@@.@@.@..@...@........@.@..@.@.@ +.@..........@.@@@.@@....@.@..@..@.@@@....@@..@.......@.@.@....@...@T@@@.........@...@....@@....@@..@ +.....@.@....@.@T@.@..@@@........@@....@@@.@@..@..........@@.....@@.@@@@..........@.@.@@...@....@.@.@ +@.......@..@@@@@@...@@....@@@....@...@@@...@@.......@..@.......@....@@...@..@...@....@@..@.......... +@.@..@.@..@@@@T@@@@@T@.....@....@.@@@@@T@..@@@...@...@...@@.@..@......@....@...@.@.@@@...@@....@.... +....@@@@.....@TT@.@TTT@@@.@..@@@..@@T@@T@@..@...@.@@.@.@@........@@@@..@..@@......@T@@....@@.@..@@.. +@..@@.@.@@..@@@@@.@TTT@@....@.@..@T@@T@TT@@...........@....@....@@@....@@.@@@....@@@T@.@..@.@@...@@. +...@....@@@...@@@..@@T@.......@...@@T@TTT@T@@....@...@....@...@.....@...@.@..@@...@@@.....@...@....@ +@.......@T@...@....@.@.@..@.@....@..@@TTT@@..@.@.@.......@.....@@...@..@.@..........@@@@.@@.....@.@@ +...@@@@..@....@......@...@........@...@T@..............@@@..@.@@..@...@.......@..@..@@..........@..@ +@@@.@....@.......@......@..@@..@...@..@TT@...@.@@..@.@@.@..@@....@@...@.....@...@...@....@@......... +@.@....@@.@@..@@..@@@@........@...@....@T@................@.....@.@@@...@.@@.@.@@....@@.@@@.......@@ +...@@.....@..@.............@@@....@.@...@...@@.@...@.@.........@......@...@..@...@.....@TTT@@@@.@.@. +@@.....@...@...@.@..@..@@......@.@T@@...@.....@....@.@...@.....@.....@..@....@.@.@.@@.@.@@@.@@@@.@.. +..@...@.....@..@..@.@....@@..@@.@.@..@..@...@..@..@.........@@.......@....@@.@.....@.....@@...@@.... +@...@@@.@..@T@@T@.....@@...@@.@.......@.@............@@.@....@.@@.....@..@@..@@@.@..@..@@...@.@....@ +....@T@.....@TTTT@.@@@.@.@.@.....@...@.......@..@.@.@@@...@..........@...@@...@@..@........@@...@... +....@T@.@....@TT@@@@@...@@.@.@..@..@.........@.@.@......@.@.@@@.@.@...@..@@.@@.@.@...@..@..@...@T@.. +@@.@.@...@..@TT@@TT@@.....@..@..@....@.@..@..@.@......@.@.@..@..@@..@..@.........@...@@.@.......@.@. +@T@...@....@@@@T@@TT@...@.....@.@@..@..........@@...@.@...@..@.@.....@.....@@...@....@...@.@@.@..... +@@....@..@@..@TT@TT@@.....@..@@@..@.@@@.@....@.@@...@..@..@@...@@....@@@...@.@@@@.@@..@@..@T@.@..... +...@@.@.@.@...@T@TTT@@..@@T@..@....@..@.@@.@...@T@.@@.@....@..@@.....@@@@.@@....@.....@T@@@@@@..@... +..@@@.........@@TTT@@T@.@TT@@.............@..@@@T@..@..@...@@......@.@TT@............@.@..@@...@.... +...@...@@.@..@..@@@..@...@@...@..........@...@..@@.@@..@.@.....@......@T@....................@@@.... +@.@...@T@...@........@.@@..@.....@..@@...........@..@....@..@..@......@@..@..@..@..@..@@..@..@@..... +.....@.@.@.......@@..@.....@...@.@.@...@.@@.@....@@..@.@.....@.@.@.@...@..@.@.@.@.@@.@....@@..@.@@.. +.@.@.....@.@@..@.......@.@...@@.@...@@......@@.@.@....@.....@T@.@...@@....@.......@.....@@@@...@.... +@T@...@.@.......@.@@@@.....@....@......@..@.@..@...@.@.@.....@.......@.@.@.@.@@..@..@@.@.@...@...@.@ +@@.@...@.......@T@..@..@.......@....@@..@.....@......@......@....@.....@.@...@@.@..@.@...@.@@@.@..@. +.....@........@T@...@.....@@@@.@..@.@@....@.@@@@.@@@...@@..@.....@...@@T@@.....@T@@...@.....@.....@. +..@...@...@.@..@@...@...@......@......@.@@@.@....@@@@.@.@......@@@@.@..@@@.@..@.@.@..@.@@.........@. +@.@@.@.....@....@...@...@.@...@@...@.@@.@T@@..@...@T@.@.@..@..@.........@..@..@.....@......@.@.@@.@. +...@@T@.....@@......@@...@.@...@@.@@.....@....@...@@@@...@.....@....@@@@..@@@@...@.@@.....@..@..@.@. +.@@..@......@@@..@@@...@...@@.@T@@@......@.......@TTT@..@.@@.....@@@TT@@.@T@@@.@.@.....@@..@.@.@.@.. +@TT@.....@.@T@@@.@@.@.@.@...@.@@TTT@....@@...@@@..@T@.........@.@...@@....@....@..@@...@.@..@....... +@T@..@@@..@.@@@......@@....@@.@TTT@..@..@T@.@TTT@..@.@@.@.@..@T@.@......@....@..@@.....@.@........@. +@@........@.@.@.@.@...@....@T@@T@@..@@..@@..@TT@@......@@..@.@@..........@....@@@@@@.@...@@..@@.@... +...@@...@@..@....@T@@@@...@.@..@@T@@@@@...@..@@@...@..@..@.@@..@.@...@......@..@...@@T@.@@...@..@..@ +@@@@..@......@....@..@T@.@...@.@.@....@@.@...@...@.@@......@..@.@...@......@......@T@@@.@T@...@@.... +@..@@@....@@..@.@@...@@............@..@.@...@..@@....@...@..@......@.@.......@@.@@T@TTT@TT@@.@@..... +@@.....@...@.......@.@....@......@.........@..@T@.....@..@@@@...@.......@.@....@@TTTTTTT@@T@.@@...@. +..@@.@....@..@.@@..@...@.@@.......@......@.@.@T@..@.@.@@.@........@..@.....@..@TTTTT@TT@.@@....@.... +.@................@T@.@............@..@@@..@@TT@.@@...@@@......@.@@.@@..@@....@@TTT@T@@.....@.@T@... +..@@@@..@...@@.....@T@@@...@.@.@..@..@.....@@@@.@....@@@.....@@.@T@@@.@@@@@.@...@TT@@.....@@@@.@..@. +.@......@..@...@..@.@..@..@T@..@@@@.@..@@..@.@....@@.@@T@.....@..@....@TT@@.@.@..@@.......@....@.@T@ +.........@......@........@.@T@....@...@@...@.....@@.@..@@@..@...@....@TTT@.@.....@....@......@.@.@@T +.....@................@@.@..@..@@..@...@...@..@.@@......@T@.@.@.@.@...@@@..@@@@.@@@..@.@@@...@.....@ +@@.......@...@.....@..@@.@@....@.....@....@@....@..@.@...@....@.@...@......@@T@@@@..@@............@@ +TT@.....@T@.....@@@T@@@.@.@.@...@...@@@......@.@.@....@..@@..@.@..@.@.@.@@...@..@.@...@....@..@....@ +TT@...@.@@.....@TTTT@@.......@@...@.@....@..@......@@@@..@T@@@..@.@@...@@@@...@.@....@...@@T@.@@@... +@@..@@@..@@..@@.@T@@T@@..@@@@@..@..@..........@@....@T@...@@.....@@....@...@@...@..@..@..@.@...@.... +@T@.@....@..@....@..@.@...@T@@@@...@.@...@.@@@....@..@........@@..@...@.......@.@.@T@.@....@.@....@. +TT@.........@@......@....@@@......@@.....@@@.....@.@..@.@.@.@@..@@.@@.@@.....@@...@@@.@.@...@...@..@ +T@.......@..@@...@.....@@@@..@@.....@........@.@@@...@@@......@.@...@.@@.@@...@..@....@@@@.@.@.@.... +@.@@@@@..@...@.@........@......@@@@.@.....@.@@..@....@.@@...@...@@...@......@.@...@...@@..@..@@....@ +..@@TT@...@.@..@.@@...@@@..@....@TT@T@........@@..@.......@.......@..@....@..@@....@.@...@T@...@.... +@..@TTT@.@...@.@@.@...@....@@@..@@TTT@.@.@@....@@...@.@@@......@..@@..@...@....@........@@@T@..@.... +..@@@T@....@@T@@......@...@.......@@TT@....@..@T@.@@@...@..@@......@...@.@@@..@@.@.@.@.....@@@...@@. +@...@@...@@..@@.....@.@..@.@.......@T@.@@@....@@@..@T@@..@..@@...@.........@.@@...@...@.....@@@..@.. +@@@.....@@...@...@...@@@.@..@.@@@.@@@@.@.@.@@...@.@TT@.......@...@.@..@@.@....@..@@@@..@@@@.@..@.@@@ +TT@@@..@@@....@.....@..@@@..@@.......@...@@........@T@.@.....@@.....@@@@.@..........@...@@@@T@.@@.@. +T@@.@@.@@T@..@@.....@@...@.@TT@...@@...@@.....@.....@@@....@..@..@@@.@@.@T@....@.@.....@.@..@.....@. +@@@.....@@....@.............@T@.@.....@@@.@@..............@.@.@@.@.......@@@.@..@@@.@@@..@.@..@..... +TT@....@TT@@...@..@......@@.@T@..@.@.....@..@..@...@.....@...........@@@@@@.@..@@...@...@@...@@.@..@ +@TT@....@@..@.......@@..@....@@@@.........@.@..@...@...@@@.@@.@....@....@.....@T@...@...@@.@..@@@@@@ +TTTT@......@...@..@@....@.@.@@@@T@....@..@..@..@......@T@..@..@.@@@......@@.@..@..@.....@.....@..@.. +@TT@@.....@...@...@@..@@..@@....@@@@..@@.@@...@.@@...@@@....@@.......@...@.....@.@.@.@.@@.........@. +TT@...@............@....@.@@...@...@@@@@..@@@.....@.@..@@...@.@@@.@..@...@..@.@@...@@.@@.@@......... +T@...@T@.@.....@.@@.@..........@......@@..@.@@.................@@.@.......@............@......@.@... +@@@@..@T@...@.@.@.@..@..........@@...@.@....@@@.@...@...@@.@.@.@.@.....@.@...@.....@@@@..@.@...@..@. +.@@@.@@@.@..@@@.........@..@..@@..@........@.@...@@@..@.@...@@.......@.......@@...@@..@......@.@.@@. +.........@@@.@......@....@.@.@@T@.....@.........@@....@@@....@@@@@........@..@...@...@...@..@.@..@@. +.@..@.@......@...@.@..@@@@..@.@@@.....@....@.@...@....@@@@.@@@@..@.@.@....@.@..........@...@.....@.. +......@.@.@@....@@..@.@.......@......@@......@...@....@..@@.........@@@.@...............@..@..@@...@ +..@.@..@@@.@@.@....@@.@@.....@......@.@@.@@.....@@@..........@........@@...@@..@.@..@..............@ +..@@.......@...@.@..@..@....@...@@........@@..@.......@...@.@....@..@@T@@@.................@..@....@ +..@@@...@..@@.......@@@@@...........@@.@....@@@@@.....@...@@..@.@@@..@@......@..@......@......@..... +.@@@@.....@@T@.@...@.@@.@@@....@@.@....@...@..........@@@.@@@.@....@...@@@@...@@...................@ +@...........@.@.@....@........@......@@@@@@.....@@@....@@.@T@@........@@T@T@........@..@..@@..@..... +@.@.....@........@@......@...@@.....@TT@TT@@@........@@TT@TT@.....@..@TTTTTT@.......@.@.....@..@.@.. diff --git a/JPSPlusGoalBounding/Maps/random-100-33.map.pre b/JPSPlusGoalBounding/Maps/random-100-33.map.pre new file mode 100644 index 0000000..dd2b923 Binary files /dev/null and b/JPSPlusGoalBounding/Maps/random-100-33.map.pre differ diff --git a/JPSPlusGoalBounding/Maps/random-100-33.map.scen b/JPSPlusGoalBounding/Maps/random-100-33.map.scen new file mode 100644 index 0000000..43c95f1 --- /dev/null +++ b/JPSPlusGoalBounding/Maps/random-100-33.map.scen @@ -0,0 +1,491 @@ +version 1 +1 random-100-33.map 100 100 10 47 12 51 6.82843 +1 random-100-33.map 100 100 23 24 25 28 6 +1 random-100-33.map 100 100 11 53 7 51 4.82843 +1 random-100-33.map 100 100 39 10 42 6 6.41421 +1 random-100-33.map 100 100 7 3 4 6 4.24264 +1 random-100-33.map 100 100 27 94 32 94 7.82843 +1 random-100-33.map 100 100 74 42 70 47 7.82843 +1 random-100-33.map 100 100 94 13 92 19 7.41421 +1 random-100-33.map 100 100 56 34 58 28 7.41421 +1 random-100-33.map 100 100 41 3 45 4 5.82843 +2 random-100-33.map 100 100 11 21 0 22 11.4142 +2 random-100-33.map 100 100 73 15 66 11 9.24264 +2 random-100-33.map 100 100 26 19 30 20 9 +2 random-100-33.map 100 100 39 84 37 91 10.4142 +2 random-100-33.map 100 100 7 50 10 42 10.6569 +2 random-100-33.map 100 100 4 60 5 57 8 +2 random-100-33.map 100 100 68 84 61 83 8 +2 random-100-33.map 100 100 96 3 97 12 9.41421 +2 random-100-33.map 100 100 46 44 48 54 11.4142 +2 random-100-33.map 100 100 21 65 13 69 9.65685 +3 random-100-33.map 100 100 7 92 6 84 12.4142 +3 random-100-33.map 100 100 62 34 61 21 13.4142 +3 random-100-33.map 100 100 77 83 86 88 14 +3 random-100-33.map 100 100 26 44 26 55 15.2426 +3 random-100-33.map 100 100 62 16 54 24 15.4142 +3 random-100-33.map 100 100 28 4 19 7 14.8284 +3 random-100-33.map 100 100 85 93 93 84 14.6569 +3 random-100-33.map 100 100 85 35 77 39 15.4142 +3 random-100-33.map 100 100 46 83 48 95 14.8284 +3 random-100-33.map 100 100 59 12 59 24 14.2426 +4 random-100-33.map 100 100 37 94 46 88 17.2426 +4 random-100-33.map 100 100 96 73 87 63 18.0711 +4 random-100-33.map 100 100 89 19 96 12 19.4142 +4 random-100-33.map 100 100 3 12 1 27 19.4853 +4 random-100-33.map 100 100 39 43 24 49 18.6569 +4 random-100-33.map 100 100 61 31 48 38 17.0711 +4 random-100-33.map 100 100 63 36 54 44 17.8284 +4 random-100-33.map 100 100 37 64 29 57 18.4142 +4 random-100-33.map 100 100 49 75 55 67 18.2426 +4 random-100-33.map 100 100 39 91 49 84 19.2426 +5 random-100-33.map 100 100 87 84 81 96 21.4142 +5 random-100-33.map 100 100 1 19 6 31 20.4142 +5 random-100-33.map 100 100 96 43 97 59 23.2426 +5 random-100-33.map 100 100 4 4 19 7 20.8284 +5 random-100-33.map 100 100 29 47 42 41 22.6569 +5 random-100-33.map 100 100 66 17 48 13 22.2426 +5 random-100-33.map 100 100 78 39 65 29 23.2426 +5 random-100-33.map 100 100 81 44 65 46 22.2426 +5 random-100-33.map 100 100 66 86 85 93 23.6569 +5 random-100-33.map 100 100 86 29 94 17 20.8284 +6 random-100-33.map 100 100 75 29 76 8 27.6569 +6 random-100-33.map 100 100 81 41 60 43 27.4853 +6 random-100-33.map 100 100 46 71 32 72 27.2426 +6 random-100-33.map 100 100 3 92 20 79 27.8995 +6 random-100-33.map 100 100 85 78 65 75 27.8284 +6 random-100-33.map 100 100 71 75 67 70 24.6569 +6 random-100-33.map 100 100 62 79 46 69 24.8284 +6 random-100-33.map 100 100 47 23 64 29 25.2426 +6 random-100-33.map 100 100 61 4 56 24 25.2426 +6 random-100-33.map 100 100 47 26 43 11 27.4853 +7 random-100-33.map 100 100 68 78 83 91 29.0711 +7 random-100-33.map 100 100 75 21 88 43 31.4853 +7 random-100-33.map 100 100 79 23 67 5 28.4853 +7 random-100-33.map 100 100 87 58 94 37 30.8284 +7 random-100-33.map 100 100 55 96 79 91 29.4853 +7 random-100-33.map 100 100 10 82 15 89 30.2426 +7 random-100-33.map 100 100 69 30 61 54 28.4853 +7 random-100-33.map 100 100 65 7 81 27 31.5563 +7 random-100-33.map 100 100 45 80 32 88 28.0711 +7 random-100-33.map 100 100 40 93 60 75 31.5563 +8 random-100-33.map 100 100 67 89 98 98 35.8995 +8 random-100-33.map 100 100 78 28 51 26 35.7279 +8 random-100-33.map 100 100 78 81 64 71 33.0711 +8 random-100-33.map 100 100 7 70 34 62 32.6569 +8 random-100-33.map 100 100 3 36 12 15 35.8995 +8 random-100-33.map 100 100 20 61 34 45 34.4853 +8 random-100-33.map 100 100 73 0 97 5 32.6569 +8 random-100-33.map 100 100 80 26 54 31 32.8995 +8 random-100-33.map 100 100 33 46 22 61 34.4853 +8 random-100-33.map 100 100 43 43 55 19 35.8995 +9 random-100-33.map 100 100 63 18 32 9 37.8995 +9 random-100-33.map 100 100 52 63 70 51 37.0711 +9 random-100-33.map 100 100 78 70 94 47 39.4853 +9 random-100-33.map 100 100 47 91 43 59 38.4853 +9 random-100-33.map 100 100 61 48 69 55 38.0711 +9 random-100-33.map 100 100 7 40 10 20 36.4142 +9 random-100-33.map 100 100 59 20 38 19 37.6569 +9 random-100-33.map 100 100 54 7 69 31 36.3137 +9 random-100-33.map 100 100 32 48 41 23 38.7279 +9 random-100-33.map 100 100 78 10 96 27 36.0711 +10 random-100-33.map 100 100 73 32 72 2 43.4853 +10 random-100-33.map 100 100 35 61 60 79 43.4853 +10 random-100-33.map 100 100 65 9 66 45 43.4853 +10 random-100-33.map 100 100 51 13 80 2 40.4853 +10 random-100-33.map 100 100 23 45 54 32 41.8995 +10 random-100-33.map 100 100 66 82 70 70 41.6569 +10 random-100-33.map 100 100 14 5 20 29 42.7279 +10 random-100-33.map 100 100 72 91 41 74 43.3137 +10 random-100-33.map 100 100 23 69 7 92 41.1421 +10 random-100-33.map 100 100 3 78 13 49 41.4853 +11 random-100-33.map 100 100 45 79 19 58 47.1421 +11 random-100-33.map 100 100 79 23 48 28 45.3137 +11 random-100-33.map 100 100 82 47 98 74 44.0711 +11 random-100-33.map 100 100 56 5 89 9 44.3137 +11 random-100-33.map 100 100 67 94 98 82 47.4853 +11 random-100-33.map 100 100 90 67 82 31 47.6569 +11 random-100-33.map 100 100 66 47 85 49 47.4853 +11 random-100-33.map 100 100 54 79 32 78 44.5563 +11 random-100-33.map 100 100 75 63 88 63 46.0711 +11 random-100-33.map 100 100 92 82 68 77 46.8995 +12 random-100-33.map 100 100 64 48 45 72 50.8995 +12 random-100-33.map 100 100 64 10 25 6 50.0711 +12 random-100-33.map 100 100 47 43 18 51 50.3137 +12 random-100-33.map 100 100 46 74 14 65 49.4853 +12 random-100-33.map 100 100 45 91 49 56 50.3137 +12 random-100-33.map 100 100 42 63 30 38 49.7279 +12 random-100-33.map 100 100 53 77 55 52 50.6569 +12 random-100-33.map 100 100 29 72 2 73 50.1421 +12 random-100-33.map 100 100 34 45 63 15 51.3848 +12 random-100-33.map 100 100 72 70 37 70 51.8284 +13 random-100-33.map 100 100 65 1 89 37 54.6274 +13 random-100-33.map 100 100 26 33 57 13 52.6569 +13 random-100-33.map 100 100 81 85 40 77 55.7279 +13 random-100-33.map 100 100 25 10 72 11 55.3137 +13 random-100-33.map 100 100 35 48 9 63 53.7279 +13 random-100-33.map 100 100 65 20 22 7 54.7279 +13 random-100-33.map 100 100 46 10 76 31 52.3137 +13 random-100-33.map 100 100 31 99 55 67 53.2132 +13 random-100-33.map 100 100 34 68 36 36 52.7279 +13 random-100-33.map 100 100 61 24 90 23 55.8995 +14 random-100-33.map 100 100 39 46 11 55 56.8995 +14 random-100-33.map 100 100 26 59 41 97 56.5563 +14 random-100-33.map 100 100 51 12 25 48 58.3848 +14 random-100-33.map 100 100 31 36 2 66 56.8995 +14 random-100-33.map 100 100 58 61 88 63 56.1421 +14 random-100-33.map 100 100 41 13 2 16 58.9706 +14 random-100-33.map 100 100 19 56 42 32 57.7279 +14 random-100-33.map 100 100 40 37 34 5 56.9706 +14 random-100-33.map 100 100 46 35 27 15 58.5563 +14 random-100-33.map 100 100 15 84 4 44 57.3848 +15 random-100-33.map 100 100 66 80 18 98 62.3848 +15 random-100-33.map 100 100 74 87 24 94 62.3137 +15 random-100-33.map 100 100 54 80 94 80 63.3137 +15 random-100-33.map 100 100 3 70 32 49 63.5563 +15 random-100-33.map 100 100 66 41 21 53 61.3848 +15 random-100-33.map 100 100 81 74 83 30 62.1421 +15 random-100-33.map 100 100 51 40 84 56 63.7279 +15 random-100-33.map 100 100 70 23 88 63 62.1421 +15 random-100-33.map 100 100 43 45 64 0 62.3848 +15 random-100-33.map 100 100 72 57 85 80 62.9706 +16 random-100-33.map 100 100 44 53 66 55 66.7279 +16 random-100-33.map 100 100 49 84 30 49 66.3848 +16 random-100-33.map 100 100 88 89 34 95 64.4853 +16 random-100-33.map 100 100 76 81 33 78 66.6274 +16 random-100-33.map 100 100 93 70 71 51 66.3137 +16 random-100-33.map 100 100 4 39 9 92 65.5563 +16 random-100-33.map 100 100 11 5 3 49 67.3137 +16 random-100-33.map 100 100 52 24 13 29 67.5563 +16 random-100-33.map 100 100 36 36 49 83 67.799 +16 random-100-33.map 100 100 84 0 46 36 67.799 +17 random-100-33.map 100 100 10 46 26 84 69.799 +17 random-100-33.map 100 100 76 2 25 7 68.1421 +17 random-100-33.map 100 100 64 42 20 74 71.799 +17 random-100-33.map 100 100 11 82 58 86 68.2132 +17 random-100-33.map 100 100 46 43 75 62 68.9706 +17 random-100-33.map 100 100 21 21 57 39 69.3137 +17 random-100-33.map 100 100 14 91 66 80 71.3848 +17 random-100-33.map 100 100 52 32 21 74 69.9706 +17 random-100-33.map 100 100 49 67 93 84 71.6274 +17 random-100-33.map 100 100 79 70 66 48 69.7279 +18 random-100-33.map 100 100 96 93 41 70 75.5563 +18 random-100-33.map 100 100 71 68 70 39 75.5563 +18 random-100-33.map 100 100 7 68 4 13 73.3137 +18 random-100-33.map 100 100 62 34 80 73 73.3848 +18 random-100-33.map 100 100 57 56 4 61 72.9706 +18 random-100-33.map 100 100 48 47 31 21 75.7279 +18 random-100-33.map 100 100 38 42 10 84 75.2132 +18 random-100-33.map 100 100 85 70 78 15 74.3848 +18 random-100-33.map 100 100 50 39 52 98 75.3848 +18 random-100-33.map 100 100 46 20 42 78 72.7279 +19 random-100-33.map 100 100 57 47 65 90 78.799 +19 random-100-33.map 100 100 56 41 16 81 76.3848 +19 random-100-33.map 100 100 10 73 5 13 78.5563 +19 random-100-33.map 100 100 58 29 12 66 77.6274 +19 random-100-33.map 100 100 31 42 8 10 76.8995 +19 random-100-33.map 100 100 3 37 12 86 76.3848 +19 random-100-33.map 100 100 93 46 51 73 79.1421 +19 random-100-33.map 100 100 76 22 41 66 77.6274 +19 random-100-33.map 100 100 57 39 6 71 79.0416 +19 random-100-33.map 100 100 68 97 82 52 77.3848 +20 random-100-33.map 100 100 57 13 14 20 81.799 +20 random-100-33.map 100 100 58 45 35 98 83.2132 +20 random-100-33.map 100 100 6 33 8 98 80.5563 +20 random-100-33.map 100 100 48 26 3 67 81.799 +20 random-100-33.map 100 100 48 48 8 90 83.4558 +20 random-100-33.map 100 100 94 89 35 65 82.799 +20 random-100-33.map 100 100 87 38 26 45 80.9706 +20 random-100-33.map 100 100 40 95 4 58 83.3848 +20 random-100-33.map 100 100 86 18 97 72 81.1421 +20 random-100-33.map 100 100 74 62 71 6 80.5563 +21 random-100-33.map 100 100 26 69 6 24 84.3137 +21 random-100-33.map 100 100 22 87 11 34 85.799 +21 random-100-33.map 100 100 52 24 7 27 85.5563 +21 random-100-33.map 100 100 97 75 83 21 84.1421 +21 random-100-33.map 100 100 63 48 74 90 87.3848 +21 random-100-33.map 100 100 66 0 9 25 86.0416 +21 random-100-33.map 100 100 39 50 74 71 86.4853 +21 random-100-33.map 100 100 8 32 16 97 85.1421 +21 random-100-33.map 100 100 17 74 77 84 87.5563 +21 random-100-33.map 100 100 58 0 84 50 86.8701 +22 random-100-33.map 100 100 36 61 2 13 91.3137 +22 random-100-33.map 100 100 11 63 75 74 89.1421 +22 random-100-33.map 100 100 89 64 89 1 89.1421 +22 random-100-33.map 100 100 31 89 86 77 91.7279 +22 random-100-33.map 100 100 2 29 14 72 91.1421 +22 random-100-33.map 100 100 89 50 35 7 91.9706 +22 random-100-33.map 100 100 81 85 67 30 89.3848 +22 random-100-33.map 100 100 47 74 53 9 91.0416 +22 random-100-33.map 100 100 48 47 23 34 89.5563 +22 random-100-33.map 100 100 44 22 45 94 91.3848 +23 random-100-33.map 100 100 5 39 32 7 92.5563 +23 random-100-33.map 100 100 11 76 56 24 93.8701 +23 random-100-33.map 100 100 89 40 61 84 93.5563 +23 random-100-33.map 100 100 78 95 0 93 95.2132 +23 random-100-33.map 100 100 4 61 20 1 95.3137 +23 random-100-33.map 100 100 4 73 61 25 94.3553 +23 random-100-33.map 100 100 62 23 78 81 93.2132 +23 random-100-33.map 100 100 42 34 3 15 92.1421 +23 random-100-33.map 100 100 24 26 6 68 94.1421 +23 random-100-33.map 100 100 91 34 21 53 94.2132 +24 random-100-33.map 100 100 83 95 43 40 97.3848 +24 random-100-33.map 100 100 53 16 53 95 99.0416 +24 random-100-33.map 100 100 0 92 57 54 97.8701 +24 random-100-33.map 100 100 39 93 94 48 96.3848 +24 random-100-33.map 100 100 18 5 97 11 99.1421 +24 random-100-33.map 100 100 97 80 20 98 98.5563 +24 random-100-33.map 100 100 36 61 86 27 99.6985 +24 random-100-33.map 100 100 40 43 86 69 96.3848 +24 random-100-33.map 100 100 30 49 61 99 96.4558 +24 random-100-33.map 100 100 76 93 49 34 96.3848 +25 random-100-33.map 100 100 27 43 94 3 102.456 +25 random-100-33.map 100 100 20 5 84 45 101.799 +25 random-100-33.map 100 100 92 94 80 64 101.213 +25 random-100-33.map 100 100 90 48 24 69 100.799 +25 random-100-33.map 100 100 25 82 84 69 101.556 +25 random-100-33.map 100 100 68 34 3 13 103.799 +25 random-100-33.map 100 100 75 33 13 0 101.385 +25 random-100-33.map 100 100 51 13 52 94 102.87 +25 random-100-33.map 100 100 29 64 11 4 100.971 +25 random-100-33.map 100 100 15 92 82 67 103.213 +26 random-100-33.map 100 100 24 55 90 57 104.971 +26 random-100-33.map 100 100 70 18 4 68 105.941 +26 random-100-33.map 100 100 80 5 72 80 107.042 +26 random-100-33.map 100 100 25 39 98 66 107.799 +26 random-100-33.map 100 100 4 93 12 30 107.971 +26 random-100-33.map 100 100 42 6 30 78 106.627 +26 random-100-33.map 100 100 91 43 31 80 105.627 +26 random-100-33.map 100 100 68 71 18 81 107.213 +26 random-100-33.map 100 100 85 96 78 16 107.87 +26 random-100-33.map 100 100 40 8 13 65 104.87 +27 random-100-33.map 100 100 50 92 48 8 109.113 +27 random-100-33.map 100 100 87 62 15 93 108.456 +27 random-100-33.map 100 100 97 87 64 61 109.87 +27 random-100-33.map 100 100 56 83 40 4 110.799 +27 random-100-33.map 100 100 9 18 49 67 111.385 +27 random-100-33.map 100 100 2 21 45 87 111.385 +27 random-100-33.map 100 100 73 60 15 58 109.799 +27 random-100-33.map 100 100 90 15 86 84 111.627 +27 random-100-33.map 100 100 88 36 5 50 110.799 +27 random-100-33.map 100 100 88 82 50 28 110.385 +28 random-100-33.map 100 100 43 85 84 18 115.698 +28 random-100-33.map 100 100 87 99 71 21 113.698 +28 random-100-33.map 100 100 15 93 12 28 114.385 +28 random-100-33.map 100 100 6 79 61 11 113.184 +28 random-100-33.map 100 100 78 31 2 13 113.456 +28 random-100-33.map 100 100 89 77 51 13 113.456 +28 random-100-33.map 100 100 69 30 15 93 115.527 +28 random-100-33.map 100 100 16 63 58 61 115.941 +28 random-100-33.map 100 100 79 68 11 52 113.799 +28 random-100-33.map 100 100 56 17 24 91 114.042 +29 random-100-33.map 100 100 73 1 12 59 116.698 +29 random-100-33.map 100 100 68 83 59 2 119.456 +29 random-100-33.map 100 100 12 85 68 12 116.598 +29 random-100-33.map 100 100 29 72 22 24 117.87 +29 random-100-33.map 100 100 63 86 2 35 117.213 +29 random-100-33.map 100 100 45 78 87 30 119.355 +29 random-100-33.map 100 100 93 79 44 41 118.213 +29 random-100-33.map 100 100 93 24 28 58 119.87 +29 random-100-33.map 100 100 10 67 71 2 117.113 +29 random-100-33.map 100 100 8 58 69 60 116.799 +30 random-100-33.map 100 100 96 8 49 67 120.87 +30 random-100-33.map 100 100 0 27 59 83 120.799 +30 random-100-33.map 100 100 46 9 91 78 123.698 +30 random-100-33.map 100 100 94 66 13 60 121.042 +30 random-100-33.map 100 100 94 92 33 34 123.042 +30 random-100-33.map 100 100 53 82 25 22 123.698 +30 random-100-33.map 100 100 10 99 82 67 123.698 +30 random-100-33.map 100 100 12 15 54 53 120.385 +30 random-100-33.map 100 100 6 67 93 68 123.456 +30 random-100-33.map 100 100 7 29 71 54 120.799 +31 random-100-33.map 100 100 78 63 14 79 125.113 +31 random-100-33.map 100 100 99 52 17 51 124.456 +31 random-100-33.map 100 100 48 83 18 14 124.113 +31 random-100-33.map 100 100 70 88 94 9 126.456 +31 random-100-33.map 100 100 72 87 41 5 126.456 +31 random-100-33.map 100 100 11 81 26 31 124.113 +31 random-100-33.map 100 100 9 31 62 60 127.698 +31 random-100-33.map 100 100 79 6 90 99 125.113 +31 random-100-33.map 100 100 92 95 87 22 125.698 +31 random-100-33.map 100 100 6 2 49 67 125.799 +32 random-100-33.map 100 100 32 28 26 75 131.042 +32 random-100-33.map 100 100 33 30 54 74 130.213 +32 random-100-33.map 100 100 12 87 16 14 130.456 +32 random-100-33.map 100 100 94 89 8 51 130.284 +32 random-100-33.map 100 100 1 6 93 0 128.284 +32 random-100-33.map 100 100 35 91 34 20 130.284 +32 random-100-33.map 100 100 7 19 74 51 130.113 +32 random-100-33.map 100 100 93 94 80 3 129.456 +32 random-100-33.map 100 100 99 54 10 76 130.113 +32 random-100-33.map 100 100 85 8 10 57 131.698 +33 random-100-33.map 100 100 66 77 10 15 134.627 +33 random-100-33.map 100 100 45 17 30 86 133.113 +33 random-100-33.map 100 100 96 96 87 10 133.87 +33 random-100-33.map 100 100 98 85 10 76 132.113 +33 random-100-33.map 100 100 22 85 84 50 132.698 +33 random-100-33.map 100 100 37 22 34 95 132.87 +33 random-100-33.map 100 100 9 37 64 64 134.527 +33 random-100-33.map 100 100 41 14 0 92 134.355 +33 random-100-33.map 100 100 17 0 6 99 133.213 +33 random-100-33.map 100 100 61 59 27 83 132.527 +34 random-100-33.map 100 100 64 59 3 10 138.77 +34 random-100-33.map 100 100 7 78 86 12 136.598 +34 random-100-33.map 100 100 78 6 13 88 138.598 +34 random-100-33.map 100 100 40 83 21 21 139.284 +34 random-100-33.map 100 100 30 89 20 30 138.113 +34 random-100-33.map 100 100 51 95 12 16 137.456 +34 random-100-33.map 100 100 73 3 27 89 138.77 +34 random-100-33.map 100 100 80 88 1 35 137.113 +34 random-100-33.map 100 100 2 36 82 87 138.941 +34 random-100-33.map 100 100 10 95 63 10 137.012 +35 random-100-33.map 100 100 31 94 59 66 141.841 +35 random-100-33.map 100 100 67 98 0 21 142.284 +35 random-100-33.map 100 100 6 99 24 6 143.042 +35 random-100-33.map 100 100 12 91 37 13 142.113 +35 random-100-33.map 100 100 69 69 35 7 142.284 +35 random-100-33.map 100 100 17 52 94 77 142.87 +35 random-100-33.map 100 100 88 69 3 40 140.042 +35 random-100-33.map 100 100 93 27 62 99 141.77 +35 random-100-33.map 100 100 4 51 93 70 141.698 +35 random-100-33.map 100 100 57 63 31 96 142.012 +36 random-100-33.map 100 100 41 92 21 35 146.698 +36 random-100-33.map 100 100 68 59 7 18 145.941 +36 random-100-33.map 100 100 23 30 65 86 145.456 +36 random-100-33.map 100 100 44 95 4 1 145.456 +36 random-100-33.map 100 100 92 74 24 22 146.87 +36 random-100-33.map 100 100 7 96 73 26 146.669 +36 random-100-33.map 100 100 76 59 7 93 144.355 +36 random-100-33.map 100 100 96 97 95 25 147.77 +36 random-100-33.map 100 100 99 78 2 60 144.698 +36 random-100-33.map 100 100 91 83 54 12 145.456 +37 random-100-33.map 100 100 94 81 98 17 150.284 +37 random-100-33.map 100 100 88 61 9 24 150.527 +37 random-100-33.map 100 100 0 95 61 60 150.669 +37 random-100-33.map 100 100 85 98 33 12 151.113 +37 random-100-33.map 100 100 5 18 97 52 149.355 +37 random-100-33.map 100 100 87 63 4 1 148.698 +37 random-100-33.map 100 100 51 95 7 0 148.456 +37 random-100-33.map 100 100 27 19 77 94 149.284 +37 random-100-33.map 100 100 2 18 76 61 149.627 +37 random-100-33.map 100 100 92 74 0 90 151.355 +38 random-100-33.map 100 100 10 30 99 69 155.113 +38 random-100-33.map 100 100 79 7 5 94 153.426 +38 random-100-33.map 100 100 92 95 34 13 155.456 +38 random-100-33.map 100 100 28 94 88 24 152.669 +38 random-100-33.map 100 100 72 94 17 14 155.527 +38 random-100-33.map 100 100 67 89 16 31 154.113 +38 random-100-33.map 100 100 10 18 76 68 154.042 +38 random-100-33.map 100 100 57 96 5 0 153.113 +38 random-100-33.map 100 100 77 76 23 29 153.042 +38 random-100-33.map 100 100 78 80 24 32 155.456 +39 random-100-33.map 100 100 79 70 11 5 156.941 +39 random-100-33.map 100 100 96 22 4 79 157.669 +39 random-100-33.map 100 100 33 14 92 95 156.284 +39 random-100-33.map 100 100 73 66 29 0 158.77 +39 random-100-33.map 100 100 87 70 4 28 156.456 +39 random-100-33.map 100 100 88 74 2 18 159.213 +39 random-100-33.map 100 100 4 82 98 20 158.669 +39 random-100-33.map 100 100 94 0 32 94 159.841 +39 random-100-33.map 100 100 86 11 6 94 157.426 +39 random-100-33.map 100 100 33 20 91 90 159.698 +40 random-100-33.map 100 100 71 93 2 2 163.113 +40 random-100-33.map 100 100 3 94 94 13 162.426 +40 random-100-33.map 100 100 29 12 94 99 163.941 +40 random-100-33.map 100 100 30 30 66 98 162.77 +40 random-100-33.map 100 100 10 14 82 95 162.355 +40 random-100-33.map 100 100 9 96 61 67 161.083 +40 random-100-33.map 100 100 13 88 99 24 160.669 +40 random-100-33.map 100 100 90 68 9 18 162.941 +40 random-100-33.map 100 100 16 90 94 7 160.012 +40 random-100-33.map 100 100 3 93 86 29 163.083 +41 random-100-33.map 100 100 31 27 85 84 166.698 +41 random-100-33.map 100 100 80 98 18 18 164.77 +41 random-100-33.map 100 100 34 6 98 98 165.941 +41 random-100-33.map 100 100 86 98 0 15 165.527 +41 random-100-33.map 100 100 4 0 97 76 164.698 +41 random-100-33.map 100 100 18 1 78 99 167.012 +41 random-100-33.map 100 100 14 0 68 94 167.941 +41 random-100-33.map 100 100 68 99 26 33 165.456 +41 random-100-33.map 100 100 33 29 82 84 164.527 +41 random-100-33.map 100 100 65 94 14 2 164.113 +42 random-100-33.map 100 100 87 97 27 28 171.527 +42 random-100-33.map 100 100 11 5 80 85 171.77 +42 random-100-33.map 100 100 19 95 96 3 169.426 +42 random-100-33.map 100 100 33 25 69 71 171.113 +42 random-100-33.map 100 100 9 7 85 95 171.941 +42 random-100-33.map 100 100 97 75 10 12 169.698 +42 random-100-33.map 100 100 37 5 97 88 168.113 +42 random-100-33.map 100 100 68 69 13 28 171.456 +42 random-100-33.map 100 100 19 32 80 88 168.941 +42 random-100-33.map 100 100 92 87 24 19 170.527 +43 random-100-33.map 100 100 93 19 10 98 172.912 +43 random-100-33.map 100 100 88 91 14 19 174.184 +43 random-100-33.map 100 100 83 99 30 30 172.77 +43 random-100-33.map 100 100 80 98 21 34 172.598 +43 random-100-33.map 100 100 25 3 92 90 173.941 +43 random-100-33.map 100 100 69 72 7 8 173.456 +43 random-100-33.map 100 100 25 23 95 97 173.355 +43 random-100-33.map 100 100 64 68 11 28 175.042 +43 random-100-33.map 100 100 87 93 25 30 173.284 +43 random-100-33.map 100 100 91 31 4 98 172.083 +44 random-100-33.map 100 100 32 29 88 96 177.527 +44 random-100-33.map 100 100 97 71 4 17 176.456 +44 random-100-33.map 100 100 88 90 25 30 176.113 +44 random-100-33.map 100 100 3 3 86 95 179.527 +44 random-100-33.map 100 100 94 90 22 19 176.113 +44 random-100-33.map 100 100 92 85 19 8 178.527 +44 random-100-33.map 100 100 27 1 91 88 178.355 +44 random-100-33.map 100 100 1 1 91 78 176.012 +44 random-100-33.map 100 100 93 89 21 2 178.355 +44 random-100-33.map 100 100 10 99 99 15 176.497 +45 random-100-33.map 100 100 95 82 30 22 181.527 +45 random-100-33.map 100 100 98 96 27 0 183.184 +45 random-100-33.map 100 100 4 2 65 66 181.87 +45 random-100-33.map 100 100 8 5 90 92 180.355 +45 random-100-33.map 100 100 13 0 67 71 183.184 +45 random-100-33.map 100 100 3 10 92 92 180.941 +45 random-100-33.map 100 100 18 1 93 96 180.184 +45 random-100-33.map 100 100 27 31 88 87 180.113 +45 random-100-33.map 100 100 96 97 1 12 180.184 +45 random-100-33.map 100 100 32 26 90 91 181.527 +46 random-100-33.map 100 100 18 17 96 81 187.941 +46 random-100-33.map 100 100 99 99 14 8 186.426 +46 random-100-33.map 100 100 21 11 97 80 184.941 +46 random-100-33.map 100 100 95 83 21 20 187.527 +46 random-100-33.map 100 100 90 81 18 19 185.355 +46 random-100-33.map 100 100 98 83 10 23 184.77 +46 random-100-33.map 100 100 21 30 97 98 185.598 +46 random-100-33.map 100 100 92 85 1 6 186.77 +46 random-100-33.map 100 100 19 20 99 90 184.527 +46 random-100-33.map 100 100 99 90 13 30 187.355 +47 random-100-33.map 100 100 15 28 93 81 191.77 +47 random-100-33.map 100 100 91 81 4 6 188.77 +47 random-100-33.map 100 100 1 7 96 86 188.184 +47 random-100-33.map 100 100 17 35 93 98 188.598 +47 random-100-33.map 100 100 17 35 95 96 190.941 +47 random-100-33.map 100 100 92 85 17 27 188.598 +47 random-100-33.map 100 100 0 0 94 89 191.77 +47 random-100-33.map 100 100 99 88 3 6 189.598 +47 random-100-33.map 100 100 5 4 96 85 188.184 +47 random-100-33.map 100 100 30 33 98 95 191.113 +48 random-100-33.map 100 100 1 9 98 82 194.184 +48 random-100-33.map 100 100 13 4 97 88 192.184 +48 random-100-33.map 100 100 11 7 95 87 194.184 +48 random-100-33.map 100 100 15 0 90 91 192.184 +48 random-100-33.map 100 100 97 86 17 26 193.012 +48 random-100-33.map 100 100 26 37 94 92 192.355 +48 random-100-33.map 100 100 98 82 22 29 193.77 +48 random-100-33.map 100 100 12 33 95 82 193.355 +48 random-100-33.map 100 100 99 87 17 25 195.598 +48 random-100-33.map 100 100 30 32 99 98 193.184 +49 random-100-33.map 100 100 97 83 33 31 198.77 +49 random-100-33.map 100 100 95 83 13 34 196.355 +49 random-100-33.map 100 100 94 81 19 34 196.77 +49 random-100-33.map 100 100 95 83 27 33 196.527 +49 random-100-33.map 100 100 26 35 97 86 196.184 +49 random-100-33.map 100 100 11 2 98 87 197.598 +49 random-100-33.map 100 100 93 79 13 34 196.355 +49 random-100-33.map 100 100 30 33 94 80 197.527 +49 random-100-33.map 100 100 24 32 99 80 199.184 +49 random-100-33.map 100 100 96 82 18 28 197.012 diff --git a/JPSPlusGoalBounding/Maps/room-100-10.map b/JPSPlusGoalBounding/Maps/room-100-10.map new file mode 100644 index 0000000..4694f40 --- /dev/null +++ b/JPSPlusGoalBounding/Maps/room-100-10.map @@ -0,0 +1,104 @@ +type octile +height 100 +width 100 +map +@@@@@@@@@.@@@@@@@.@@@@@@@@@@.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@@.@@@@@.@@@@@@@@@@@@@@ +@.........@.........@.........@.........@.........@.........@...................@.........@......... +@.........@.........@.........@.........@.........@...................@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +..........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@...................@.........@.........@.........@.........@.........@...................@......... +@.........@...................@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@................... +@@@@@@@@@@@@@@@@.@@@@@@@.@@@@@@@@@.@@@@@@@@.@@@@@@@@@@@@@@@.@@@@@@@@@.@@@@@@@@.@@@@@@.@@@@@@@@@@.@@@ +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@...................@.........@...................@...................@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@...................@.........@.........@.........@.........@.........@................... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +..........@.........@.........@.........@...................@.........@...................@......... +@@@@@@@@@@@@@@@.@@@@@@@@@@@@.@@@@@@.@@@@@@@@@@@@.@@@@@@@.@@@@@@.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@ +@.........@.........@.........@.........@.........@.........@...................@.........@......... +@.........@.........@.........@.........@.........@...................@.........@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +..........@.........@.........@.........@.........@.........@.........@.........@................... +@.........@.........@.........@...................@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@...................@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@@@@@.@@@@@@@.@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@@@.@@@@@@@@@@@@.@@@@@@.@@@@@@@@.@@@@@@@.@@@@@@@ +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@...................@.........@.........@...................@.........@.........@......... +..........@.........@.........@.........@.........@.........@.........@...................@......... +@...................@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@...................@.........@.........@...................@.........@......... +@@@.@@@@@@@@.@@@@@@@@@@@@@@@.@@@@@@@@@.@@@@@@@@@.@@@@.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@.@@@ +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@...................@.........@.........@.........@...................@.........@.........@......... +@.........@.........@.........@.........@...................@.........@...................@......... +@.........@.........@.........@...................@.........@.........@.........@................... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +..........@...................@.........@.........@.........@.........@.........@.........@......... +@.@@@@@@@@@@@.@@@@@@@@@@.@@@@@@@.@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@.@@@@@@@@.@@@@@@@@@.@@@@@@@@@@@@.@@@ +..........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@...................@.........@...................@.........@......... +@.........@.........@...................@.........@.........@.........@.........@................... +@...................@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@...................@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@@.@@@@@@@@@@@@.@@@@@@@@@.@@@@@@@.@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@@.@@@@@@@@.@@.@@@@@@@@@.@@@@@@@@ +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@...................@.........@...................@.........@.........@......... +@...................@.........@.........@.........@.........@...................@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@...................@......... +@.........@.........@.........@.........@.........@.........@.........@.........@................... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +..........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +@@@@@@@.@@@@@@@@@@@@@@@@@@@.@@@@@@@.@@@@@@@@@@@@@.@@@.@@@@@@@@.@@@@@@@@@@@@.@@@@@@@@.@@@@@@.@@@@@@@@ +@.........@.........@.........@...................@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@...................@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +@.........@.........@...................@.........@...................@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@................... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@@@@.@@@@@@@@@@@@@@.@@@@@@@@@.@@@@@.@@@@@@@.@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@@@.@@@@@@@@.@@@@@@@@@@.@@@ +@.........@.........@.............................@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@...................@......... +@.........@.........@.........@.........@.........@.........@.........@.........@................... +@.........@.........@.........@.........@.........@.........@...................@.........@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... +....................@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@...................@.........@.........@.........@.........@.........@.........@......... +@@@@@@.@@@@@@@@.@@@@@@@@@@@@@.@.@@@@@@@@@@@@@@@@.@@@@@.@@@@@@@.@@@@@@@@.@@@@@@@@@@@@@@@@@.@@.@@@@@@@ +@.........@...................@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@...................@.........@.........@.........@.........@......... +..........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@.........@.........@......... +@.........@.........@...................@.........@.........@.........@.........@.........@......... +@...................@.........@.........@.........@...................@.........@.........@......... +@.........@.........@.........@.........@.........@.........@.........@...................@......... +@.........@.........@.........@.........@...................@.........@.........@.........@......... diff --git a/JPSPlusGoalBounding/Maps/room-100-10.map.pre b/JPSPlusGoalBounding/Maps/room-100-10.map.pre new file mode 100644 index 0000000..4ea4c9d Binary files /dev/null and b/JPSPlusGoalBounding/Maps/room-100-10.map.pre differ diff --git a/JPSPlusGoalBounding/Maps/room-100-10.map.scen b/JPSPlusGoalBounding/Maps/room-100-10.map.scen new file mode 100644 index 0000000..2bf37b8 --- /dev/null +++ b/JPSPlusGoalBounding/Maps/room-100-10.map.scen @@ -0,0 +1,421 @@ +version 1 +1 room-100-10.map 100 100 91 28 95 23 6.65685 +1 room-100-10.map 100 100 94 92 98 93 4.41421 +1 room-100-10.map 100 100 73 92 74 88 7.82843 +1 room-100-10.map 100 100 46 8 42 6 4.82843 +1 room-100-10.map 100 100 78 19 74 14 6.65685 +1 room-100-10.map 100 100 54 75 53 70 5.41421 +1 room-100-10.map 100 100 32 39 38 38 6.41421 +1 room-100-10.map 100 100 14 72 19 74 5.82843 +1 room-100-10.map 100 100 78 36 75 31 6.24264 +1 room-100-10.map 100 100 14 57 17 62 6.82843 +2 room-100-10.map 100 100 26 43 25 51 9.82843 +2 room-100-10.map 100 100 79 82 74 74 11.2426 +2 room-100-10.map 100 100 60 42 69 47 11.0711 +2 room-100-10.map 100 100 15 14 19 22 11.4142 +2 room-100-10.map 100 100 95 86 95 92 9.65685 +2 room-100-10.map 100 100 3 43 13 41 10.8284 +2 room-100-10.map 100 100 38 75 31 82 11.6569 +2 room-100-10.map 100 100 36 84 42 78 11.6569 +2 room-100-10.map 100 100 76 67 75 78 11.4142 +2 room-100-10.map 100 100 88 38 87 42 9.82843 +3 room-100-10.map 100 100 82 99 71 96 12.2426 +3 room-100-10.map 100 100 41 41 53 39 15.6569 +3 room-100-10.map 100 100 12 64 1 57 15.6569 +3 room-100-10.map 100 100 14 25 17 12 14.2426 +3 room-100-10.map 100 100 25 60 34 52 12.8995 +3 room-100-10.map 100 100 32 74 31 87 15.8995 +3 room-100-10.map 100 100 54 18 58 8 12.4853 +3 room-100-10.map 100 100 68 88 78 82 13.6569 +3 room-100-10.map 100 100 49 70 57 78 14.8284 +3 room-100-10.map 100 100 52 25 54 39 15.6569 +4 room-100-10.map 100 100 56 64 49 62 16.0711 +4 room-100-10.map 100 100 92 41 91 29 18.6569 +4 room-100-10.map 100 100 31 83 17 89 19.3137 +4 room-100-10.map 100 100 72 37 84 29 17.6569 +4 room-100-10.map 100 100 16 92 26 83 17.4853 +4 room-100-10.map 100 100 40 25 58 23 18.8284 +4 room-100-10.map 100 100 77 36 67 33 16.0711 +4 room-100-10.map 100 100 62 87 78 84 17.2426 +4 room-100-10.map 100 100 67 13 72 5 19.2426 +4 room-100-10.map 100 100 52 37 59 22 17.8995 +5 room-100-10.map 100 100 39 69 29 57 21.3137 +5 room-100-10.map 100 100 52 38 54 58 20.8284 +5 room-100-10.map 100 100 5 64 2 81 21.0711 +5 room-100-10.map 100 100 18 25 26 13 20.7279 +5 room-100-10.map 100 100 55 81 68 69 23.2426 +5 room-100-10.map 100 100 44 87 31 75 20.8995 +5 room-100-10.map 100 100 27 91 37 76 23.8284 +5 room-100-10.map 100 100 82 41 96 36 21.4853 +5 room-100-10.map 100 100 24 54 44 56 21.6569 +5 room-100-10.map 100 100 19 83 26 94 21.8995 +6 room-100-10.map 100 100 98 62 78 59 27.4853 +6 room-100-10.map 100 100 44 79 55 58 27.5563 +6 room-100-10.map 100 100 14 47 5 65 26.8995 +6 room-100-10.map 100 100 63 48 58 68 26.3137 +6 room-100-10.map 100 100 28 38 19 25 27.5563 +6 room-100-10.map 100 100 98 71 85 87 24.3137 +6 room-100-10.map 100 100 86 53 78 55 26.4853 +6 room-100-10.map 100 100 45 83 24 72 26.7279 +6 room-100-10.map 100 100 99 67 96 84 25.8995 +6 room-100-10.map 100 100 39 74 28 59 27.3137 +7 room-100-10.map 100 100 26 81 31 58 31.8995 +7 room-100-10.map 100 100 34 86 53 95 31.799 +7 room-100-10.map 100 100 42 79 56 57 28.9706 +7 room-100-10.map 100 100 49 87 64 89 29.7279 +7 room-100-10.map 100 100 2 54 22 47 28.0711 +7 room-100-10.map 100 100 1 22 1 47 28.3137 +7 room-100-10.map 100 100 27 96 45 83 29.1421 +7 room-100-10.map 100 100 81 26 73 47 29.7279 +7 room-100-10.map 100 100 42 41 57 24 31.3137 +7 room-100-10.map 100 100 21 16 10 37 28.4853 +8 room-100-10.map 100 100 88 82 65 77 32.9706 +8 room-100-10.map 100 100 53 48 73 67 33.1421 +8 room-100-10.map 100 100 68 38 69 7 35.5563 +8 room-100-10.map 100 100 74 53 96 68 32.3137 +8 room-100-10.map 100 100 46 35 57 61 32.3137 +8 room-100-10.map 100 100 34 86 41 68 33.9706 +8 room-100-10.map 100 100 27 74 12 96 33.3848 +8 room-100-10.map 100 100 73 22 91 45 33.9706 +8 room-100-10.map 100 100 21 24 12 27 34.1421 +8 room-100-10.map 100 100 68 7 66 34 32.799 +9 room-100-10.map 100 100 15 48 48 59 39.5563 +9 room-100-10.map 100 100 36 83 7 95 39.6274 +9 room-100-10.map 100 100 95 28 86 56 39.1421 +9 room-100-10.map 100 100 17 33 31 56 36.799 +9 room-100-10.map 100 100 66 61 44 45 38.7279 +9 room-100-10.map 100 100 91 79 69 59 36.1421 +9 room-100-10.map 100 100 92 27 74 23 37.799 +9 room-100-10.map 100 100 95 19 83 45 36.7279 +9 room-100-10.map 100 100 79 26 71 44 36.3848 +9 room-100-10.map 100 100 83 85 54 75 39.6274 +10 room-100-10.map 100 100 22 58 14 26 41.5563 +10 room-100-10.map 100 100 37 48 18 53 41.3137 +10 room-100-10.map 100 100 65 48 58 17 42.1421 +10 room-100-10.map 100 100 97 71 68 53 42.3137 +10 room-100-10.map 100 100 6 34 25 22 42.5563 +10 room-100-10.map 100 100 44 29 64 3 40.3848 +10 room-100-10.map 100 100 35 58 57 32 42.9706 +10 room-100-10.map 100 100 47 36 19 33 43.7279 +10 room-100-10.map 100 100 82 54 66 32 41.5563 +10 room-100-10.map 100 100 97 1 65 7 43.4558 +11 room-100-10.map 100 100 68 88 43 77 45.2132 +11 room-100-10.map 100 100 65 62 31 83 46.2132 +11 room-100-10.map 100 100 83 96 61 73 47.8701 +11 room-100-10.map 100 100 53 22 88 32 47.3848 +11 room-100-10.map 100 100 68 82 81 52 45.1421 +11 room-100-10.map 100 100 97 27 95 63 46.3848 +11 room-100-10.map 100 100 65 27 49 57 46.9706 +11 room-100-10.map 100 100 76 59 87 97 46.5563 +11 room-100-10.map 100 100 5 53 23 67 45.3137 +11 room-100-10.map 100 100 59 52 87 77 47.1421 +12 room-100-10.map 100 100 7 99 44 84 48.0416 +12 room-100-10.map 100 100 48 58 8 44 50.0416 +12 room-100-10.map 100 100 64 17 81 49 48.2132 +12 room-100-10.map 100 100 81 84 45 93 51.3848 +12 room-100-10.map 100 100 39 24 33 57 49.6274 +12 room-100-10.map 100 100 56 61 79 38 49.4558 +12 room-100-10.map 100 100 38 81 3 72 50.6274 +12 room-100-10.map 100 100 48 96 75 97 48.9706 +12 room-100-10.map 100 100 66 76 97 48 49.0416 +12 room-100-10.map 100 100 43 67 22 54 48.1421 +13 room-100-10.map 100 100 54 67 88 39 52.0416 +13 room-100-10.map 100 100 94 52 99 4 54.799 +13 room-100-10.map 100 100 5 72 3 25 53.3848 +13 room-100-10.map 100 100 27 33 65 39 53.799 +13 room-100-10.map 100 100 29 52 58 85 53.2132 +13 room-100-10.map 100 100 32 32 9 61 52.9706 +13 room-100-10.map 100 100 15 78 51 76 52.9706 +13 room-100-10.map 100 100 59 82 49 48 53.5563 +13 room-100-10.map 100 100 62 59 94 87 52.9706 +13 room-100-10.map 100 100 7 58 14 11 52.7279 +14 room-100-10.map 100 100 21 59 63 38 57.8701 +14 room-100-10.map 100 100 34 41 67 71 58.5563 +14 room-100-10.map 100 100 36 79 9 45 57.6274 +14 room-100-10.map 100 100 93 22 85 71 57.3848 +14 room-100-10.map 100 100 83 51 54 17 57.6274 +14 room-100-10.map 100 100 81 29 56 66 59.2132 +14 room-100-10.map 100 100 66 36 51 78 57.3848 +14 room-100-10.map 100 100 46 48 2 49 58.6985 +14 room-100-10.map 100 100 33 60 56 18 59.9706 +14 room-100-10.map 100 100 57 55 22 86 56.0416 +15 room-100-10.map 100 100 75 76 41 39 62.2132 +15 room-100-10.map 100 100 55 91 42 45 63.3848 +15 room-100-10.map 100 100 88 46 48 34 61.6985 +15 room-100-10.map 100 100 26 43 61 25 61.9706 +15 room-100-10.map 100 100 79 21 92 7 62.1127 +15 room-100-10.map 100 100 27 85 8 57 60.6985 +15 room-100-10.map 100 100 93 14 47 8 60.2843 +15 room-100-10.map 100 100 93 89 55 58 60.799 +15 room-100-10.map 100 100 92 35 63 17 60.6985 +15 room-100-10.map 100 100 59 48 82 22 60.1127 +16 room-100-10.map 100 100 54 95 97 61 67.8701 +16 room-100-10.map 100 100 93 92 69 48 66.8701 +16 room-100-10.map 100 100 28 64 79 68 66.4558 +16 room-100-10.map 100 100 79 78 94 28 67.5269 +16 room-100-10.map 100 100 24 35 53 77 66.1127 +16 room-100-10.map 100 100 81 25 41 35 65.9411 +16 room-100-10.map 100 100 39 12 27 36 65.6985 +16 room-100-10.map 100 100 12 42 46 65 64.4558 +16 room-100-10.map 100 100 27 35 65 15 67.2132 +16 room-100-10.map 100 100 57 71 38 29 65.0416 +17 room-100-10.map 100 100 56 38 78 88 68.0416 +17 room-100-10.map 100 100 25 47 79 69 71.6985 +17 room-100-10.map 100 100 38 64 74 37 70.1127 +17 room-100-10.map 100 100 37 47 27 4 71.8701 +17 room-100-10.map 100 100 1 25 38 72 69.3553 +17 room-100-10.map 100 100 49 75 35 22 68.6985 +17 room-100-10.map 100 100 31 81 75 97 71.1127 +17 room-100-10.map 100 100 38 82 96 65 69.0416 +17 room-100-10.map 100 100 31 17 75 51 71.9411 +17 room-100-10.map 100 100 69 22 24 48 71.0416 +18 room-100-10.map 100 100 56 36 5 52 73.2843 +18 room-100-10.map 100 100 56 85 16 54 75.2843 +18 room-100-10.map 100 100 51 86 69 26 75.6985 +18 room-100-10.map 100 100 43 17 17 38 73.7696 +18 room-100-10.map 100 100 11 69 57 49 73.799 +18 room-100-10.map 100 100 6 39 16 97 72.8701 +18 room-100-10.map 100 100 72 61 13 43 74.6985 +18 room-100-10.map 100 100 97 69 47 36 72.4558 +18 room-100-10.map 100 100 81 28 92 93 74.9706 +18 room-100-10.map 100 100 5 38 52 65 75.3553 +19 room-100-10.map 100 100 44 76 71 25 79.1127 +19 room-100-10.map 100 100 31 43 4 97 77.2843 +19 room-100-10.map 100 100 53 96 88 37 79.9411 +19 room-100-10.map 100 100 14 96 47 41 79.9411 +19 room-100-10.map 100 100 98 97 47 63 78.598 +19 room-100-10.map 100 100 49 44 11 89 77.2843 +19 room-100-10.map 100 100 23 36 17 98 79.1127 +19 room-100-10.map 100 100 38 16 51 78 76.3553 +19 room-100-10.map 100 100 85 64 36 21 79.9411 +19 room-100-10.map 100 100 4 26 53 28 76.4558 +20 room-100-10.map 100 100 39 91 88 47 82.1127 +20 room-100-10.map 100 100 63 21 95 81 83.6985 +20 room-100-10.map 100 100 63 89 72 26 82.7696 +20 room-100-10.map 100 100 91 45 44 96 83.598 +20 room-100-10.map 100 100 99 88 99 15 82.9411 +20 room-100-10.map 100 100 9 25 34 89 81.0416 +20 room-100-10.map 100 100 77 72 19 73 83.0416 +20 room-100-10.map 100 100 52 16 13 45 81.6985 +20 room-100-10.map 100 100 25 95 46 31 82.6985 +20 room-100-10.map 100 100 19 23 43 81 81.9411 +21 room-100-10.map 100 100 72 71 37 14 84.5269 +21 room-100-10.map 100 100 86 75 93 3 85.2843 +21 room-100-10.map 100 100 83 61 15 86 85.1838 +21 room-100-10.map 100 100 75 98 55 32 85.3553 +21 room-100-10.map 100 100 63 22 91 86 87.1127 +21 room-100-10.map 100 100 43 25 9 62 86.9411 +21 room-100-10.map 100 100 61 55 78 15 84.9411 +21 room-100-10.map 100 100 72 79 33 28 84.2843 +21 room-100-10.map 100 100 79 55 39 7 86.5269 +21 room-100-10.map 100 100 67 62 9 25 87.0416 +22 room-100-10.map 100 100 92 14 54 71 88.8406 +22 room-100-10.map 100 100 77 67 5 96 90.3553 +22 room-100-10.map 100 100 65 78 2 36 90.9411 +22 room-100-10.map 100 100 71 1 79 63 88.2843 +22 room-100-10.map 100 100 78 22 44 83 90.3553 +22 room-100-10.map 100 100 94 46 24 46 88.7696 +22 room-100-10.map 100 100 68 7 24 69 91.598 +22 room-100-10.map 100 100 64 57 2 72 91.8701 +22 room-100-10.map 100 100 87 76 52 12 89.7696 +22 room-100-10.map 100 100 76 54 0 49 90.0122 +23 room-100-10.map 100 100 4 35 77 29 94.9411 +23 room-100-10.map 100 100 58 14 98 75 93.5269 +23 room-100-10.map 100 100 22 96 99 81 93.9411 +23 room-100-10.map 100 100 89 28 47 94 92.1838 +23 room-100-10.map 100 100 79 56 5 87 95.1838 +23 room-100-10.map 100 100 59 67 89 9 92.2843 +23 room-100-10.map 100 100 8 59 76 35 94.7696 +23 room-100-10.map 100 100 75 19 33 49 95.8406 +23 room-100-10.map 100 100 61 47 13 72 94.2548 +23 room-100-10.map 100 100 15 42 81 75 95.7696 +24 room-100-10.map 100 100 7 11 44 82 98.7696 +24 room-100-10.map 100 100 35 1 95 27 96.4264 +24 room-100-10.map 100 100 92 28 24 50 96.669 +24 room-100-10.map 100 100 62 96 99 24 98.6985 +24 room-100-10.map 100 100 62 1 87 76 98.5269 +24 room-100-10.map 100 100 18 31 62 98 99.669 +24 room-100-10.map 100 100 33 57 96 97 97.7696 +24 room-100-10.map 100 100 74 95 3 85 99.4264 +24 room-100-10.map 100 100 13 54 93 68 98.8701 +24 room-100-10.map 100 100 67 2 45 81 98.0122 +25 room-100-10.map 100 100 31 89 91 25 103.154 +25 room-100-10.map 100 100 57 5 45 92 100.113 +25 room-100-10.map 100 100 88 39 22 95 103.497 +25 room-100-10.map 100 100 93 81 27 48 101.77 +25 room-100-10.map 100 100 36 8 87 72 101.426 +25 room-100-10.map 100 100 88 17 88 98 102.113 +25 room-100-10.map 100 100 68 4 48 89 101.184 +25 room-100-10.map 100 100 30 81 92 31 103.255 +25 room-100-10.map 100 100 6 87 82 74 100.012 +25 room-100-10.map 100 100 46 88 37 8 101.426 +26 room-100-10.map 100 100 65 54 29 27 106.113 +26 room-100-10.map 100 100 25 38 71 18 107.255 +26 room-100-10.map 100 100 92 47 9 43 104.255 +26 room-100-10.map 100 100 9 22 59 93 106.012 +26 room-100-10.map 100 100 35 13 26 96 107.012 +26 room-100-10.map 100 100 9 65 81 36 107.77 +26 room-100-10.map 100 100 42 83 98 12 105.912 +26 room-100-10.map 100 100 15 74 76 41 104.669 +26 room-100-10.map 100 100 1 62 75 78 107.355 +26 room-100-10.map 100 100 17 91 4 13 106.355 +27 room-100-10.map 100 100 78 48 21 12 110.941 +27 room-100-10.map 100 100 38 3 26 88 111.083 +27 room-100-10.map 100 100 11 51 94 23 110.841 +27 room-100-10.map 100 100 79 1 34 75 110.355 +27 room-100-10.map 100 100 41 15 24 9 109.326 +27 room-100-10.map 100 100 14 98 52 21 110.012 +27 room-100-10.map 100 100 16 89 21 1 110.113 +27 room-100-10.map 100 100 81 99 26 37 110.841 +27 room-100-10.map 100 100 94 94 34 26 111.841 +27 room-100-10.map 100 100 78 58 27 11 111.841 +28 room-100-10.map 100 100 82 5 11 37 115.426 +28 room-100-10.map 100 100 38 11 23 97 112.497 +28 room-100-10.map 100 100 22 24 62 25 112.598 +28 room-100-10.map 100 100 21 14 11 78 112.184 +28 room-100-10.map 100 100 76 98 14 41 114.497 +28 room-100-10.map 100 100 23 84 54 2 112.012 +28 room-100-10.map 100 100 41 1 18 65 113.326 +28 room-100-10.map 100 100 49 1 18 15 112.397 +28 room-100-10.map 100 100 63 92 63 4 115.941 +28 room-100-10.map 100 100 78 46 2 72 112.184 +29 room-100-10.map 100 100 8 87 47 12 116.569 +29 room-100-10.map 100 100 88 24 13 65 118.669 +29 room-100-10.map 100 100 91 38 15 86 118.569 +29 room-100-10.map 100 100 95 5 67 97 117.841 +29 room-100-10.map 100 100 22 24 36 98 118.184 +29 room-100-10.map 100 100 88 82 4 35 118.841 +29 room-100-10.map 100 100 31 87 99 14 116.397 +29 room-100-10.map 100 100 37 4 9 68 116.426 +29 room-100-10.map 100 100 2 17 76 64 118.255 +29 room-100-10.map 100 100 62 13 18 95 119.941 +30 room-100-10.map 100 100 86 29 15 76 122.326 +30 room-100-10.map 100 100 24 23 65 75 120.598 +30 room-100-10.map 100 100 7 64 78 95 122.326 +30 room-100-10.map 100 100 12 92 41 9 120.811 +30 room-100-10.map 100 100 77 96 6 65 121.154 +30 room-100-10.map 100 100 13 8 84 48 123.426 +30 room-100-10.map 100 100 72 86 1 28 121.326 +30 room-100-10.map 100 100 59 91 79 11 123.012 +30 room-100-10.map 100 100 22 22 34 5 122.841 +30 room-100-10.map 100 100 98 27 6 21 123.74 +31 room-100-10.map 100 100 98 2 14 34 126.083 +31 room-100-10.map 100 100 87 14 13 28 125.497 +31 room-100-10.map 100 100 45 7 16 97 124.64 +31 room-100-10.map 100 100 61 91 71 8 127.184 +31 room-100-10.map 100 100 97 86 15 61 124.598 +31 room-100-10.map 100 100 92 82 9 28 124.841 +31 room-100-10.map 100 100 18 82 95 22 126.397 +31 room-100-10.map 100 100 8 6 53 3 124.426 +31 room-100-10.map 100 100 79 0 6 51 127.012 +31 room-100-10.map 100 100 26 11 86 66 124.255 +32 room-100-10.map 100 100 4 64 81 95 130.811 +32 room-100-10.map 100 100 21 9 85 57 131.598 +32 room-100-10.map 100 100 89 88 8 22 129.083 +32 room-100-10.map 100 100 73 84 25 14 129.497 +32 room-100-10.map 100 100 12 79 77 26 130.326 +32 room-100-10.map 100 100 3 76 32 1 129.497 +32 room-100-10.map 100 100 95 21 15 95 129.397 +32 room-100-10.map 100 100 7 87 66 6 131.983 +32 room-100-10.map 100 100 72 15 17 23 129.569 +32 room-100-10.map 100 100 86 23 14 72 130.983 +33 room-100-10.map 100 100 96 93 1 47 134.74 +33 room-100-10.map 100 100 9 51 85 6 133.669 +33 room-100-10.map 100 100 21 24 81 29 132.497 +33 room-100-10.map 100 100 15 4 76 86 134.012 +33 room-100-10.map 100 100 8 84 96 22 134.225 +33 room-100-10.map 100 100 7 77 94 37 135.468 +33 room-100-10.map 100 100 94 23 6 83 133.64 +33 room-100-10.map 100 100 24 17 87 84 135.255 +33 room-100-10.map 100 100 87 65 5 6 132.598 +33 room-100-10.map 100 100 72 9 19 69 132.841 +34 room-100-10.map 100 100 37 94 82 1 138.912 +34 room-100-10.map 100 100 62 94 23 26 137.811 +34 room-100-10.map 100 100 67 5 7 82 136.397 +34 room-100-10.map 100 100 6 17 98 67 138.669 +34 room-100-10.map 100 100 87 57 5 19 136.083 +34 room-100-10.map 100 100 68 6 5 96 138.397 +34 room-100-10.map 100 100 67 98 25 22 137.154 +34 room-100-10.map 100 100 94 24 13 72 136.64 +34 room-100-10.map 100 100 17 69 96 93 139.426 +34 room-100-10.map 100 100 25 26 84 58 136.255 +35 room-100-10.map 100 100 99 77 24 19 140.497 +35 room-100-10.map 100 100 87 17 15 84 140.882 +35 room-100-10.map 100 100 3 89 98 17 143.468 +35 room-100-10.map 100 100 25 88 72 19 143.64 +35 room-100-10.map 100 100 19 7 99 72 142.012 +35 room-100-10.map 100 100 12 66 84 11 141.326 +35 room-100-10.map 100 100 9 6 92 77 142.912 +35 room-100-10.map 100 100 19 17 96 6 141.154 +35 room-100-10.map 100 100 97 15 13 5 142.569 +35 room-100-10.map 100 100 96 2 2 22 143.397 +36 room-100-10.map 100 100 7 4 80 7 145.74 +36 room-100-10.map 100 100 97 28 23 27 146.054 +36 room-100-10.map 100 100 24 18 95 88 144.74 +36 room-100-10.map 100 100 2 47 92 2 144.64 +36 room-100-10.map 100 100 95 79 24 22 147.74 +36 room-100-10.map 100 100 94 12 4 88 147.882 +36 room-100-10.map 100 100 2 69 91 19 146.74 +36 room-100-10.map 100 100 4 11 73 12 146.569 +36 room-100-10.map 100 100 18 12 85 18 144.397 +36 room-100-10.map 100 100 18 3 97 81 147.912 +37 room-100-10.map 100 100 81 8 18 79 149.397 +37 room-100-10.map 100 100 22 9 76 98 151.569 +37 room-100-10.map 100 100 93 17 1 82 149.125 +37 room-100-10.map 100 100 86 86 3 4 150.74 +37 room-100-10.map 100 100 15 3 72 98 149.497 +37 room-100-10.map 100 100 87 13 8 84 151.296 +37 room-100-10.map 100 100 61 83 22 1 148.74 +37 room-100-10.map 100 100 83 89 28 2 150.569 +37 room-100-10.map 100 100 22 21 87 86 148.912 +37 room-100-10.map 100 100 78 12 6 5 148.154 +38 room-100-10.map 100 100 5 72 88 18 153.811 +38 room-100-10.map 100 100 9 87 97 2 152.054 +38 room-100-10.map 100 100 89 14 3 18 153.882 +38 room-100-10.map 100 100 72 11 25 28 155.983 +38 room-100-10.map 100 100 23 29 99 33 153.054 +38 room-100-10.map 100 100 87 7 3 72 153.326 +38 room-100-10.map 100 100 7 2 76 95 155.983 +38 room-100-10.map 100 100 77 14 9 0 153.74 +38 room-100-10.map 100 100 5 3 76 95 155.811 +38 room-100-10.map 100 100 14 4 87 96 153.569 +39 room-100-10.map 100 100 5 79 95 6 159.125 +39 room-100-10.map 100 100 96 9 21 25 158.64 +39 room-100-10.map 100 100 72 18 4 6 158.225 +39 room-100-10.map 100 100 88 9 4 85 158.468 +39 room-100-10.map 100 100 83 91 4 19 157.225 +39 room-100-10.map 100 100 28 21 93 97 159.326 +39 room-100-10.map 100 100 17 4 96 93 156.912 +39 room-100-10.map 100 100 27 8 83 96 159.054 +39 room-100-10.map 100 100 25 26 96 87 157.983 +39 room-100-10.map 100 100 88 6 15 76 159.468 +40 room-100-10.map 100 100 7 93 74 14 162.125 +40 room-100-10.map 100 100 3 79 92 5 161.368 +40 room-100-10.map 100 100 6 99 77 17 163.711 +40 room-100-10.map 100 100 79 18 14 74 161.125 +40 room-100-10.map 100 100 8 97 75 16 160.711 +40 room-100-10.map 100 100 74 19 17 97 160.296 +40 room-100-10.map 100 100 27 25 91 4 161.468 +40 room-100-10.map 100 100 95 2 6 74 162.397 +40 room-100-10.map 100 100 94 3 25 23 160.64 +40 room-100-10.map 100 100 81 14 3 76 161.64 +41 room-100-10.map 100 100 94 3 23 28 165.882 +41 room-100-10.map 100 100 91 97 7 4 164.74 +41 room-100-10.map 100 100 3 9 98 92 167.74 +41 room-100-10.map 100 100 99 1 26 25 164.054 +41 room-100-10.map 100 100 87 4 1 93 167.125 +41 room-100-10.map 100 100 88 4 4 93 165.125 +41 room-100-10.map 100 100 7 99 72 19 166.782 +41 room-100-10.map 100 100 94 1 7 79 166.539 +41 room-100-10.map 100 100 91 3 2 71 164.64 +41 room-100-10.map 100 100 7 1 95 2 165.811 +42 room-100-10.map 100 100 22 24 99 98 170.054 +42 room-100-10.map 100 100 98 99 28 4 169.468 +42 room-100-10.map 100 100 0 4 92 97 170.74 +42 room-100-10.map 100 100 91 1 2 8 169.054 +42 room-100-10.map 100 100 2 6 98 92 168.326 +42 room-100-10.map 100 100 22 26 99 98 170.882 +42 room-100-10.map 100 100 5 2 98 99 171.64 +42 room-100-10.map 100 100 23 24 98 98 168.64 +42 room-100-10.map 100 100 97 96 1 7 169.569 +42 room-100-10.map 100 100 88 4 1 96 169.368 diff --git a/JPSPlusGoalBounding/PathfindingNode.h b/JPSPlusGoalBounding/PathfindingNode.h new file mode 100644 index 0000000..1a3f156 --- /dev/null +++ b/JPSPlusGoalBounding/PathfindingNode.h @@ -0,0 +1,82 @@ +/* + * PathfindingNode.h + * + * Copyright (c) 2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "stdafx.h" + +struct PathfindingNode +{ +public: + PathfindingNode* m_parent; + short m_row, m_col; + unsigned int m_givenCost; + unsigned int m_finalCost; + unsigned int m_iteration; + unsigned char m_directionFromParent; + + enum PathfindingNodeStatus + { + OnNone, + OnOpen, + OnClosed + }; + + unsigned char m_listStatus; +}; + +struct DijkstraPathfindingNode +{ +public: + DijkstraPathfindingNode* m_parent; + short m_row, m_col; + unsigned int m_givenCost; + unsigned int m_iteration; + unsigned char m_directionFromStart; + unsigned char m_directionFromParent; + unsigned char m_blockedDirectionBitfield; // highest bit [DownLeft, Left, UpLeft, Up, UpRight, Right, DownRight, Down] lowest bit + + enum PathfindingNodeStatus + { + OnNone, + OnOpen, + OnClosed + }; + + unsigned char m_listStatus; +}; diff --git a/JPSPlusGoalBounding/PrecomputeMap.cpp b/JPSPlusGoalBounding/PrecomputeMap.cpp new file mode 100644 index 0000000..b9c2059 --- /dev/null +++ b/JPSPlusGoalBounding/PrecomputeMap.cpp @@ -0,0 +1,691 @@ +/* + * PrecomputeMap.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "PrecomputeMap.h" +#include "DijkstraFloodfill.h" +#include "JPSPlus.h" +#include + +using std::ifstream; +using std::ofstream; + +//#define FILE_FORMAT_ASCII +#define INVALID_GOAL_BOUNDS -1 + +PrecomputeMap::PrecomputeMap(int width, int height, std::vector map) +: m_mapCreated(false), m_width(width), m_height(height), m_map(map) +{ +} + +PrecomputeMap::~PrecomputeMap() +{ +} + +DistantJumpPoints** PrecomputeMap::CalculateMap() +{ + m_mapCreated = true; + + InitArray(m_jumpPointMap, m_width, m_height); + CalculateJumpPointMap(); + + InitArray(m_distantJumpPointMap, m_width, m_height); + CalculateDistantJumpPointMap(); + + // Destroy the m_jumpPointMap since it isn't needed for the search + DestroyArray(m_jumpPointMap); + + // Calculate Goal Bounds + //CalculateGoalBoundingDEPRECATED(); + CalculateGoalBounding(); + + return m_distantJumpPointMap; +} + +void PrecomputeMap::SaveMap(const char *filename) +{ +#ifdef FILE_FORMAT_ASCII + ofstream file(filename); + + for (int r = 0; r < m_height; r++) + { + for (int c = 0; c < m_width; c++) + { + DistantJumpPoints* jumpPoints = &m_distantJumpPointMap[r][c]; + + for (int i = 0; i < 8; i++) + { + file << (int)jumpPoints->jumpDistance[i] << "\t"; + } + for (int dir = 0; dir < 8; dir++) + { + for (int minMaxIndex = 0; minMaxIndex < 4; minMaxIndex++) + { + file << (int)m_goalBoundsMap[r][c].bounds[dir][minMaxIndex] << "\t"; + } + } + file << std::endl; + } + file << std::endl; + } +#else + ofstream file(filename, std::ios::out | std::ios::binary); + + for (int r = 0; r < m_height; r++) + { + for (int c = 0; c < m_width; c++) + { + if (IsWall(r, c)) + { + // Don't save data if a wall + continue; + } + + // Save Jump Distances + DistantJumpPoints* jumpPoints = &m_distantJumpPointMap[r][c]; + + for (int i = 0; i < 8; i++) + { + file.write((char*)&jumpPoints->jumpDistance[i], 2); + } + + // Save Goal Bounds + for (int dir = 0; dir < 8; dir++) + { + if ((m_goalBoundsMap[r][c].bounds[dir][MinRow] > + m_goalBoundsMap[r][c].bounds[dir][MaxRow]) && + (m_goalBoundsMap[r][c].bounds[dir][MinCol] > + m_goalBoundsMap[r][c].bounds[dir][MaxCol])) + { + // Use INVALID_GOAL_BOUNDS to represent all four values for compression + short value = INVALID_GOAL_BOUNDS; + file.write((char*)&value, 2); + } + else + { + for (int minMaxIndex = 0; minMaxIndex < 4; minMaxIndex++) + { + short value = m_goalBoundsMap[r][c].bounds[dir][minMaxIndex]; + file.write((char*)&value, 2); + } + } + } + } + } +#endif +} + +void PrecomputeMap::LoadMap(const char *filename) +{ + m_mapCreated = true; + +#ifdef FILE_FORMAT_ASCII + ifstream file(filename, std::ios::in); + + InitArray(m_jumpDistancesAndGoalBoundsMap, m_width, m_height); + + for (int r = 0; r < m_height; r++) + { + for (int c = 0; c < m_width; c++) + { + JumpDistancesAndGoalBounds* map = &m_jumpDistancesAndGoalBoundsMap[r][c]; + map->blockedDirectionBitfield = 0; + + for (int i = 0; i < 8; i++) + { + file >> map->jumpDistance[i]; + } + for (int i = 0; i < 8; i++) + { + // Detect invalid movement from jump distances + // (jump distance of zero is invalid movement) + if(map->jumpDistance[i] == 0) + { + map->blockedDirectionBitfield |= (1 << i); + } + } + for (int dir = 0; dir < 8; dir++) + { + file >> m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinRow]; + file >> m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxRow]; + file >> m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinCol]; + file >> m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxCol]; + } + + } + } +#else + ifstream file(filename, std::ios::in | std::ios::binary); + + InitArray(m_jumpDistancesAndGoalBoundsMap, m_width, m_height); + + for (int r = 0; r < m_height; r++) + { + for (int c = 0; c < m_width; c++) + { + if (IsWall(r, c)) + { + // Don't load data if a wall + continue; + } + + JumpDistancesAndGoalBounds* map = &m_jumpDistancesAndGoalBoundsMap[r][c]; + map->blockedDirectionBitfield = 0; + + // Load Jump Distances + for (int i = 0; i < 8; i++) + { + file.read((char*)&map->jumpDistance[i], 2); + } + + // Fabricate wall bitfield for each node + for (int i = 0; i < 8; i++) + { + // Jump distance of zero is invalid movement and means a wall + if(map->jumpDistance[i] == 0) + { + map->blockedDirectionBitfield |= (1 << i); + } + } + + // Load Goal Bounds + for (int dir = 0; dir < 8; dir++) + { + short value; + file.read((char*)&value, 2); + + if(value == INVALID_GOAL_BOUNDS) + { + m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinRow] = m_height; + m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxRow] = 0; + m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinCol] = m_width; + m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxCol] = 0; + } + else + { + m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinRow] = value; + file.read((char*)&m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxRow], 2); + file.read((char*)&m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MinCol], 2); + file.read((char*)&m_jumpDistancesAndGoalBoundsMap[r][c].bounds[dir][MaxCol], 2); + } + } + + } + } +#endif +} + +template +void PrecomputeMap::InitArray(T**& t, int width, int height) +{ + t = new T*[height]; + for (int i = 0; i < height; ++i) + { + t[i] = new T[width]; + memset(t[i], 0, sizeof(T)*width); + } +} + +template +void PrecomputeMap::DestroyArray(T**& t) +{ + for (int i = 0; i < m_height; ++i) + delete[] t[i]; + delete[] t; + + t = 0; +} + +void PrecomputeMap::CalculateJumpPointMap() +{ + for (int r = 0; r < m_height; ++r) + { + for (int c = 0; c < m_width; ++c) + { + if (m_map[c + (r * m_width)]) + { + if (IsJumpPoint(r, c, 1, 0)) + { + m_jumpPointMap[r][c] |= MovingDown; + } + if (IsJumpPoint(r, c, -1, 0)) + { + m_jumpPointMap[r][c] |= MovingUp; + } + if (IsJumpPoint(r, c, 0, 1)) + { + m_jumpPointMap[r][c] |= MovingRight; + } + if (IsJumpPoint(r, c, 0, -1)) + { + m_jumpPointMap[r][c] |= MovingLeft; + } + } + } + } +} + +bool PrecomputeMap::IsJumpPoint(int r, int c, int rowDir, int colDir) +{ + return + IsEmpty(r - rowDir, c - colDir) && // Parent not a wall (not necessary) + ((IsEmpty(r + colDir, c + rowDir) && // 1st forced neighbor + IsWall(r - rowDir + colDir, c - colDir + rowDir)) || // 1st forced neighbor (continued) + ((IsEmpty(r - colDir, c - rowDir) && // 2nd forced neighbor + IsWall(r - rowDir - colDir, c - colDir - rowDir)))); // 2nd forced neighbor (continued) +} + +inline bool PrecomputeMap::IsEmpty(int r, int c) +{ + unsigned int colBoundsCheck = c; + unsigned int rowBoundsCheck = r; + if (colBoundsCheck < (unsigned int)m_width && rowBoundsCheck < (unsigned int)m_height) + { + return m_map[c + (r * m_width)]; + } + else + { + return false; + } +} + +inline bool PrecomputeMap::IsWall(int r, int c) +{ + unsigned int colBoundsCheck = c; + unsigned int rowBoundsCheck = r; + if (colBoundsCheck < (unsigned int)m_width && rowBoundsCheck < (unsigned int)m_height) + { + return !m_map[c + (r * m_width)]; + } + else + { + return true; + } +} + +void PrecomputeMap::CalculateDistantJumpPointMap() +{ + // Calculate distant jump points (Left and Right) + for (int r = 0; r < m_height; ++r) + { + { + int countMovingLeft = -1; + bool jumpPointLastSeen = false; + for (int c = 0; c < m_width; ++c) + { + if (IsWall(r, c)) + { + countMovingLeft = -1; + jumpPointLastSeen = false; + m_distantJumpPointMap[r][c].jumpDistance[Left] = 0; + continue; + } + + countMovingLeft++; + + if (jumpPointLastSeen) + { + m_distantJumpPointMap[r][c].jumpDistance[Left] = countMovingLeft; + } + else // Wall last seen + { + m_distantJumpPointMap[r][c].jumpDistance[Left] = -countMovingLeft; + } + + if ((m_jumpPointMap[r][c] & MovingLeft) > 0) + { + countMovingLeft = 0; + jumpPointLastSeen = true; + } + } + } + + { + int countMovingRight = -1; + bool jumpPointLastSeen = false; + for (int c = m_width - 1; c >= 0; --c) + { + if (IsWall(r, c)) + { + countMovingRight = -1; + jumpPointLastSeen = false; + m_distantJumpPointMap[r][c].jumpDistance[Right] = 0; + continue; + } + + countMovingRight++; + + if (jumpPointLastSeen) + { + m_distantJumpPointMap[r][c].jumpDistance[Right] = countMovingRight; + } + else // Wall last seen + { + m_distantJumpPointMap[r][c].jumpDistance[Right] = -countMovingRight; + } + + if ((m_jumpPointMap[r][c] & MovingRight) > 0) + { + countMovingRight = 0; + jumpPointLastSeen = true; + } + } + } + } + + // Calculate distant jump points (Up and Down) + for (int c = 0; c < m_width; ++c) + { + { + int countMovingUp = -1; + bool jumpPointLastSeen = false; + for (int r = 0; r < m_height; ++r) + { + if (IsWall(r, c)) + { + countMovingUp = -1; + jumpPointLastSeen = false; + m_distantJumpPointMap[r][c].jumpDistance[Up] = 0; + continue; + } + + countMovingUp++; + + if (jumpPointLastSeen) + { + m_distantJumpPointMap[r][c].jumpDistance[Up] = countMovingUp; + } + else // Wall last seen + { + m_distantJumpPointMap[r][c].jumpDistance[Up] = -countMovingUp; + } + + if ((m_jumpPointMap[r][c] & MovingUp) > 0) + { + countMovingUp = 0; + jumpPointLastSeen = true; + } + } + } + + { + int countMovingDown = -1; + bool jumpPointLastSeen = false; + for (int r = m_height - 1; r >= 0; --r) + { + if (IsWall(r, c)) + { + countMovingDown = -1; + jumpPointLastSeen = false; + m_distantJumpPointMap[r][c].jumpDistance[Down] = 0; + continue; + } + + countMovingDown++; + + if (jumpPointLastSeen) + { + m_distantJumpPointMap[r][c].jumpDistance[Down] = countMovingDown; + } + else // Wall last seen + { + m_distantJumpPointMap[r][c].jumpDistance[Down] = -countMovingDown; + } + + if ((m_jumpPointMap[r][c] & MovingDown) > 0) + { + countMovingDown = 0; + jumpPointLastSeen = true; + } + } + } + } + + // Calculate distant jump points (Diagonally UpLeft and UpRight) + for (int r = 0; r < m_height; ++r) + { + for (int c = 0; c < m_width; ++c) + { + if (IsEmpty(r, c)) + { + if (r == 0 || c == 0 || (IsWall(r - 1, c) || IsWall(r, c - 1) || IsWall(r - 1, c - 1))) + { + // Wall one away + m_distantJumpPointMap[r][c].jumpDistance[UpLeft] = 0; + } + else if (IsEmpty(r - 1, c) && IsEmpty(r, c - 1) && + (m_distantJumpPointMap[r - 1][c - 1].jumpDistance[Up] > 0 || + m_distantJumpPointMap[r - 1][c - 1].jumpDistance[Left] > 0)) + { + // Diagonal one away + m_distantJumpPointMap[r][c].jumpDistance[UpLeft] = 1; + } + else + { + // Increment from last + int jumpDistance = m_distantJumpPointMap[r - 1][c - 1].jumpDistance[UpLeft]; + + if (jumpDistance > 0) + { + m_distantJumpPointMap[r][c].jumpDistance[UpLeft] = 1 + jumpDistance; + } + else //if( jumpDistance <= 0 ) + { + m_distantJumpPointMap[r][c].jumpDistance[UpLeft] = -1 + jumpDistance; + } + } + + + if (r == 0 || c == m_width - 1 || (IsWall(r - 1, c) || IsWall(r, c + 1) || IsWall(r - 1, c + 1))) + { + // Wall one away + m_distantJumpPointMap[r][c].jumpDistance[UpRight] = 0; + } + else if (IsEmpty(r - 1, c) && IsEmpty(r, c + 1) && + (m_distantJumpPointMap[r - 1][c + 1].jumpDistance[Up] > 0 || + m_distantJumpPointMap[r - 1][c + 1].jumpDistance[Right] > 0)) + { + // Diagonal one away + m_distantJumpPointMap[r][c].jumpDistance[UpRight] = 1; + } + else + { + // Increment from last + int jumpDistance = m_distantJumpPointMap[r - 1][c + 1].jumpDistance[UpRight]; + + if (jumpDistance > 0) + { + m_distantJumpPointMap[r][c].jumpDistance[UpRight] = 1 + jumpDistance; + } + else //if( jumpDistance <= 0 ) + { + m_distantJumpPointMap[r][c].jumpDistance[UpRight] = -1 + jumpDistance; + } + } + } + } + } + + // Calculate distant jump points (Diagonally DownLeft and DownRight) + for (int r = m_height - 1; r >= 0; --r) + { + for (int c = 0; c < m_width; ++c) + { + if (IsEmpty(r, c)) + { + if (r == m_height - 1 || c == 0 || + (IsWall(r + 1, c) || IsWall(r, c - 1) || IsWall(r + 1, c - 1))) + { + // Wall one away + m_distantJumpPointMap[r][c].jumpDistance[DownLeft] = 0; + } + else if (IsEmpty(r + 1, c) && IsEmpty(r, c - 1) && + (m_distantJumpPointMap[r + 1][c - 1].jumpDistance[Down] > 0 || + m_distantJumpPointMap[r + 1][c - 1].jumpDistance[Left] > 0)) + { + // Diagonal one away + m_distantJumpPointMap[r][c].jumpDistance[DownLeft] = 1; + } + else + { + // Increment from last + int jumpDistance = m_distantJumpPointMap[r + 1][c - 1].jumpDistance[DownLeft]; + + if (jumpDistance > 0) + { + m_distantJumpPointMap[r][c].jumpDistance[DownLeft] = 1 + jumpDistance; + } + else //if( jumpDistance <= 0 ) + { + m_distantJumpPointMap[r][c].jumpDistance[DownLeft] = -1 + jumpDistance; + } + } + + + if (r == m_height - 1 || c == m_width - 1 || (IsWall(r + 1, c) || IsWall(r, c + 1) || IsWall(r + 1, c + 1))) + { + // Wall one away + m_distantJumpPointMap[r][c].jumpDistance[DownRight] = 0; + } + else if (IsEmpty(r + 1, c) && IsEmpty(r, c + 1) && + (m_distantJumpPointMap[r + 1][c + 1].jumpDistance[Down] > 0 || + m_distantJumpPointMap[r + 1][c + 1].jumpDistance[Right] > 0)) + { + // Diagonal one away + m_distantJumpPointMap[r][c].jumpDistance[DownRight] = 1; + } + else + { + // Increment from last + int jumpDistance = m_distantJumpPointMap[r + 1][c + 1].jumpDistance[DownRight]; + + if (jumpDistance > 0) + { + m_distantJumpPointMap[r][c].jumpDistance[DownRight] = 1 + jumpDistance; + } + else //if( jumpDistance <= 0 ) + { + m_distantJumpPointMap[r][c].jumpDistance[DownRight] = -1 + jumpDistance; + } + } + } + } + } +} + +void PrecomputeMap::CalculateGoalBounding() +{ + printf("Goal Bounding Preprocessing\n"); + + DijkstraFloodfill* dijkstra = new DijkstraFloodfill(m_width, m_height, m_map, m_distantJumpPointMap); + + InitArray(m_goalBoundsMap, m_width, m_height); + for (int r = 0; r < m_height; ++r) + { + for (int c = 0; c < m_width; ++c) + { + for (int dir = 0; dir < 8; ++dir) + { + m_goalBoundsMap[r][c].bounds[dir][MinRow] = m_height; + m_goalBoundsMap[r][c].bounds[dir][MaxRow] = 0; + m_goalBoundsMap[r][c].bounds[dir][MinCol] = m_width; + m_goalBoundsMap[r][c].bounds[dir][MaxCol] = 0; + } + } + } + + for (int startRow = 0; startRow < m_height; ++startRow) + { + printf("Row: %d\n", startRow); + + for (int startCol = 0; startCol < m_width; ++startCol) + { + if (IsWall(startRow, startCol)) + { + continue; + } + + dijkstra->Flood(startRow, startCol); + int currentIteration = dijkstra->GetCurrentInteration(); + + for (int r = 0; r < m_height; ++r) + { + for (int c = 0; c < m_width; ++c) + { + if (IsWall(r, c)) + { + continue; + } + + int iteration = dijkstra->m_mapNodes[r][c].m_iteration; + unsigned char status = dijkstra->m_mapNodes[r][c].m_listStatus; + int dir = dijkstra->m_mapNodes[r][c].m_directionFromStart; + + if (iteration == currentIteration && + status == PathfindingNode::OnClosed && + dir >= 0 && dir <= 7) + { + int row = dijkstra->m_mapNodes[r][c].m_row; + int col = dijkstra->m_mapNodes[r][c].m_col; + + if (m_goalBoundsMap[startRow][startCol].bounds[dir][MinRow] > row) + { + m_goalBoundsMap[startRow][startCol].bounds[dir][MinRow] = row; + } + if (m_goalBoundsMap[startRow][startCol].bounds[dir][MaxRow] < row) + { + m_goalBoundsMap[startRow][startCol].bounds[dir][MaxRow] = row; + } + if (m_goalBoundsMap[startRow][startCol].bounds[dir][MinCol] > col) + { + m_goalBoundsMap[startRow][startCol].bounds[dir][MinCol] = col; + } + if (m_goalBoundsMap[startRow][startCol].bounds[dir][MaxCol] < col) + { + m_goalBoundsMap[startRow][startCol].bounds[dir][MaxCol] = col; + } + } + } + } + } + } + + delete dijkstra; +} + diff --git a/JPSPlusGoalBounding/PrecomputeMap.h b/JPSPlusGoalBounding/PrecomputeMap.h new file mode 100644 index 0000000..e6bed7a --- /dev/null +++ b/JPSPlusGoalBounding/PrecomputeMap.h @@ -0,0 +1,121 @@ +/* + * PrecomputeMap.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include + +enum ArrayDirections +{ + Down = 0, + DownRight = 1, + Right = 2, + UpRight = 3, + Up = 4, + UpLeft = 5, + Left = 6, + DownLeft = 7, + All = 8 +}; + +enum GoalBoundsEnum +{ + MinRow = 0, + MaxRow = 1, + MinCol = 2, + MaxCol = 3 +}; + +struct DistantJumpPoints +{ + short jumpDistance[8]; +}; + +struct GoalBounds +{ + short bounds[8][4]; +}; + +struct JumpDistancesAndGoalBounds +{ + unsigned char blockedDirectionBitfield; // highest bit [DownLeft, Left, UpLeft, Up, UpRight, Right, DownRight, Down] lowest bit + short jumpDistance[8]; + short bounds[8][4]; +}; + +class PrecomputeMap +{ +public: + PrecomputeMap(int width, int height, std::vector map); + ~PrecomputeMap(); + + DistantJumpPoints** CalculateMap(); + void SaveMap(const char *filename); + void LoadMap(const char *filename); + JumpDistancesAndGoalBounds** GetPreprocessedMap() { return m_jumpDistancesAndGoalBoundsMap; } + void ReleaseMap() { if (m_mapCreated) DestroyArray(m_distantJumpPointMap); } + +protected: + bool m_mapCreated; + int m_width; + int m_height; + std::vector m_map; + unsigned char** m_jumpPointMap; + DistantJumpPoints** m_distantJumpPointMap; + GoalBounds** m_goalBoundsMap; + JumpDistancesAndGoalBounds** m_jumpDistancesAndGoalBoundsMap; + + template void InitArray(T**& t, int width, int height); + template void DestroyArray(T**& t); + + void CalculateJumpPointMap(); + void CalculateDistantJumpPointMap(); + void CalculateGoalBounding(); + bool IsJumpPoint(int r, int c, int rowDir, int colDir); + bool IsEmpty(int r, int c); + bool IsWall(int r, int c); + + enum BitfieldDirections + { + MovingDown = 1 << 0, + MovingRight = 1 << 1, + MovingUp = 1 << 2, + MovingLeft = 1 << 3, + }; +}; + diff --git a/JPSPlusGoalBounding/ScenarioLoader.cpp b/JPSPlusGoalBounding/ScenarioLoader.cpp new file mode 100644 index 0000000..5440d56 --- /dev/null +++ b/JPSPlusGoalBounding/ScenarioLoader.cpp @@ -0,0 +1,84 @@ +/* + * scenarioLoader.cpp + * hog + * + * Created by Renee Jansen on 5/2/2006 + * + */ + +#include "stdafx.h" +#include +using std::ifstream; +using std::ofstream; + +#include "ScenarioLoader.h" +#include + +/** + * Loads the experiments from the scenario file. + */ +ScenarioLoader::ScenarioLoader(const char* fname) +{ + strncpy(scenName, fname, 1024); + ifstream sfile(fname,std::ios::in); + + float ver; + string first; + sfile>>first; + + // Check if a version number is given + if(first != "version"){ + ver = 0.0; + sfile.seekg(0,std::ios::beg); + } + else{ + sfile>>ver; + } + + int sizeX = 0, sizeY = 0; + int bucket; + string map; + int xs, ys, xg, yg; + double dist; + + // Read in & store experiments + if (ver==0.0){ + while(sfile>>bucket>>map>>xs>>ys>>xg>>yg>>dist) { + Experiment exp(xs,ys,xg,yg,bucket,dist,map); + experiments.push_back(exp); + } + } + else if(ver==1.0){ + while(sfile>>bucket>>map>>sizeX>>sizeY>>xs>>ys>>xg>>yg>>dist){ + Experiment exp(xs,ys,xg,yg,sizeX,sizeY,bucket,dist,map); + experiments.push_back(exp); + } + } + else{ + printf("Invalid version number.\n"); + //assert(0); + } +} + +void ScenarioLoader::Save(const char *fname) +{ +// strncpy(scenName, fname, 1024); + ofstream ofile(fname); + + float ver = 1.0; + ofile<<"version "< +#include +#include +using std::string; + + + +static const int kNoScaling = -1; + +/** + * Experiments stored by the ScenarioLoader class. + */ +class ScenarioLoader; + +class Experiment { +public: + Experiment(int sx,int sy,int gx,int gy,int b, double d, string m) + :startx(sx),starty(sy),goalx(gx),goaly(gy),scaleX(kNoScaling),scaleY(kNoScaling),bucket(b),distance(d),map(m){} + Experiment(int sx,int sy,int gx,int gy,int sizeX, int sizeY,int b, double d, string m) + :startx(sx),starty(sy),goalx(gx),goaly(gy),scaleX(sizeX),scaleY(sizeY),bucket(b),distance(d),map(m){} + int GetStartX() const {return startx;} + int GetStartY() const {return starty;} + int GetGoalX() const {return goalx;} + int GetGoalY() const {return goaly;} + int GetBucket() const {return bucket;} + double GetDistance() const {return distance;} + void GetMapName(char* mymap) const {strcpy(mymap,map.c_str());} + const char *GetMapName() const { return map.c_str(); } + int GetXScale() const {return scaleX;} + int GetYScale() const {return scaleY;} + +private: + friend class ScenarioLoader; + int startx, starty, goalx, goaly; + int scaleX; + int scaleY; + int bucket; + double distance; + string map; +}; + +/** A class which loads and stores scenarios from files. + * Versions currently handled: 0.0 and 1.0 (includes scale). + */ + +class ScenarioLoader{ +public: + ScenarioLoader() { scenName[0] = 0; } + ScenarioLoader(const char *); + void Save(const char *); + int GetNumExperiments(){return experiments.size();} + const char *GetScenarioName() { return scenName; } + Experiment GetNthExperiment(int which) + {return experiments[which];} + void AddExperiment(Experiment which); + void Clear() { experiments.clear(); } +private: + char scenName[1024]; + std::vector experiments; +}; + +#endif diff --git a/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.cpp b/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.cpp new file mode 100644 index 0000000..0010811 --- /dev/null +++ b/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.cpp @@ -0,0 +1,65 @@ +/* + * SimpleUnsortedPriorityQueue.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "StdAfx.h" +#include "SimpleUnsortedPriorityQueue.h" + +PathfindingNode* SimpleUnsortedPriorityQueue::Pop(void) +{ + // Find the cheapest node + unsigned int cheapestNodeCost = m_nodeArray[0]->m_finalCost; + int cheapestNodeIndex = 0; + + for (int i = 1; i < m_nextFreeNode; ++i) + { + if (m_nodeArray[i]->m_finalCost < cheapestNodeCost) + { + cheapestNodeCost = m_nodeArray[i]->m_finalCost; + cheapestNodeIndex = i; + } + } + + // Remember the cheapest node + PathfindingNode* cheapestNode = m_nodeArray[cheapestNodeIndex]; + + // Delete off list (put the last node where this one was) + m_nodeArray[cheapestNodeIndex] = m_nodeArray[--m_nextFreeNode]; + + return cheapestNode; +} diff --git a/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.h b/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.h new file mode 100644 index 0000000..8f0ef84 --- /dev/null +++ b/JPSPlusGoalBounding/SimpleUnsortedPriorityQueue.h @@ -0,0 +1,64 @@ +/* + * SimpleUnsortedPriorityQueue.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "PathfindingNode.h" + +// This priority queue only makes sense when the open list on average contains +// fewer than 10 elements. This is the case for JPS+ with Goal Bounding when +// a fast stack is being used in conjunction with the open list. + +#pragma once +class SimpleUnsortedPriorityQueue +{ +public: + SimpleUnsortedPriorityQueue(int arraySize) : m_nextFreeNode(0) { m_nodeArray = new PathfindingNode*[arraySize]; } + ~SimpleUnsortedPriorityQueue(void) { delete[] m_nodeArray; } + + inline void Reset() { m_nextFreeNode = 0; } + inline bool Empty(void) { return m_nextFreeNode == 0; } + inline void Add(PathfindingNode* node) { m_nodeArray[m_nextFreeNode++] = node; } + PathfindingNode* Pop(void); + +private: + int m_nextFreeNode; + bool m_identical; + PathfindingNode** m_nodeArray; +}; + diff --git a/JPSPlusGoalBounding/Timer.cpp b/JPSPlusGoalBounding/Timer.cpp new file mode 100644 index 0000000..02c687f --- /dev/null +++ b/JPSPlusGoalBounding/Timer.cpp @@ -0,0 +1,53 @@ +/* + * $Id: timer.cpp,v 1.6 2006/11/30 20:33:25 nathanst Exp $ + * + * timer.cpp + * HOG file + * + * Written by Renee Jansen on 08/28/06 + * + * This file is part of HOG. + * + * HOG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * HOG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HOG; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +//#include "UnitSimulation.h" +#include "stdafx.h" +#include "Timer.h" +#include +#include +#include + +Timer::Timer() +{ + QueryPerformanceFrequency(&ticksPerSecond); + startTimeInUS = 0; + elapsedTime = 0; +} + +void Timer::StartTimer() +{ + startTimeInUS = GetHighestResolutionTime(); +} + +double Timer::EndTimer() +{ + double currentTimeInUS = GetHighestResolutionTime(); + double elapsedTimeInUS = currentTimeInUS - startTimeInUS; + elapsedTime = elapsedTimeInUS; + + return elapsedTime; + +} diff --git a/JPSPlusGoalBounding/Timer.h b/JPSPlusGoalBounding/Timer.h new file mode 100644 index 0000000..578b4f7 --- /dev/null +++ b/JPSPlusGoalBounding/Timer.h @@ -0,0 +1,54 @@ +/* + * $Id: timer.h,v 1.5 2006/10/30 17:45:10 nathanst Exp $ + * + * timer.h + * HOG file + * + * Written by Renee Jansen on 08/28/06 + * + * This file is part of HOG. + * + * HOG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * HOG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with HOG; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef TIMER_H +#define TIMER_H + +#include +#include +#include + +class Timer { + +private: + //unsigned int startTimeInMS; + double startTimeInUS; + double elapsedTime; + LARGE_INTEGER ticksPerSecond; + + float getCPUSpeed(); + +public: + Timer(); + ~Timer(){} + + void StartTimer(); + double EndTimer(); + double GetElapsedTime(){return elapsedTime;} + + inline double GetHighestResolutionTime(void) { LARGE_INTEGER qwTime; QueryPerformanceCounter(&qwTime); return((double)qwTime.QuadPart); } +}; + +#endif diff --git a/JPSPlusGoalBounding/UnsortedPriorityQueue.cpp b/JPSPlusGoalBounding/UnsortedPriorityQueue.cpp new file mode 100644 index 0000000..2061165 --- /dev/null +++ b/JPSPlusGoalBounding/UnsortedPriorityQueue.cpp @@ -0,0 +1,128 @@ +/* + * UnsortedPriorityQueue.cpp + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "stdafx.h" +#include "UnsortedPriorityQueue.h" + +//#define TRACK_IDENTICAL_OPTIMIZATION +//#define ALL_NODES_EQUAL_COST // ~40% faster and still results in optimal paths in virtually all cases + +UnsortedPriorityQueue::UnsortedPriorityQueue(int arraySize) +: m_nextFreeNode(0), m_iteration(0) +{ + m_nodeArray = new DijkstraPathfindingNode*[arraySize]; +} + +UnsortedPriorityQueue::~UnsortedPriorityQueue() +{ + delete[] m_nodeArray; +} + +void UnsortedPriorityQueue::Push(DijkstraPathfindingNode* node) +{ + if (m_iteration != node->m_iteration) + { + m_nextFreeNode = 0; + m_identical = true; + m_iteration = node->m_iteration; + } +#ifdef TRACK_IDENTICAL_OPTIMIZATION + else if(m_identical) + { + m_identical = node->m_finalCost == m_nodeArray[0]->m_finalCost; + } + else + { + m_identical = m_nextFreeNode == 0; + } +#endif + + m_nodeArray[m_nextFreeNode++] = node; + +} + +void UnsortedPriorityQueue::Remove(DijkstraPathfindingNode* node) +{ + for (int i = 0; i < m_nextFreeNode; ++i) + { + if (m_nodeArray[i] == node) + { + // Delete off Open list (put last node where this one was) + m_nodeArray[i] = m_nodeArray[--m_nextFreeNode]; + return; + } + } +} + +DijkstraPathfindingNode* UnsortedPriorityQueue::Pop(void) +{ +#ifdef ALL_NODES_EQUAL_COST + // Just pop last node (all nodes are very close to each other in cost) + return m_nodeArray[--m_nextFreeNode]; +#else + +#ifdef TRACK_IDENTICAL_OPTIMIZATION + if(m_identical) + { + return m_nodeArray[--m_nextFreeNode]; + } +#endif + + // Find cheapest node + unsigned int cheapestNodeCostFinal = m_nodeArray[0]->m_givenCost; + int cheapestNodeIndex = 0; + + for (int i = 1; i < m_nextFreeNode; ++i) + { + if (m_nodeArray[i]->m_givenCost < cheapestNodeCostFinal) + { + cheapestNodeCostFinal = m_nodeArray[i]->m_givenCost; + cheapestNodeIndex = i; + } + } + + // Remember cheapest node + DijkstraPathfindingNode* cheapestNode = m_nodeArray[cheapestNodeIndex]; + + // Delete off Open list (put last node where this one was) + m_nodeArray[cheapestNodeIndex] = m_nodeArray[--m_nextFreeNode]; + + return cheapestNode; +#endif +} diff --git a/JPSPlusGoalBounding/UnsortedPriorityQueue.h b/JPSPlusGoalBounding/UnsortedPriorityQueue.h new file mode 100644 index 0000000..b83683b --- /dev/null +++ b/JPSPlusGoalBounding/UnsortedPriorityQueue.h @@ -0,0 +1,67 @@ +/* + * UnsortedPriorityQueue.h + * + * Copyright (c) 2014-2015, Steve Rabin + * All rights reserved. + * + * An explanation of the JPS+ algorithm is contained in Chapter 14 + * of the book Game AI Pro 2, edited by Steve Rabin, CRC Press, 2015. + * A presentation on Goal Bounding titled "JPS+: Over 100x Faster than A*" + * can be found at www.gdcvault.com from the 2015 GDC AI Summit. + * A copy of this code is on the website http://www.gameaipro.com. + * + * If you develop a way to improve this code or make it faster, please + * contact steve.rabin@gmail.com and share your insights. I would + * be equally eager to hear from anyone integrating this code or using + * the Goal Bounding concept in a commercial application or game. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STEVE RABIN ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#include "PathfindingNode.h" + +// This array is dangerous since there are no safeguards if the max size is exceeded. +// However, any method to detect a problem and deal with it gracefully will sacrifice speed. +// In this code base, this is only used by the Dijkstra floodfill for Goal Bounding preprocessing. + +class UnsortedPriorityQueue +{ +public: + + UnsortedPriorityQueue(int arraySize); + ~UnsortedPriorityQueue(); + + inline bool Empty(int iteration) { if(m_iteration == iteration) { return m_nextFreeNode == 0; } else { return true; } } + inline int GetIteration() { return m_iteration; } + void Push(DijkstraPathfindingNode* node); + void Remove(DijkstraPathfindingNode* node); + DijkstraPathfindingNode* Pop(void); + +private: + int m_nextFreeNode; + int m_iteration; + bool m_identical; + DijkstraPathfindingNode** m_nodeArray; + +}; + diff --git a/JPSPlusGoalBounding/main.cpp b/JPSPlusGoalBounding/main.cpp new file mode 100644 index 0000000..7cb128e --- /dev/null +++ b/JPSPlusGoalBounding/main.cpp @@ -0,0 +1,286 @@ +// +// File.cpp +// MapAbstraction +// +// Created by Nathan Sturtevant on 7/11/13. +// Modified by Steve Rabin 12/15/14 +// +// + +#include "stdafx.h" +#include +#include +#include +#include +#include +#include "ScenarioLoader.h" +#include "Timer.h" +#include "Entry.h" +#include + +#include +#include +#include +#include +#include + +void LoadMap(const char *fname, std::vector &map, int &w, int &h); + +struct stats { + std::vector times; + std::vector path; + std::vector lengths; + + double GetTotalTime() + { + return std::accumulate(times.begin(), times.end(), 0.0); + } + double GetMaxTimestep() + { + return *std::max_element(times.begin(), times.end()); + } + double Get20MoveTime() + { + for (unsigned int x = 0; x < lengths.size(); x++) + if (lengths[x] >= 20) + return std::accumulate(times.begin(), times.begin()+1+x, 0.0); + return GetTotalTime(); + } + double GetPathLength() + { + double len = 0; + for (int x = 0; x < (int)path.size()-1; x++) + { + if (path[x].x == path[x+1].x || path[x].y == path[x+1].y) + { + len++; + } + else { + len += 1.4142; + } + } + return len; + } + bool ValidatePath(int width, int height, const std::vector &mapData) + { + for (int x = 0; x < (int)path.size()-1; x++) + { + if (abs(path[x].x - path[x+1].x) > 1) + return false; + if (abs(path[x].y - path[x+1].y) > 1) + return false; + if (!mapData[path[x].y*width+path[x].x]) + return false; + if (!mapData[path[x+1].y*width+path[x+1].x]) + return false; + if (path[x].x != path[x+1].x && path[x].y != path[x+1].y) + { + if (!mapData[path[x+1].y*width+path[x].x]) + return false; + if (!mapData[path[x].y*width+path[x+1].x]) + return false; + } + } + return true; + } +}; + +int _tmain(int argc, char* argv[]) +{ + double allTestsTotalTime = 0; + + WIN32_FIND_DATA ffd; + LARGE_INTEGER filesize; + TCHAR szDir[MAX_PATH]; + size_t length_of_arg; + HANDLE hFind = INVALID_HANDLE_VALUE; + DWORD dwError=0; + + StringCchCopy(szDir, MAX_PATH, TEXT("Maps\\*")); + hFind = FindFirstFile(szDir, &ffd); + + do + { + char filename[2048]; + std::vector thePath; + std::vector mapData; + int width, height; + bool pre = false; + bool run = true; + bool silenceIndividualTests = false; + + char mapFilename[2048] = "\0"; + char mapScenarioFilename[2048] = "\0"; + char mapPreprocessedFilename[2048] = "\0"; + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + continue; + } + else + { + int filenameLength = 0; + while(ffd.cFileName[++filenameLength] != 0) {} + + if (ffd.cFileName[filenameLength-3] == 'm' && + ffd.cFileName[filenameLength-2] == 'a' && + ffd.cFileName[filenameLength-1] == 'p') + { + char baseFilename[2048]; + for(int i=0; i experimentStats; + for (int x = 0; x < scen.GetNumExperiments(); x++) + { + thePath.resize(0); + experimentStats.resize(x+1); + bool done; + do { + xyLoc s, g; + s.x = scen.GetNthExperiment(x).GetStartX(); + s.y = scen.GetNthExperiment(x).GetStartY(); + g.x = scen.GetNthExperiment(x).GetGoalX(); + g.y = scen.GetNthExperiment(x).GetGoalY(); + + if(s.x == g.x && s.y == g.y) + { + done = true; + } + else + { + t.StartTimer(); + done = GetPath(reference, s, g, thePath); + t.EndTimer(); + + if(thePath.size() > 0) + { + experimentStats[x].times.push_back(t.GetElapsedTime()); + experimentStats[x].lengths.push_back(thePath.size()); + for (unsigned int t = experimentStats[x].path.size(); t < thePath.size(); t++) + experimentStats[x].path.push_back(thePath[t]); + } + } + } while (done == false); + + } + thePath.clear(); + delete reference; + + double totalTime = 0; + bool invalid = false; + bool suboptimal = false; + for (unsigned int x = 0; x < experimentStats.size(); x++) + { + if(!silenceIndividualTests) + { + printf("GPPC\t%s\ttotal-time\t%f\tmax-time-step\t%f\ttime-20-moves\t%f\ttotal-len\t%f\tsubopt\t%f\t", mapScenarioFilename, + experimentStats[x].GetTotalTime(), experimentStats[x].GetMaxTimestep(), experimentStats[x].Get20MoveTime(), + experimentStats[x].GetPathLength(), experimentStats[x].GetPathLength()/scen.GetNthExperiment(x).GetDistance()); + } + + if (experimentStats[x].path.size() != 0 && + (experimentStats[x].ValidatePath(width, height, mapData) && + scen.GetNthExperiment(x).GetStartX() == experimentStats[x].path[0].x && + scen.GetNthExperiment(x).GetStartY() == experimentStats[x].path[0].y && + scen.GetNthExperiment(x).GetGoalX() == experimentStats[x].path.back().x && + scen.GetNthExperiment(x).GetGoalY() == experimentStats[x].path.back().y)) + { + if(!silenceIndividualTests) + printf("valid\n"); + } + else + { + invalid = true; + if(!silenceIndividualTests) + printf("invalid\n"); + } + if (experimentStats[x].GetPathLength() / scen.GetNthExperiment(x).GetDistance() > 1.000005f) + { + suboptimal = true; + } + + totalTime += experimentStats[x].GetTotalTime(); + allTestsTotalTime += experimentStats[x].GetTotalTime(); + } + + printf("Total map time: %f,\t%s", totalTime, mapFilename); + if (invalid) { printf(",\tINVALID"); } + if (suboptimal) { printf(",\tSUBOPTIMAL"); } + printf("\n"); + + for (unsigned int x = 0; x < experimentStats.size(); x++) + { + experimentStats[x].path.clear(); + experimentStats[x].times.clear(); + experimentStats[x].lengths.clear(); + } + experimentStats.clear(); + scen.Clear(); + mapData.clear(); + + } while (FindNextFile(hFind, &ffd) != 0); + + printf("All tests total time: %f", allTestsTotalTime); + + while(true) {} + + return 0; +} + +void LoadMap(const char *fname, std::vector &map, int &width, int &height) +{ + FILE *f; + f = fopen(fname, "r"); + if (f) + { + fscanf(f, "type octile\nheight %d\nwidth %d\nmap\n", &height, &width); + map.resize(height*width); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + char c; + do { + fscanf(f, "%c", &c); + } while (isspace(c)); + map[y*width+x] = (c == '.' || c == 'G' || c == 'S'); + } + } + fclose(f); + } +} diff --git a/JPSPlusGoalBounding/stdafx.cpp b/JPSPlusGoalBounding/stdafx.cpp new file mode 100644 index 0000000..20d54fd --- /dev/null +++ b/JPSPlusGoalBounding/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// JPSPlusGoalBounding.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/JPSPlusGoalBounding/stdafx.h b/JPSPlusGoalBounding/stdafx.h new file mode 100644 index 0000000..b005a83 --- /dev/null +++ b/JPSPlusGoalBounding/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/JPSPlusGoalBounding/targetver.h b/JPSPlusGoalBounding/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/JPSPlusGoalBounding/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include