/// <summary> /// Calculates heuristic distance to target node. /// </summary> /// <param name="dataPos">The data node position.</param> /// <param name="emptyPos">The empty node.</param> /// <param name="targetNodePos">The target node.</param> /// <returns>The heuristic distance to target node.</returns> public static int CalcF(X_Y dataPos, X_Y emptyPos, X_Y targetNodePos) { var adjustedTargets = new X_Y[] { new X_Y() { X = dataPos.X - 1, Y = dataPos.Y }, new X_Y() { X = dataPos.X + 1, Y = dataPos.Y }, new X_Y() { X = dataPos.X, Y = dataPos.Y + 1 }, new X_Y() { X = dataPos.X, Y = dataPos.Y - 1 }, }; var fs = adjustedTargets.Select(t => { var distanceTargetY = Math.Abs(dataPos.Y - targetNodePos.Y); var distanceEmptyY = Math.Abs(t.Y - targetNodePos.Y); var distanceTargetX = Math.Abs(dataPos.X - targetNodePos.X); var distanceEmptyX = Math.Abs(t.X - targetNodePos.X); var f = CalcFAdjusted(distanceTargetX, distanceTargetY, distanceEmptyX, distanceEmptyY); return(new { h = emptyPos.CalcManhattanDistance(t), f }); }) .OrderBy(x => x.h) .ThenBy(x => x.f); var target = fs.First(); return(target.h + target.f); }