A whole lotta stuff.
This commit is contained in:
313
web/modules/custom/ufc/src/FightPredictor.php
Normal file
313
web/modules/custom/ufc/src/FightPredictor.php
Normal file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\ufc;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Drupal\ufc\Fighter;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\Core\Config\ConfigFactory;
|
||||
|
||||
class FightPredictor {
|
||||
|
||||
/**
|
||||
* First Fighter.
|
||||
*
|
||||
* @var Drupal\node\Entity\Node
|
||||
*/
|
||||
protected $fighterOne;
|
||||
|
||||
/**
|
||||
* Second Fighter.
|
||||
*
|
||||
* @var Drupal\node\Entity\Node
|
||||
*/
|
||||
protected $fighterTwo;
|
||||
|
||||
/**
|
||||
* Entity Type Manager.
|
||||
*
|
||||
* @var Drupal\Core\Entity\EntityTypeManager
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Config for ufc weights.
|
||||
*
|
||||
* @var Drupal\Core\Config\ConfigFactory
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Weights config object.
|
||||
*
|
||||
* @var Drupal\Core\Config\ConfigFactory
|
||||
*/
|
||||
protected $weights;
|
||||
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*/
|
||||
public function __construct(EntityTypeManager $entityTypeManager, ConfigFactory $config) {
|
||||
$this->entityTypeManager = $entityTypeManager;
|
||||
$this->config = $config->getEditable('ufc.weights');
|
||||
$this->weights = $config->getEditable('ufc.weights')->get('fight_weights');
|
||||
}
|
||||
|
||||
/**
|
||||
* The results of the fight.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $results = [
|
||||
'fighter_one' => [
|
||||
'name' => null,
|
||||
'points' => 0,
|
||||
'advantages' => [],
|
||||
'disadvantages' => []
|
||||
],
|
||||
'fighter_two' => [
|
||||
'name' => null,
|
||||
'points' => 0,
|
||||
'advantages' => [],
|
||||
'disadvantages' => []
|
||||
],
|
||||
'skips' => 0
|
||||
];
|
||||
|
||||
/**
|
||||
* The amount of categories skipped.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $skipCount;
|
||||
|
||||
/**
|
||||
* Calculate the fight results.
|
||||
*/
|
||||
public function calculate(Node $fighter_one, Node $fighter_two) {
|
||||
// Reset skip count.
|
||||
$this->skipCount = 0;
|
||||
// First Fighter.
|
||||
$this->fighterOne = $fighter_one;
|
||||
// Second Fighter.
|
||||
$this->fighterTwo = $fighter_two;
|
||||
|
||||
// Run the fight.
|
||||
$this->runFight();
|
||||
|
||||
// Label the results array.
|
||||
$this->results['fighter_one']['name'] = $fighter_one->label();
|
||||
$this->results['fighter_two']['name'] = $fighter_two->label();
|
||||
// Add total skips.
|
||||
$this->results['skips'] = $this->skipCount;
|
||||
|
||||
// echo "<pre>";
|
||||
// print_r($this->results);
|
||||
// echo "</pre>";
|
||||
// exit();
|
||||
|
||||
return $this->results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate fight results.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function runFight() {
|
||||
$points = 0;
|
||||
$this->calcComparativePoints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate comparative points.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function calcComparativePoints() {
|
||||
$this->calculateDiff('field_height', 'height');
|
||||
$this->calculateDiff('field_weight', 'weight');
|
||||
$this->calculateDiff('field_age', 'age');
|
||||
$this->calculateDiff('field_reach', 'reach');
|
||||
$this->calculateDiff('field_leg_reach', 'leg_reach');
|
||||
$this->calculateDiff('field_wins', 'wins');
|
||||
$this->calculateDiff('field_losses', 'losses', TRUE);
|
||||
$this->calculateDiff('field_ties', 'ties');
|
||||
$this->calculateDiff('field_decisions', 'decisions');
|
||||
$this->calculateDiff('field_knockouts', 'knockouts');
|
||||
$this->calculateDiff('field_submissions', 'submissions');
|
||||
$this->calculateDiff('field_grappling_accuracy', 'grappling_accuracy');
|
||||
$this->calculateDiff('field_striking_accuracy', 'striking_accuracy');
|
||||
$this->calculateDiff('field_strikes_per_minute', 'strikes_per_minute');
|
||||
$this->calculateDiff('field_absorbed_per_min', 'absorbed_per_min', TRUE);
|
||||
$this->calculateDiff('field_takedowns_per_15', 'takedowns_per_15');
|
||||
$this->calculateDiff('field_knockdown_ratio', 'knockdown_ratio');
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the weighted diff between two fighters.
|
||||
*
|
||||
* @param [type] $field
|
||||
* @param [type] $weight_label
|
||||
* @return void
|
||||
*/
|
||||
public function calculateDiff($field, $weight_label, $inverse = FALSE) {
|
||||
$f1 = $this->getFieldValue($field, $this->fighterOne);
|
||||
$f2 = $this->getFieldValue($field, $this->fighterTwo);
|
||||
|
||||
if (empty($f1) || empty($f2)) {
|
||||
$this->skipCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
$weighted_points = 1 * $this->config->get('fight_weights')[$weight_label];
|
||||
|
||||
if ($f1 === $f2) {
|
||||
$this->skipCount += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if ($inverse) {
|
||||
if ($f1 < $f2) {
|
||||
$this->results['fighter_one']['points'] += $weighted_points;
|
||||
$this->results['fighter_one']['advantages'][] = $field;
|
||||
$this->results['fighter_two']['disadvantages'][] = $field;
|
||||
return;
|
||||
}
|
||||
elseif ($f1 > $f2) {
|
||||
$this->results['fighter_two']['points'] += $$weighted_points;
|
||||
$this->results['fighter_two']['advantages'][] = $field;
|
||||
$this->results['fighter_one']['disadvantages'][] = $field;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($f1 > $f2) {
|
||||
$this->results['fighter_one']['points'] += $weighted_points;
|
||||
$this->results['fighter_one']['advantages'][] = $field;
|
||||
$this->results['fighter_two']['disadvantages'][] = $field;
|
||||
}
|
||||
elseif ($f1 < $f2) {
|
||||
$this->results['fighter_two']['points'] += $weighted_points;
|
||||
$this->results['fighter_two']['advantages'][] = $field;
|
||||
$this->results['fighter_one']['disadvantages'][] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value from a field.
|
||||
*/
|
||||
public function getFieldValue($field, Node $fighter) {
|
||||
$field_values = reset($fighter->get($field)->getValue());
|
||||
|
||||
if (empty($field_values['value'])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (float) $field_values['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the knockout percentage for a fighter.
|
||||
*
|
||||
* @param Node $fighter
|
||||
* @return void
|
||||
*/
|
||||
public function getKnockoutPercentage(Node $fighter) {
|
||||
|
||||
$total_fights =
|
||||
$this->getFieldValue('field_wins', $fighter) +
|
||||
$this->getFieldValue('field_losses', $fighter) +
|
||||
$this->getFieldValue('field_ties', $fighter);
|
||||
|
||||
$knockout_pct = $this->getFieldValue('field_knockouts', $fighter) / $total_fights;
|
||||
|
||||
return $knockout_pct;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update predictions for all fights in batches
|
||||
*/
|
||||
public function updatePredictionsBatched($fights, &$context) {
|
||||
// $fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
|
||||
$results = [];
|
||||
foreach ($fights as $fight) {
|
||||
\Drupal::logger('ufc')->notice("Starting " . $fight->label() . "");
|
||||
$fight->save();
|
||||
$results[] = $fight->id();
|
||||
}
|
||||
$context['results'] = $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update predictions for all fights.
|
||||
*/
|
||||
public function updatePredictions() {
|
||||
$fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
|
||||
|
||||
// $count = 0;
|
||||
|
||||
foreach ($fights as $fight) {
|
||||
\Drupal::logger('ufc')->notice("Starting " . $fight->label() . "");
|
||||
$fight->save();
|
||||
|
||||
// if ($count == 4) {
|
||||
// return;
|
||||
// }
|
||||
// $count++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function adjustWeights($adv, $dis_adv) {
|
||||
foreach ($adv as $cat_to_increase) {
|
||||
$clean = str_replace('field_', '', $cat_to_increase);
|
||||
$this->adjustWeight($clean, 2);
|
||||
}
|
||||
|
||||
foreach ($dis_adv as $cat_to_decrease) {
|
||||
$clean = str_replace('field_', '', $cat_to_decrease);
|
||||
$this->adjustWeight($clean, -1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to increase the weight of a category.
|
||||
*/
|
||||
public function adjustWeight($key, $increment) {
|
||||
$current_val = $this->config->get('fight_weights')[$key];
|
||||
$increase = $current_val + $increment;
|
||||
$target = 'fight_weights.' . $key;
|
||||
$this->config->set($target, $increase)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to reset all weighting.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetWeights() {
|
||||
foreach ($this->config->get('fight_weights') as $cat => $weight) {
|
||||
$this->config->set('fight_weights.' . $cat, 1)->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function fightUpdatedCallback($success, $results, $operations) {
|
||||
// The 'success' parameter means no fatal PHP errors were detected. All
|
||||
// other error management should be handled using 'results'.
|
||||
if ($success) {
|
||||
$message = \Drupal::translation()->formatPlural(
|
||||
count($results),
|
||||
'One fight processed.', '@count fight processed.'
|
||||
);
|
||||
}
|
||||
else {
|
||||
$message = t('Finished with an error.');
|
||||
}
|
||||
drupal_set_message($message);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user