'Размер колоды', 'weapons_items' => 'Оружие (вещь)', 'weapons_spells' => 'Оружие (заклинание)', 'card_prepared_to_worst' => 'Готовность к худшему', 'card_backpack_0' => 'Рюкзак (0)', 'card_backpack_2' => 'Рюкзак (2)', 'card_initiate' => 'Посвящённая', ]; } private $result; public function compute() : ComputationResult { $this->result = new ComputationResult(); $this->result->probabilities = []; for ($i = 0; $i < self::COMPUTE_ROUNDS; $i++) $this->result->probabilities[] = 0; for ($i = 0; $i < self::COMPUTE_TRIES; $i++) { $this->generateTry(); } for ($i = 0; $i < self::COMPUTE_ROUNDS; $i++) $this->result->probabilities[$i] /= (self::COMPUTE_TRIES + 0.0); return $this->result; } private $deck; private $hand; private function fillDeck() { $this->deck = []; for ($i = 0; $i < $this->size; $i++) $this->deck[] = self::CARD_ANY; $pos = 0; for ($i = 0; $i < $this->weapons_items && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_WEAPON_ITEM; } for ($i = 0; $i < $this->weapons_spells && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_WEAPON_SPELL; } for ($i = 0; $i < $this->card_backpack_0 && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_BACKPACK_0; } for ($i = 0; $i < $this->card_backpack_2 && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_BACKPACK_2; } for ($i = 0; $i < $this->card_prepared_to_worst && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_PREPARED; } for ($i = 0; $i < $this->card_initiate && $pos < count($this->deck); $i++) { $this->deck[$pos++] = self::CARD_INITIATE; } } private function shuffleDeck() { for ($i = 0; $i < count($this->deck); $i++) { $j = rand(0, $i); $t = $this->deck[$j]; $this->deck[$j] = $this->deck[$i]; $this->deck[$i] = $t; } } private function addProb($round) { for ($i = $round; $i < self::COMPUTE_ROUNDS; $i++) $this->result->probabilities[$i]++; } private function haveWeapon() { foreach ($this->hand as $card) { if ($card == self::CARD_WEAPON_ITEM) return true; if ($card == self::CARD_WEAPON_SPELL) return true; } return false; } private function generateTry() { $this->fillDeck(); $this->shuffleDeck(); // mulligan $this->hand = []; $replace = []; for ($i = 0; $i < 5; $i++) { $current = array_pop($this->deck); if ($current != self::CARD_ANY) $this->hand[] = $current; else $replace[] = $current; } while (count($this->hand) < 5) $this->hand[] = array_pop($this->deck); foreach ($replace as $r) $this->deck[] = $r; $this->shuffleDeck(); for ($round = 0; $round < self::COMPUTE_ROUNDS; $round++) { if ($this->haveWeapon()) { $this->addProb($round); return; } } } }