davaxi/Takuzu

View on GitHub
src/Resolver.php

Summary

Maintainability
A
3 hrs
Test Coverage
<?php
 
namespace Davaxi\Takuzu;
use Davaxi\Takuzu\ResolverMethod\RandomValue;
 
/**
* Class Resolver
* @package Davaxi\Takuzu
*/
class Resolver
{
/**
* @var bool
*/
protected $resolved = false;
 
/**
* @var Grid
*/
protected $originalGrid;
 
/**
* @var Grid
*/
protected $resolvedGrid;
 
/**
* @var ResolverChain[]
*/
protected $chains = array();
 
/**
* @var ResolverChain
*/
protected $resolvedChain;
 
/**
* @var ResolverMethod[]
*/
protected $resolverMethods = array(
'\Davaxi\Takuzu\ResolverMethod\NoThreeSide',
'\Davaxi\Takuzu\ResolverMethod\NoThreeCenter',
'\Davaxi\Takuzu\ResolverMethod\CompleteEquality',
'\Davaxi\Takuzu\ResolverMethod\NecessaryValues',
'\Davaxi\Takuzu\ResolverMethod\NoPossibleRange',
);
 
/**
* Resolver constructor.
* @param Grid $grid
*/
public function __construct(Grid $grid)
{
$this->originalGrid = $grid;
$this->chains[] = new ResolverChain($grid);
$this->resolved = $this->originalGrid->getChecker()->hasResolved();
if ($this->resolved) {
$this->resolvedGrid = $grid;
}
}
 
/**
* @return bool
*/
public function hasResolved()
{
return $this->resolved;
}
 
/**
* @return Grid
*/
public function getResolvedGrid()
{
return $this->resolvedGrid;
}
 
/**
* @param Grid $grid
* @return ResolverMethod|null
*/
protected function foundNextResolveGridMethod(Grid $grid)
{
foreach ($this->resolverMethods as $resolverMethodClass) {
/** @var ResolverMethod $resolverMethod */
$resolverMethod = new $resolverMethodClass($grid);
if ($resolverMethod->found()) {
return $resolverMethod;
}
}
return null;
}
 
/**
* @param Grid $grid
* @param $value
* @return ResolverStep
*/
protected function generateTryResolverStep(Grid $grid, $value)
{
list($lineNo, $columnNo) = $grid->getFirstEmptyCasePosition();
$resolverMethod = new RandomValue($grid);
$resolverMethod->setValue($lineNo, $columnNo, $value);
return $this->generateResolverStep($resolverMethod);
}
 
/**
* @param ResolverMethod $resolverMethod
* @return ResolverStep
*/
protected function generateResolverStep(ResolverMethod $resolverMethod)
{
$nextResolveStep = new ResolverStep();
$nextResolveStep->setResolverMethod($resolverMethod);
$nextResolveStep->resolve();
return $nextResolveStep;
}
 
Function `nextResolveSteps` has a Cognitive Complexity of 17 (exceeds 5 allowed). Consider refactoring.
Method `nextResolveSteps` has 41 lines of code (exceeds 25 allowed). Consider refactoring.
protected function nextResolveSteps()
{
if ($this->resolved) {
Missing class import via use statement (line '122', column '23').
throw new \LogicException('Grid already resolved');
}
$chains = array();
foreach ($this->chains as $resolverChain) {
$grid = $resolverChain->getCurrentGrid();
try {
$resolveMethod = $this->foundNextResolveGridMethod($grid);
}
catch (InvalidGridException $e) {
continue;
}
 
if ($resolveMethod === null) {
if (!$grid->getEmptyCaseCount()) {
continue;
}
 
$secondResolverChain = clone $resolverChain;
 
$nextResolverStep = $this->generateTryResolverStep($grid, Grid::ZERO);
$resolverChain->addResolverStep($nextResolverStep);
$chains[] = $resolverChain;
 
$nextResolverStep = $this->generateTryResolverStep($grid, Grid::ONE);
$secondResolverChain->addResolverStep($nextResolverStep);
$chains[] = $secondResolverChain;
continue;
}
 
$nextResolverStep = $this->generateResolverStep($resolveMethod);
$resolverChain->addResolverStep($nextResolverStep);
 
$resolvedGrid = $nextResolverStep->getResolvedGrid();
if ($grid->getGridString() === $resolvedGrid->getGridString()) {
Missing class import via use statement (line '156', column '27').
throw new \LogicException('No change ?');
}
if ($resolvedGrid->getChecker()->hasResolved()) {
$this->resolved = true;
$this->resolvedGrid = $resolvedGrid;
$this->resolvedChain = $resolverChain;
$chains = array();
break;
}
$chains[] = $resolverChain;
}
$this->chains = $chains;
}
 
/**
* @return ResolverChain
*/
public function getResolvedChain()
{
return $this->resolvedChain;
}
 
public function resolve()
{
do {
$this->nextResolveSteps();
}
while ($this->chains);
 
if (!$this->resolved) {
throw new InvalidGridException('Not resovled grid');
}
}
}