Какой-то базовый расчёт, просто вероятности без ничего
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
|
use app\models\ComputationResult;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\filters\AccessControl;
|
use yii\filters\AccessControl;
|
||||||
use yii\web\Controller;
|
use yii\web\Controller;
|
||||||
@@ -9,6 +10,7 @@ use yii\web\Response;
|
|||||||
use yii\filters\VerbFilter;
|
use yii\filters\VerbFilter;
|
||||||
use app\models\LoginForm;
|
use app\models\LoginForm;
|
||||||
use app\models\ContactForm;
|
use app\models\ContactForm;
|
||||||
|
use app\models\DeckForm;
|
||||||
|
|
||||||
class SiteController extends Controller
|
class SiteController extends Controller
|
||||||
{
|
{
|
||||||
@@ -18,23 +20,6 @@ class SiteController extends Controller
|
|||||||
public function behaviors()
|
public function behaviors()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'access' => [
|
|
||||||
'class' => AccessControl::class,
|
|
||||||
'only' => ['logout'],
|
|
||||||
'rules' => [
|
|
||||||
[
|
|
||||||
'actions' => ['logout'],
|
|
||||||
'allow' => true,
|
|
||||||
'roles' => ['@'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'verbs' => [
|
|
||||||
'class' => VerbFilter::class,
|
|
||||||
'actions' => [
|
|
||||||
'logout' => ['post'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,10 +32,6 @@ class SiteController extends Controller
|
|||||||
'error' => [
|
'error' => [
|
||||||
'class' => 'yii\web\ErrorAction',
|
'class' => 'yii\web\ErrorAction',
|
||||||
],
|
],
|
||||||
'captcha' => [
|
|
||||||
'class' => 'yii\captcha\CaptchaAction',
|
|
||||||
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,68 +42,18 @@ class SiteController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function actionIndex()
|
public function actionIndex()
|
||||||
{
|
{
|
||||||
return $this->render('index');
|
$computation_result = new ComputationResult();
|
||||||
}
|
$deck_form = new DeckForm();
|
||||||
|
if ($deck_form->load(Yii::$app->request->post()))
|
||||||
/**
|
|
||||||
* Login action.
|
|
||||||
*
|
|
||||||
* @return Response|string
|
|
||||||
*/
|
|
||||||
public function actionLogin()
|
|
||||||
{
|
{
|
||||||
if (!Yii::$app->user->isGuest) {
|
if ($deck_form->validate())
|
||||||
return $this->goHome();
|
{
|
||||||
|
$computation_result = $deck_form->compute();
|
||||||
}
|
}
|
||||||
|
|
||||||
$model = new LoginForm();
|
|
||||||
if ($model->load(Yii::$app->request->post()) && $model->login()) {
|
|
||||||
return $this->goBack();
|
|
||||||
}
|
}
|
||||||
|
return $this->render('index', [
|
||||||
$model->password = '';
|
'deck_form' => $deck_form,
|
||||||
return $this->render('login', [
|
'result' => $computation_result,
|
||||||
'model' => $model,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logout action.
|
|
||||||
*
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
public function actionLogout()
|
|
||||||
{
|
|
||||||
Yii::$app->user->logout();
|
|
||||||
|
|
||||||
return $this->goHome();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays contact page.
|
|
||||||
*
|
|
||||||
* @return Response|string
|
|
||||||
*/
|
|
||||||
public function actionContact()
|
|
||||||
{
|
|
||||||
$model = new ContactForm();
|
|
||||||
if ($model->load(Yii::$app->request->post()) && $model->contact(Yii::$app->params['adminEmail'])) {
|
|
||||||
Yii::$app->session->setFlash('contactFormSubmitted');
|
|
||||||
|
|
||||||
return $this->refresh();
|
|
||||||
}
|
|
||||||
return $this->render('contact', [
|
|
||||||
'model' => $model,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays about page.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function actionAbout()
|
|
||||||
{
|
|
||||||
return $this->render('about');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
class ComputationResult
|
||||||
|
{
|
||||||
|
public $probabilities = [];
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\models;
|
||||||
|
|
||||||
|
use Yii;
|
||||||
|
use yii\base\Model;
|
||||||
|
|
||||||
|
class DeckForm extends Model
|
||||||
|
{
|
||||||
|
const COMPUTE_TRIES = 10000;
|
||||||
|
const COMPUTE_ROUNDS = 10;
|
||||||
|
|
||||||
|
const CARD_ANY = 0;
|
||||||
|
const CARD_WEAPON_ITEM = 1;
|
||||||
|
const CARD_WEAPON_SPELL = 2;
|
||||||
|
const CARD_PREPARED = 3;
|
||||||
|
const CARD_BACKPACK_0 = 4;
|
||||||
|
const CARD_BACKPACK_2 = 5;
|
||||||
|
const CARD_INITIATE = 6;
|
||||||
|
|
||||||
|
public $size = 30;
|
||||||
|
public $weapons_items = 0;
|
||||||
|
public $weapons_spells = 0;
|
||||||
|
public $card_prepared_to_worst = 0;
|
||||||
|
public $card_backpack_0 = 0;
|
||||||
|
public $card_backpack_2 = 0;
|
||||||
|
public $card_initiate = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array the validation rules.
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['size', 'weapons_items', 'weapons_spells', 'card_prepared_to_worst', 'card_backpack_0', 'card_backpack_2', 'card_initiate'], 'required'],
|
||||||
|
[['size', 'weapons_items', 'weapons_spells', 'card_prepared_to_worst', 'card_backpack_0', 'card_backpack_2', 'card_initiate'], 'integer'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array customized attribute labels
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'size' => 'Размер колоды',
|
||||||
|
'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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
-42
@@ -1,53 +1,40 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/** @var yii\web\View $this */
|
use yii\bootstrap5\ActiveForm;
|
||||||
|
use yii\helpers\Html;
|
||||||
|
|
||||||
$this->title = 'My Yii Application';
|
$this->title = 'Карточный ужас Аркхэма. Калькулятор вероятностей.';
|
||||||
?>
|
?>
|
||||||
<div class="site-index">
|
<div class="site-index">
|
||||||
|
|
||||||
<div class="jumbotron text-center bg-transparent mt-5 mb-5">
|
|
||||||
<h1 class="display-4">Congratulations!</h1>
|
|
||||||
|
|
||||||
<p class="lead">You have successfully created your Yii-powered application.</p>
|
|
||||||
|
|
||||||
<p><a class="btn btn-lg btn-success" href="https://www.yiiframework.com">Get started with Yii</a></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="body-content">
|
<div class="body-content">
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-4 mb-3">
|
<div class="col-md-6">
|
||||||
<h2>Heading</h2>
|
<h3>Параметры колоды</h3>
|
||||||
|
<?php $form = ActiveForm::begin([
|
||||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
|
'layout' => 'horizontal' ,
|
||||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
|
'class' => 'form-horizontal' ,
|
||||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
]); ?>
|
||||||
fugiat nulla pariatur.</p>
|
<?= $form->field($deck_form, 'size')->textInput(); ?>
|
||||||
|
<?= $form->field($deck_form, 'weapons_items')->textInput(); ?>
|
||||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/doc/">Yii Documentation »</a></p>
|
<?= $form->field($deck_form, 'weapons_spells')->textInput(); ?>
|
||||||
</div>
|
<?= $form->field($deck_form, 'card_prepared_to_worst')->textInput(); ?>
|
||||||
<div class="col-lg-4 mb-3">
|
<?= $form->field($deck_form, 'card_backpack_0')->textInput(); ?>
|
||||||
<h2>Heading</h2>
|
<?= $form->field($deck_form, 'card_backpack_2')->textInput(); ?>
|
||||||
|
<?= $form->field($deck_form, 'card_initiate')->textInput(); ?>
|
||||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
|
<?= Html::submitButton(); ?>
|
||||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
|
<?php $form->end(); ?>
|
||||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
|
||||||
fugiat nulla pariatur.</p>
|
|
||||||
|
|
||||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/forum/">Yii Forum »</a></p>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4">
|
|
||||||
<h2>Heading</h2>
|
|
||||||
|
|
||||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
|
|
||||||
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
|
|
||||||
ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
|
|
||||||
fugiat nulla pariatur.</p>
|
|
||||||
|
|
||||||
<p><a class="btn btn-outline-secondary" href="https://www.yiiframework.com/extensions/">Yii Extensions »</a></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<ul>
|
||||||
|
<?php for ($i = 0; $i < count($result->probabilities); $i++): ?>
|
||||||
|
<li>Ход <?= ($i + 1); ?>: <?= sprintf("%.3f", $result->probabilities[$i] * 100); ?>%</li>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user