Rebuild
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\ufc\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\Core\Entity\EntityTypeManager;
|
||||
use Drupal\node\NodeInterface;
|
||||
use Drupal\node\Entity\Node;
|
||||
use Drupal\media\Entity\Media;
|
||||
use Drupal\file\Entity\File;
|
||||
use Drupal\Core\Cache\CacheableJsonResponse;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class FightTrainingController extends ControllerBase {
|
||||
|
||||
/*
|
||||
* Fields holding fighter data.
|
||||
*/
|
||||
protected $fields = [
|
||||
'age',
|
||||
'height',
|
||||
'reach',
|
||||
'leg_reach',
|
||||
'knockouts',
|
||||
'striking_accuracy',
|
||||
'strikes_per_minute',
|
||||
'sig_strike_defense',
|
||||
'absorbed_per_min',
|
||||
'standing_strikes',
|
||||
'clinch_strikes',
|
||||
'ground_strikes',
|
||||
'grappling_accuracy',
|
||||
'strikes_to_head',
|
||||
'strikes_to_body',
|
||||
'strikes_to_leg',
|
||||
'knockdown_ratio',
|
||||
'takedowns_per_15',
|
||||
'takedown_defense',
|
||||
'average_fight_time',
|
||||
'first_round_finishes',
|
||||
];
|
||||
|
||||
/**
|
||||
* The entity type manager service.
|
||||
*
|
||||
* @var Drupal\Core\Entity\EntityTypeManager
|
||||
* The entity type manager service.
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Public constructor.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
|
||||
* The entity type manager service.
|
||||
*
|
||||
*/
|
||||
public function __construct(
|
||||
EntityTypeManager $entityTypeManager
|
||||
) {
|
||||
$this->entityTypeManager = $entityTypeManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
// Instantiates this form class.
|
||||
return new static(
|
||||
// Load the service required to construct this class.
|
||||
$container->get('entity_type.manager'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all fighting data for training NN.
|
||||
*/
|
||||
public function generateTrainingData(): CacheableJsonResponse {
|
||||
// Go get all fights.
|
||||
$all_fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
|
||||
$training_data = [];
|
||||
foreach ($all_fights as $fight) {
|
||||
$train_array = [
|
||||
'input' => [],
|
||||
'output' => [],
|
||||
];
|
||||
// Ensure we have a winner.
|
||||
if (!$fight->field_result->target_id) {
|
||||
continue;
|
||||
}
|
||||
// Extract fighters.
|
||||
$fighter_one_id = $fight->field_fighter_one->target_id;
|
||||
$fighter_two_id = $fight->field_fighter_two->target_id;
|
||||
|
||||
if (!$fighter_one_id || !$fighter_two_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$fighter_one_data = $this->getFighterData($fighter_one_id);
|
||||
$fighter_two_data = $this->getFighterData($fighter_two_id, FALSE);
|
||||
|
||||
if (empty($fighter_one_data) || empty($fighter_two_data)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$train_array['input'] = array_merge($fighter_one_data, $fighter_two_data);
|
||||
|
||||
if ($fight->field_result->target_id == $fighter_one_id) {
|
||||
$train_array['output'] = [
|
||||
'fighter_one' => 1,
|
||||
'fighter_two' => 0,
|
||||
];
|
||||
$training_data[] = $train_array;
|
||||
}
|
||||
else if ($fight->field_result->target_id == $fighter_two_id) {
|
||||
$train_array['output'] = [
|
||||
'fighter_one' => 0,
|
||||
'fighter_two' => 1,
|
||||
];
|
||||
$training_data[] = $train_array;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return new CacheableJsonResponse($training_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves data about a specific fight for predictions.
|
||||
*/
|
||||
public function getFightData(NodeInterface $fight): CacheableJsonResponse {
|
||||
$fighter_1_id = $fight->field_fighter_one->target_id;
|
||||
$fighter_2_id = $fight->field_fighter_two->target_id;
|
||||
|
||||
$fight_data = array_merge(
|
||||
$this->getFighterData($fighter_1_id),
|
||||
$this->getFighterData($fighter_2_id, FALSE),
|
||||
);
|
||||
|
||||
return new CacheableJsonResponse($fight_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fighter data.
|
||||
*
|
||||
* @return array<string,mixed>
|
||||
*/
|
||||
private function getFighterData(int $id, bool $is_f1 = TRUE): array {
|
||||
if ($is_f1) {
|
||||
$prefix = 'fighter_one_';
|
||||
}
|
||||
else {
|
||||
$prefix = 'fighter_two_';
|
||||
}
|
||||
|
||||
$extracted_values = $this->extractValuesFromFields($id, $this->fields, $prefix);
|
||||
|
||||
return $this->normalizeData($extracted_values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a value from a given field (cannot be ent reference)
|
||||
*/
|
||||
private function extractValuesFromFields(int $id, array $field_names, string $prefix): mixed {
|
||||
$fighter = Node::load($id);
|
||||
$values = [];
|
||||
|
||||
foreach ($field_names as $field) {
|
||||
$value_key = $prefix . $field;
|
||||
$field_machine_name = 'field_' . $field;
|
||||
$values[$value_key] = $fighter->{$field_machine_name}->value ?? 0;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the field value.
|
||||
*
|
||||
* This needs to be between 0-1
|
||||
*/
|
||||
private function normalizeData(array $data): array {
|
||||
$min = min(array_values($data));
|
||||
$max = max(array_values($data));
|
||||
$normalized = [];
|
||||
foreach ($data as $key => $value) {
|
||||
$norm_val = 0;
|
||||
if ($max - $min == 0) {
|
||||
$normalized[$key] = $norm_val;
|
||||
}
|
||||
else {
|
||||
$norm_val = ($value - $min) / ($max - $min);
|
||||
$normalized[$key] = $norm_val;
|
||||
}
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trained neural network.
|
||||
*/
|
||||
public function getNeuralNetwork(): CacheableJsonResponse {
|
||||
$build = [];
|
||||
$cur_network = \Drupal::state()->get('neuralNetwork') ?? FALSE;
|
||||
if (!$cur_network) {
|
||||
$build['ERROR'] = "There is no spoon.";
|
||||
}
|
||||
else {
|
||||
$build['data'] = base64_decode($cur_network);
|
||||
}
|
||||
|
||||
return new CacheableJsonResponse($build);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user