Skip to content

Commit

Permalink
21.12.2018
Browse files Browse the repository at this point in the history
General Work
  • Loading branch information
Suficio committed Dec 21, 2018
1 parent 3ece51e commit 09e7ad0
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 32 deletions.
2 changes: 1 addition & 1 deletion DefaultConditions/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#Default Condition
# Default Condition
1 change: 1 addition & 0 deletions Pathfinders/ASTAR.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use strict';
const Heap = require('fastpriorityqueue');

function State(p)
Expand Down
1 change: 1 addition & 0 deletions Pathfinders/DLITE/DLITE.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use strict';
const Path = require('path');
const DLITEReturnState = require(Path.resolve(__dirname, 'DLITEReturnState.js'));

Expand Down
40 changes: 20 additions & 20 deletions Pathfinders/DLITE/DLITEReturnState.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use strict';
const Heap = require('fastpriorityqueue');

module.exports = function DLITEReturnState(bot, sp, ep, UpdateVertex, ComputeShortestPath)
Expand Down Expand Up @@ -57,7 +58,7 @@ module.exports = function DLITEReturnState(bot, sp, ep, UpdateVertex, ComputeSho
Object.defineProperty(this, 'U', {value: U, enumerable: false});
Object.defineProperty(this, 'S', {value: S, enumerable: false});

State = function(p)
const State = function(p)
{
if (S.check(p))
return S[p.x >>> 0][p.y >>> 0][p.z >>> 0];
Expand All @@ -75,8 +76,7 @@ module.exports = function DLITEReturnState(bot, sp, ep, UpdateVertex, ComputeSho

Object.defineProperty(this, 'State', {value: State, enumerable: false});

// Algorithm
Initialize.call(this, bot, sp, ep, UpdateVertex, ComputeShortestPath);
// Path functions

const R = this;
this.path = {};
Expand All @@ -89,6 +89,7 @@ module.exports = function DLITEReturnState(bot, sp, ep, UpdateVertex, ComputeSho
let minState;
let minCost = Number.POSITIVE_INFINITY;

// Get successors according to stored state.
const successors = bot.pathfinder.getSuccessors(R.S.start.p);
for (let n = 0, len = successors.length; n < len; n++)
{
Expand Down Expand Up @@ -122,6 +123,9 @@ module.exports = function DLITEReturnState(bot, sp, ep, UpdateVertex, ComputeSho
}
else return undefined;
};

// Algorithm
Initialize.call(this, bot, sp, ep, UpdateVertex, ComputeShortestPath);
};

function Initialize(bot, sp, ep, UpdateVertex, ComputeShortestPath)
Expand All @@ -143,23 +147,19 @@ function Initialize(bot, sp, ep, UpdateVertex, ComputeShortestPath)
{
// ComputeShortestPath has to be run initially
const MainPromise = this.ComputeShortestPath();
MainPromise
.then(function(ReturnState)
MainPromise.then(function(ReturnState)
{
R.ENUMStatus = ReturnState.ENUMStatus;
R.ClosestPoint = ReturnState.State.p;
if (ReturnState.ENUMStatus === bot.pathfinder.ENUMStatus.Incomplete)
{
R.ENUMStatus = ReturnState.ENUMStatus;
// Should the path be incomplete, sets the start point to the closest point to the intended
// start point, to which a replan can be attempted using a different algorithm.
if (ReturnState.ENUMStatus === bot.pathfinder.ENUMStatus.Incomplete)
{
console.warn(
'WARNING Pathfinder: Did not find path in allowed MAX_EXPANSIONS, returned closest valid start point',
'Use another algorithm to reach the valid start point before attempting D*Lite'
);
R.S.start = ReturnState.State;
}

Callback(R);
});
console.warn(
'WARNING Pathfinder: Did not find path in allowed MAX_EXPANSIONS, returned closest valid start point',
'Use another algorithm to reach the valid start point before attempting D*Lite'
);
}
});
MainPromise.then(function() {Callback(R);});
};
};

Expand All @@ -172,4 +172,4 @@ function floatEqual(f1, f2)
{
if (f1 === Number.POSITIVE_INFINITY && f2 === Number.POSITIVE_INFINITY) return true;
return Math.abs(f1 - f2) < Number.EPSILON;
}
}
1 change: 1 addition & 0 deletions Pathfinders/DLITE/UDLITE.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
'use strict';
const Path = require('path');
const DLITEReturnState = require(Path.resolve(__dirname, 'DLITEReturnState.js'));

Expand Down
34 changes: 30 additions & 4 deletions Pathfinders/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
# Algorithm Documentation

## Table of Contents
- [Algorithm Documentation](#algorithm-documentation)
- [Table of Contents](#table-of-contents)
- [A* Pathfinding](#a-pathfinding)
- [ASTARReturnState](#astarreturnstate)
- [ASTARReturnState.on( Callback)](#astarreturnstateon-callback)
- [D* Lite Pathfinding](#d-lite-pathfinding)
- [DLITEReturnState](#dlitereturnstate)
- [ASTARReturnState.on( Callback)](#astarreturnstateon-callback-1)
- [ASTARReturnState.path.pop()](#astarreturnstatepathpop)
- [ASTARReturnState.path.peek()](#astarreturnstatepathpeek)
- [ASTARReturnState.path.replan([startPoint, endPoint]) [Not implemented]](#astarreturnstatepathreplanstartpoint-endpoint-not-implemented)
- [JPS A* Pathfinding [Not implemented]](#jps-a-pathfinding-not-implemented)

## A* Pathfinding
Standard A* algorithim as per Peter E. Hart, Nils J. Nilsson, Bertram Raphael, 1968.
Should you want to learn how the algorithm works: https://en.wikipedia.org/wiki/A*_search_algorithm
Expand All @@ -13,6 +28,9 @@ Provides a function to be executed when the path search has completed

* `Callback` - Function to be executed once the path search has completed, `ASTARReturnState` passed as argument.

### ASTARReturnState.ENUMState
Set when algorithim completes path search, equal to one of `bot.pathfinder.ENUMStatus` depending on whether the path search was successfull or not.


## D* Lite Pathfinding
D* Lite as per S. Koenig, 2002.
Expand All @@ -30,22 +48,30 @@ Object with the following properties:
* `ENUMStatus` - Provides the respective `bot.pathfinder.ENUMStatus` based on the outcome of the path search.
* `path` - See `DLITEReturnState.path`

#### ASTARReturnState.on( Callback)
#### DLITEReturnState.on( Callback)
Provides a function to be executed when the path search has completed

* `Callback` - Function to be executed once the path search has completed, `DLITEReturnState` passed as argument.

#### ASTARReturnState.path.pop()
### DLITEReturnState.ENUMState
Set when algorithim completes path search, equal to one of `bot.pathfinder.ENUMStatus` depending on whether the path search was successfull or not.

### DLITEReturnState.ClosestPoint
Set when algorithim completes path search, equal to the closest point from which a path from the end point to the start could be found.

If `DLITEReturnState.ENUMState` is incomplete, it is recommended to use a different method to navigate the bot to the `DLITEReturnState.ClosestPoint` before attempting pathfinding using D* Lite again.

#### DLITEReturnState.path.pop()
As the path is determined while the bot moves across it, pop must be used to determine the next location to move to.

Returns position vector.

#### ASTARReturnState.path.peek()
#### DLITEReturnState.path.peek()
Determines which path element will be popped next.

Returns position vector.

#### ASTARReturnState.path.replan([startPoint, endPoint]) /[Not implemented]
#### DLITEReturnState.path.replan([startPoint, endPoint]) \[Not implemented]


## JPS A* Pathfinding \[Not implemented]
Expand Down
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
# Mineflayer-Pathfinder
Fast, promise based, 3D pathfinding library using A* and D*Lite algorithms, for Mineflayer found under: [https://github.com/superjoe30/mineflayer/](https://github.com/superjoe30/mineflayer/)

## Features
## Table of Contents
- [Mineflayer-Pathfinder](#mineflayer-pathfinder)
- [Features](#features)
- [Table of Contents](#table-of-contents)
- [Basic Usage](#basic-usage)
- [Advanced Usage](#advanced-usage)
- [Documentation](#documentation)
- [bot.pathfinder.to( startPoint, endPoint [, ENUMPathfinder])](#botpathfinderto-startpoint-endpoint--enumpathfinder)
- [bot.pathfinder.getSuccessors( position)](#botpathfindergetsuccessors-position)
- [bot.pathfinder.getPredecessors( position)](#botpathfindergetpredecessors-position)
- [bot.pathfinder.getBlock( position)](#botpathfindergetblock-position)
- [bot.pathfinder.MAX_EXPANSIONS](#botpathfindermax_expansions)
- [bot.pathfinder.HEURISTIC( startPoint, EndPoint)](#botpathfinderheuristic-startpoint-endpoint)
- [bot.pathfinder.COST](#botpathfindercost)
- [bot.pathfinder.ENUMPathfinder](#botpathfinderenumpathfinder)
- [bot.pathfinder.ENUMStatus](#botpathfinderenumstatus)
- [Algorithm Documentation](#algorithm-documentation)

## Features
* Provides high level API for determining paths between two points
* Multiple algorithms for pathfinding, A* and D*Lite
* Exposed internal functions to allow easier user replacement
* Based solely on a promise based API

## Table of Contents

## Basic Usage
To get started just paste this code into your bot:
```js
Expand Down
12 changes: 8 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
EventEmitter = require('events').EventEmitter;
'use strict';
const EventEmitter = require('events').EventEmitter;
const Vec3 = require('vec3');
const Path = require('path');

Expand All @@ -15,10 +16,13 @@ module.exports = function(bot)

bot.pathfinder = new EventEmitter();
bot.pathfinder.ENUMPathfinder = {ASTAR: 0, DLITE: 1, UDLITE: 2};
bot.pathfinder.ENUMStatus = {Complete: 0, Incomplete: 1};
bot.pathfinder.ENUMStatus = {Complete: 0, Incomplete: 1, Replan: 2};

bot.pathfinder.getSuccessors = gMS.bind(undefined, require(Path.resolve(__dirname, 'DefaultConditions/successorConditions.json')));
bot.pathfinder.getPredecessors = gMS.bind(undefined, require(Path.resolve(__dirname, 'DefaultConditions/predecessorConditions.json')));
Object.defineProperty(bot.pathfinder, 'defaultSuccessors', {value: require(Path.resolve(__dirname, 'DefaultConditions/successorConditions.json')), enumerable: false});
Object.defineProperty(bot.pathfinder, 'defaultPredecessors', {value: require(Path.resolve(__dirname, 'DefaultConditions/predecessorConditions.json')), enumerable: false});

bot.pathfinder.getSuccessors = gMS.bind(undefined, bot.pathfinder.defaultSuccessors);
bot.pathfinder.getPredecessors = gMS.bind(undefined, bot.pathfinder.defaultPredecessors);

// Native getBlock implementation too slow for this case
let blocks;
Expand Down

0 comments on commit 09e7ad0

Please sign in to comment.