{"id":22426082,"url":"https://github.com/vladovsiychuk/jump-point-search-algorithm","last_synced_at":"2026-07-10T01:31:38.068Z","repository":{"id":264306058,"uuid":"892993065","full_name":"vladovsiychuk/jump-point-search-algorithm","owner":"vladovsiychuk","description":"Improved version of A*, aka JPS","archived":false,"fork":false,"pushed_at":"2024-11-25T09:35:53.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T15:59:54.017Z","etag":null,"topics":["a-star","algorithm","jps","jps-algorithm","jump-point-search","pathfinding","pathfinding-algorithm"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vladovsiychuk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-23T08:44:04.000Z","updated_at":"2024-11-25T09:35:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"fcc5b462-5d43-40cd-9bc7-f4c98010f6b9","html_url":"https://github.com/vladovsiychuk/jump-point-search-algorithm","commit_stats":null,"previous_names":["vladovsiychuk/jump-point-search-algorithm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vladovsiychuk/jump-point-search-algorithm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladovsiychuk%2Fjump-point-search-algorithm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladovsiychuk%2Fjump-point-search-algorithm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladovsiychuk%2Fjump-point-search-algorithm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladovsiychuk%2Fjump-point-search-algorithm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vladovsiychuk","download_url":"https://codeload.github.com/vladovsiychuk/jump-point-search-algorithm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vladovsiychuk%2Fjump-point-search-algorithm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35317805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a-star","algorithm","jps","jps-algorithm","jump-point-search","pathfinding","pathfinding-algorithm"],"created_at":"2024-12-05T19:16:28.025Z","updated_at":"2026-07-10T01:31:38.062Z","avatar_url":"https://github.com/vladovsiychuk.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Implements the idea from https://zerowidth.com/2013/a-visual-explanation-of-jump-point-search/\n\n## Pseudo Code\n```\nNode {\n    Position          // X, Y coordinates\n    G, H, F           // Cost metrics: G (from start), H (heuristic to end), F (total cost)\n    ParentDir         // Direction from parent node\n    ForcedNeighborDir // Direction of a forced neighbor (if any)\n    Parent            // Reference to parent node\n}\n\nfindPathWithJPS(StartNode, EndNode, Matrix)\n    OpenList = createHeap()          // Binary heap, pops node with lowest F value with log(N) speed\n    OpenList.push(StartNode)         // Add StartNode to OpenList\n\n    while OpenList is not empty\n        CurrentNode = pop(OpenList)  // Get node with the lowest F value\n        if CurrentNode.Position == EndNode.Position\n            return reconstructPath(CurrentNode) // Build path by traversing Parent nodes\n\n        Successors = findSuccessors(CurrentNode, EndNode, Matrix)\n        for each Successor in Successors\n            OpenList.push(Successor)\n\nreconstructPath(Node)\n    ResultList = []\n    while Node != nil\n        add Node to ResultList\n        Node = Node.Parent\n    reverse(ResultList)\n    return ResultList\n\nfindSuccessors(CurrentNode, EndNode, Matrix)\n    Successors = []\n    X, Y = CurrentNode.Position\n\n    for each Dir in getDirections(CurrentNode)  // Note: can be run in parallel\n        DX, DY = Dir\n        SX, SY, ForcedNeighborDir, found = jump(X+DX, Y+DY, DX, DY, EndNode, Matrix)\n        if found\n            Successor = new Node()\n            Successor.Position = {SX, SY}\n            Successor.G = CurrentNode.G + heuristic(CurrentNode.Position, Successor.Position)\n            Successor.H = heuristic(Successor.Position, EndNode.Position)\n            Successor.F = Successor.G + Successor.H\n            Successor.ParentDir = Dir\n            Successor.ForcedNeighborDir = ForcedNeighborDir\n            Successor.Parent = CurrentNode\n            add Successor to Successors\n    return Successors\n\ngetDirections(Node)\n    if Node.ParentDir == nil  // Starting node\n        return [{0, -1}, {0, 1}, {-1, 0}, {1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}] // All 8 directions\n\n    PDX, PDY = Node.ParentDir\n    FNDX, FNDY = Node.ForcedNeighborDir\n\n    if PDX != 0 and PDY != 0  // Diagonal movement\n        return [{PDX, PDY}, {PDX, 0}, {0, PDY}, if ForcedNeighborDir exists then also {FNDX, FNDY}]\n    else  // Horizontal or vertical movement\n        return [{PDX, PDY}, if ForcedNeighborDir exists then also {FNDX, FNDY}]\n\njump(X, Y, DX, DY, EndNode, Matrix) returns X, Y, ForcedNeighnorDir, found\n    while isWalkable(X, Y, Matrix)\n        if {X, Y} == EndNode.Position\n            return X, Y, nil, true\n\n        // Diagonal movement: Check forced neighbors\n        if DX != 0 and DY != 0\n            if !isWalkable(X-DX, Y, Matrix) \u0026\u0026 !isWalkable(X, Y-DY, Matrix)\n                return 0, 0, nil, false\n\n            // Try to find the forced neighbor pattern for diagonal move as described in the article \n            if !isWalkable(X, Y+DY*-1, Matrix) and isWalkable(X+DX, Y+DY*-1, Matrix)\n                return X, Y, {DX, DY*-1}, true\n            if !isWalkable(X+DX*-1, Y Matrix) and isWalkable(X+DX*-1, Y+DY, Matrix)\n                return X, Y, {DX*-1, DY}, true\n\n            // Recursive jump for horizontal and vertical continuations\n            _, _, _, found1 = jump(X + DX, Y, DX, 0, EndNode, Matrix) // Only found is of interest\n            _, _, _, found2 = jump(X, Y + DY, 0, DY, EndNode, Matrix)\n            if (found1 == true) or (found2 == true)\n                return X, Y, nil, true\n\n        // Horizontal movement: Check forced neighbors\n        else if DX != 0\n            if !isWalkable(X, Y - 1, Matrix) and isWalkable(X + DX, Y - 1, Matrix)\n                return X, Y, {DX, -1}, true\n            if !isWalkable(X, Y + 1, Matrix) and isWalkable(X + DX, Y + 1, Matrix)\n                return X, Y, {DX, 1}, true\n\n        // Vertical movement: Check forced neighbors\n        else if DY != 0\n            if !isWalkable(X - 1, Y, Matrix) and isWalkable(X - 1, Y + DY, Matrix)\n                return X, Y, {-1, DY}, true\n            if !isWalkable(X + 1, Y, Matrix) and isWalkable(X + 1, Y + DY, Matrix)\n                return X, Y, {1, DY}, true\n\n        // Continue in the same direction\n        X += DX\n        Y += DY\n\n    return 0, 0, nil, false\n\n\nisWalkable(X, Y, Matrix)\n\treturn X \u003e= 0 and Y \u003e= 0 and x \u003c Matrix.size and y \u003c Matrix[0].size and Matrix[x][y]\n\n\nfunc heuristic(A, B, Matrix) returns int \n\t// Using Manhattan distance as heuristic\n\treturn math.Abs(A.X-B.X) + math.Abs(A.Y-B.Y)\n```\n\n## Running Tests\n1. Install Go with \"brew install go\" or https://go.dev/doc/install\n2. git clone https://github.com/vladovsiychuk/jump-point-search-algorithm\n3. cd jump-point-search-algorithm\n4. go mod tidy\n5. go test ./...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladovsiychuk%2Fjump-point-search-algorithm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvladovsiychuk%2Fjump-point-search-algorithm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvladovsiychuk%2Fjump-point-search-algorithm/lists"}