EagerSolver::using()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php declare(strict_types=1);
2
3
namespace Stratadox\PuzzleSolver\Solver;
4
5
use Stratadox\PuzzleSolver\Puzzle;
6
use Stratadox\PuzzleSolver\PuzzleSolver;
7
use Stratadox\PuzzleSolver\NoPossibleSolution;
8
use Stratadox\PuzzleSolver\PuzzleSolution;
9
use Stratadox\PuzzleSolver\SearchStrategy\SearchStrategyFactory;
10
use Stratadox\PuzzleSolver\Solutions;
11
12
/**
13
 * Eager puzzle solvers will search for the first valid solution. Eager solvers
14
 * will stop after finding a single solution, making them neat for puzzles that
15
 * can have only one possible solution, or require only a single solution.
16
 *
17
 * @author Stratadox
18
 */
19
final class EagerSolver implements PuzzleSolver
20
{
21
    /** @var SearchStrategyFactory */
22
    private $strategy;
23
24
    private function __construct(SearchStrategyFactory $strategy)
25
    {
26
        $this->strategy = $strategy;
27
    }
28
29
    public static function using(SearchStrategyFactory $strategy): PuzzleSolver
30
    {
31
        return new self($strategy);
32
    }
33
34
    public function solve(Puzzle $puzzle): Solutions
35
    {
36
        $search = $this->strategy->begin($puzzle);
37
38
        while ($search->isOngoing()) {
39
            $puzzleState = $search->nextCandidate();
40
41
            if ($puzzleState->isSolved()) {
42
                return new Solutions(PuzzleSolution::fromSolved($puzzleState, $puzzle));
43
            }
44
45
            foreach ($puzzleState->possibleMoves() as $move) {
46
                $search->consider($puzzleState->afterMaking($move));
47
            }
48
        }
49
50
        throw NoPossibleSolution::to($puzzle);
51
    }
52
}
53