public GoalSeeker(Player player) {
		if (player == null) {
			throw new NullPointerException("Player is null.");
		}
		this.player = player;

		if (player.isWinner()) {
			// Special case: we're already at a goal position.
			path = new Orientation[0];
			return;
		}

		int w = getBoard().getWidth();
		int h = getBoard().getHeight();
		from = new Orientation[w][h];
		distance = new int[w][h];
		for (int x = 0; x < w; x++) {
			for (int y = 0; y < h; y++) {
				distance[x][y] = Integer.MAX_VALUE;
			}
		}

		Queue<Position> front = new PriorityQueue<Position>(8, this);
		Position pos = player.getPosition();
		distance[pos.getX()][pos.getY()] = 0;
		front.add(player.getPosition());

		int counter = 0;

		while (!front.isEmpty()) {
			counter++;
			pos = front.remove();
			int x = pos.getX();
			int y = pos.getY();
			for (Orientation o : Orientation.values()) {
				if (getBoard().isBlocked(pos, o)) {
					continue;
				}
				Position pos2 = pos.move(o);
				int x2 = pos2.getX();
				int y2 = pos2.getY();
				if (distance[x2][y2] > distance[x][y] + 1) {
					distance[x2][y2] = distance[x][y] + 1;
					from[x2][y2] = o.opposite();
					front.add(pos2);

					if (player.isGoal(pos2)) {
						// We've found a goal position. Build and return path.
						path = buildPath(pos2);
						return;
					}
				}
			}
		}
	}