/// <summary> /// Determines whether the Sokoban can move from the source node to <paramref name="pos"/>, and if /// so, adds this as a newly-discovered node to the <paramref name="priorityQueue"/>. This is used /// only to add the first four items into the priority queue at the beginning of the algorithm. /// </summary> /// <param name="arrIndex">Index of the node the Sokoban is moving to.</param> /// <param name="pos">Co-ordinates of the cell the Sokoban is moving to.</param> /// <param name="priorityQueue">The priority queue.</param> private void addIfValid(int arrIndex, Point pos, specialHeap priorityQueue) { if (_moveFinder.Get(pos)) { _pushLength[arrIndex] = 1; _moveLength[arrIndex] = _moveFinder.PathLength(pos) + 1; priorityQueue.Add(arrIndex); } }
/// <summary> /// Relaxes an edge, which is Dijkstrian for: Given that going from <paramref name="fromNode"/> to <paramref name="toNode"/> /// requires <paramref name="pushLength"/> pushes and <paramref name="moveLength"/> moves, check if this gives rise to a /// shorter way to reach <paramref name="toNode"/> from the source node, and if so, update the node with the new path /// lengths and the new predecessor, and insert it into the priority queue. /// </summary> private void relaxEdge(int fromNode, int toNode, int pushLength, int moveLength, specialHeap priorityQueue) { if ( // Either we haven't discovered this node yet... _pushLength[toNode] == 0 || // ...or we can reduce its push length... _pushLength[toNode] > _pushLength[fromNode] + pushLength || // ...or its push length is the same, but we can reduce the move length (_pushLength[toNode] == _pushLength[fromNode] + pushLength && _moveLength[toNode] > _moveLength[fromNode] + moveLength) ) { _pushLength[toNode] = _pushLength[fromNode] + pushLength; _moveLength[toNode] = _moveLength[fromNode] + moveLength; _predecessor[toNode] = fromNode; priorityQueue.Add(toNode); } }