Equidea

color.php

Nov 9th, 2019 (edited)
310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.96 KB | None | 0 0
  1. <?php
  2.  
  3. namespace Equidea\Engine;
  4.  
  5. // Base phenotypes
  6.  
  7. define('COLOR_BLACK', 1);
  8. define('COLOR_SEALBROWN', 2);
  9.  
  10. define('COLOR_BAY', 3);
  11. define('COLOR_WILDBAY', 4);
  12.  
  13. define('COLOR_CHESTNUT', 5);
  14. define('COLOR_FLAXEN_CHESTNUT', 6);
  15.  
  16. // Single cream phenotypes
  17.  
  18. define('COLOR_SMOKY_BLACK', 7);
  19. define('COLOR_SMOKY_BROWN', 8);
  20.  
  21. define('COLOR_BUCKSKIN', 9);
  22. define('COLOR_WILD_BUCKSKIN', 10);
  23.  
  24. define('COLOR_PALOMINO', 11);
  25.  
  26. // Double cream phenotypes
  27.  
  28. define('COLOR_SMOKY_CREAM', 12);
  29. define('COLOR_SEALBROWN_CREAM', 13);
  30.  
  31. define('COLOR_PERLINO', 14);
  32. define('COLOR_CREMELLO', 15);
  33.  
  34. /**
  35.  * An object representation of a full horse color genome.
  36.  *
  37.  * A genome contains many different locuses, which are the places where genetic
  38.  * information about color mutations and manipulation of molecules such as
  39.  * eumelanin and pheomelanin are stored.
  40.  *
  41.  * @see https://en.wikipedia.org/wiki/Equine_coat_color_genetics
  42.  *
  43.  * @author      Lisa Saalfrank <lisa.saalfrank@web.de>
  44.  * @copyright   2020 Lisa Saalfrank
  45.  * @package     Equidea\Engine
  46.  * @version     0.1.0
  47.  */
  48. class ColorDna
  49. {
  50.     public const GENE_CHECK_HOMOZYGOUS = true;
  51.     public const GENE_CHECK_HETEROZYGOUS = false;
  52.  
  53.     // Agouti
  54.  
  55.     public const AGOUTI_INACTIVE = 'a';
  56.     public const AGOUTI_SEALBROWN = 'at';
  57.     public const AGOUTI_BAY = 'A';
  58.     public const AGOUTI_WILDBAY = 'A+';
  59.  
  60.     // Extension
  61.  
  62.     public const EXTENSION_INACTIVE = 'e';
  63.     public const EXTENSION_ACTIVE = 'E';
  64.  
  65.     // Flaxen
  66.  
  67.     public const FLAXEN_INACTIVE = 'F';
  68.     public const FLAXEN_ACTIVE = 'f';
  69.  
  70.     // Cream
  71.  
  72.     public const CREAM_INACTIVE = 'cr'
  73.     public const CREAM_ACTIVE = 'Cr';
  74.  
  75.     protected array $agouti = [
  76.         self::AGOUTI_INACTIVE,
  77.         self::AGOUTI_INACTIVE
  78.     ];
  79.  
  80.     protected array $extension = [
  81.        self::EXTENSION_INACTIVE,
  82.        self::EXTENSION_INACTIVE
  83.     ];
  84.  
  85.     protected array $flaxen = [
  86.         self::FLAXEN_INACTIVE,
  87.         self::FLAXEN_INACTIVE
  88.     ];
  89.  
  90.     protected array $cream = [
  91.         self::CREAM_INACTIVE,
  92.         self::CREAM_INACTIVE
  93.     ];
  94.  
  95.     public function getAgouti() : array {
  96.         return $this->agouti;
  97.     }
  98.  
  99.     public function getExtension() : array {
  100.         return $this->extension;
  101.     }
  102.  
  103.     public function getFlaxen() : array {
  104.         return $this->flaxen;
  105.     }
  106.  
  107.     public function getCream() : array {
  108.         return $this->cream;
  109.     }
  110.  
  111.     public function agoutiHas(string $gene) : bool {
  112.         return in_array($gene, $this->agouti);
  113.     }
  114.  
  115.     public function extensionHas(string $gene) : bool {
  116.         return in_array($gene, $this->extension);
  117.     }
  118.  
  119.     public function flaxenHas(string $gene) : bool {
  120.         return in_array($gene, $this->flaxen);
  121.     }
  122.  
  123.     public function creamHas(string $gene, bool $type = false) : bool
  124.     {
  125.         if ($type == true) {
  126.             return $this->cream[0] == $gene && $this->cream[1] == $gene;
  127.         }
  128.  
  129.         return in_array($gene, $this->cream);
  130.     }
  131.  
  132.     public function setAllAlleles(array $dna) : void
  133.     {
  134.         $this->agouti = $dna['agouti'];
  135.         $this->extension = $dna['extension'];
  136.         $this->flaxen = $dna['flaxen'];
  137.         $this->cream = $dna['cream'];
  138.     }
  139.  
  140.     public function getAllAlleles() : array
  141.     {
  142.         return [
  143.             'agouti' => $this->agouti,
  144.             'extension' => $this->extension,
  145.             'flaxen' => $this->flaxen,
  146.             'cream' => $this->cream
  147.         ];
  148.     }
  149.  
  150.     public function importJson(array $jsonDna) : void
  151.     {
  152.         $this->agouti = json_decode($jsonDna['agouti']);
  153.         $this->extension = json_decode($jsonDna['extension']);
  154.         $this->flaxen = json_decode($jsonDna['flaxen']);
  155.         $this->cream = json_decode($jsonDna['cream']);
  156.     }
  157.  
  158.     public function exportJson() : array
  159.     {
  160.         return [
  161.             'agouti' => json_encode($this->agouti),
  162.             'extension' => json_encode($this->extension),
  163.             'flaxen' => json_encode($this->flaxen),
  164.             'cream' => json_encode($this->cream)
  165.         ];
  166.     }
  167. }
  168.  
  169. // Color inheritance
  170.  
  171. function inheritColorDna(ColorDna $mother, ColorDna $father) : ColorDna
  172. {
  173.     $randomGene = function(array $genes) : string {
  174.         return $genes[array_rand($genes)];
  175.     };
  176.  
  177.     $motherAlleles = $mother->getAllAlleles();
  178.     $fatherAlleles = $father->getAllAlleles();
  179.  
  180.     $childAlleles = [];
  181.  
  182.     foreach (array_keys($motherAlleles) as $allele)
  183.     {
  184.         $childAlleles[$allele] = [
  185.             $randomGene($motherAlleles[$allele]),
  186.             $randomGene($fatherAlleles[$allele])
  187.         ];
  188.     }
  189.  
  190.     $child = new ColorDna();
  191.     $child->setAllAlleles($childAlleles);
  192.     return $child;
  193. }
  194.  
  195. // Color calculation
  196.  
  197. function findBasePhenotype(ColorDna $dna) : int
  198. {
  199.     if ($dna->extensionHas(ColorDna::EXTENSION_ACTIVE))
  200.     {
  201.         if ($dna->agoutiHas(ColorDna::AGOUTI_WILDBAY)) {
  202.             return COLOR_WILDBAY;
  203.         }
  204.  
  205.         if ($dna->agoutiHas(ColorDna::AGOUTI_BAY)) {
  206.             return COLOR_BAY;
  207.         }
  208.  
  209.         if ($dna->agoutiHas(ColorDna::AGOUTI_SEALBROWN)) {
  210.             return COLOR_SEALBROWN;
  211.         }
  212.  
  213.         return COLOR_BLACK;
  214.     } else
  215.     {
  216.         if (!$dna->flaxenHas(ColorDna::FLAXEN_INACTIVE)) {
  217.             return COLOR_FLAXEN_CHESTNUT;
  218.         }
  219.  
  220.         return COLOR_CHESTNUT;
  221.     }
  222. }
  223.  
  224. function hasDoubleCreamPhenotype(ColorDna $dna) : bool
  225. {
  226.     return $dna->creamHas(
  227.         ColorDna::CREAM_ACTIVE,
  228.         ColorDna::GENE_CHECK_HOMOZYGOUS
  229.     );
  230. }
  231.  
  232. function findSingleCreamPhenotype(int $base) : int
  233. {
  234.     switch ($base)
  235.     {
  236.         case COLOR_BLACK: return COLOR_SMOKY_BLACK;
  237.         case COLOR_SEALBROWN: return COLOR_SMOKY_BROWN;
  238.  
  239.         case COLOR_BAY: return COLOR_BUCKSKIN;
  240.         case COLOR_WILDBAY: return COLOR_WILD_BUCKSKIN;
  241.  
  242.         case COLOR_CHESTNUT:
  243.         case COLOR_FLAXEN_CHESTNUT: return COLOR_PALOMINO;
  244.     }
  245. }
  246.  
  247. function findDoubleCreamPhenotype(int $base) : int
  248. {
  249.     switch ($base)
  250.     {
  251.         case COLOR_BLACK: return COLOR_SMOKY_CREAM;
  252.         case COLOR_SEALBROWN: return COLOR_SEALBROWN_CREAM;
  253.  
  254.         case COLOR_BAY:
  255.         case COLOR_WILDBAY: return COLOR_PERLINO;
  256.  
  257.         case COLOR_CHESTNUT:
  258.         case COLOR_FLAXEN_CHESTNUT: return COLOR_CREMELLO;
  259.     }
  260. }
  261.  
  262. function findBirthPhenotype(ColorDna $dna) : int
  263. {
  264.     $base = findBasePhenotype($dna);
  265.  
  266.     if ($dna->creamHas(ColorDna::CREAM_ACTIVE))
  267.     {
  268.         if (hasDoubleCreamPhenotype($dna)) {
  269.             return findDoubleCreamPhenotype($base);
  270.         }
  271.  
  272.         return findSingleCreamPhenotype($base);
  273.     }
  274.  
  275.     return $base;
  276. }
  277.  
  278.  
  279.  
  280.  
  281. function hasGreyPhenotype(ColorDna $dna) : bool
  282. {
  283.     return !$dna->greyHas(
  284.         ColorDna::GREY_INACTIVE,
  285.         ColorDna::GENE_CHECK_HOMOZYGOUS
  286.     );
  287. }
  288.  
  289. function findIntermediateGreyPhenotype(int $base) : int
  290. {
  291.     switch ($base)
  292.     {
  293.         case COLOR_BLACK: return COLOR_BLACK_GREY;
  294.         case COLOR_SEALBROWN: return COLOR_SEALBROWN_GREY;
  295.  
  296.         case COLOR_BAY: return COLOR_BAY_GREY;
  297.         case COLOR_WILDBAY: return COLOR_WILDBAY_GREY;
  298.  
  299.         case COLOR_CHESTNUT: return COLOR_FLAXEN_CHESTNUT_GREY;
  300.         case COLOR_FLAXEN_CHESTNUT: return COLOR_FLAXEN_CHESTNUT_GREY;
  301.  
  302.         case COLOR_SMOKY_BLACK: return COLOR_SMOKY_BLACK_GREY;
  303.         case COLOR_SMOKY_BROWN: return COLOR_SMOKY_BROWN_GREY;
  304.  
  305.         case COLOR_BUCKSKIN: return COLOR_BUCKSKIN_GREY;
  306.         case COLOR_WILD_BUCKSKIN: return COLOR_WILD_BUCKSKIN_GREY;
  307.  
  308.         case COLOR_PALOMINO: return COLOR_PALOMINO_GREY;
  309.     }
  310. }
  311.  
  312. function findFinalGreyPhenotype(ColorDna $dna) : int
  313. {
  314.     if ($dna->greyHas(ColorDna::GREY_NORMAL))
  315.     {
  316.         $isNormalHomozygous = $dna->greyHas(
  317.             ColorDna::GREY_NORMAL,
  318.             ColorDna::GENE_CHECK_HOMOZYGOUS
  319.         );
  320.  
  321.         if ($isNormalHomozygous == true) {
  322.             return COLOR_SOLID_GREY;
  323.         }
  324.  
  325.         return COLOR_FLEABITTEN_GREY;
  326.     }
  327.  
  328.     return COLOR_DAPPLE_GREY;
  329. }
  330.  
Add Comment
Please, Sign In to add comment