Пишу игровой портал, вот возник вопрос с реализацией универсальных правил. Пытался уже это дело реализовать и накосячил, вот приходится переделывать.
Значит в чем суть, пользователь создает игру в дурака к примеру, ожидает соперника и играет.
Создать игру можно выбрав правила:
- Кол-во игроков (2, 3, 4)
- На пару или каждый сам за себя
- Время хода (30 сек, 2 минуты и тп.)
- ставка (на интерес или на рейтинг)
....
Архитектура такая:
Есть таблица всех правил
games_rules
Правила выглядят примерно так:
rule_id: 1
parent_rule_id: 0
name: count_player
value: Количество игроков
options: {"0":{"value":2,"description":"Два игрока"},"1":{"value":3,"description":"Три игрока"},"2":{"value":4,"description":"Четыре игрока"}}
options - это возможные варианты для выбора. В некоторых играх нам придется ограничивать выбор, например в шашки могут играть только 2 игрока.
Далее есть таблица
games
Где в поле rule я указываю возможные правила:
{"0":{"rule_id":10,"values":{"0":"all"}},"2":{"rule_id":1,"values":{"0":"all"}},"3":{"rule_id":3,"values":{"0":"all"}},"4":{"rule_id":2,"values":{"0":"all"}},"5":{"rule_id":4,"values":{"0":"all"}},"6":{"rule_id":5,"values":{"0":"2"}}}
"rule_id":10,"values":{"0":"all"} - к примеру правило с идентификатором 10 может использовать все варианты
"rule_id":5,"values":{"0":"2"} - правило 5 может использовать только 2 вариант
И так далее.
Основная суть:
У нас есть несколько игр и каждая игра содержит определенные правила с определенными вариантами для выбора.
Теперь как это работает:
Когда пользователь попадает на страницу для создания новой игры, я исходя из допустимых правил игры достаю данные из таблицы правил и рисую ему на экран input и select для выбора правил.
Пользователь выбирает себе правила для игры и создает заявку. В этот момент на сервере я опять по такому же принципу проверяю действительно ли пользователь может вводить такие вот значения и тп.
Для примера выглядит это вот так:public function checkRules($attribute,$params)
{
$game = GamesModel::model()->findByPk($this->game_id);
$result = array();
if($game)
{
//$game->rules = @json_decode($game->rules, true);
if($game->rules)
{
$getRulesPrintArray = RuleOperations::load()->getRulesPrintArray($game->rules);
foreach($getRulesPrintArray as $ruleData)
{
if(!array_key_exists($ruleData['name'], $this->user_rules))
{
$this->addError($attribute, 'Правило "'.$ruleData['value'].'" не передано ');
}
else
{
//$this->user_rules[$ruleData['name']] - указанное правило пользователя
// проверяем может ли пользователь указать текущее значение для правила
if(!ProcessingData::load()->array_find_val($this->user_rules[$ruleData['name']], $ruleData['options']))
{
$this->addError($attribute, 'Указан неверный параметр '.$this->user_rules[$ruleData['name']].', правило: '.$ruleData['value']);
}
$result[] = array('rule'=>$ruleData['name'], 'param'=>$this->user_rules[$ruleData['name']], 'childs'=>$ruleData['childs']);
}
}
// все проверенные правила игры
$this->rules = $result;
}
else
{
$this->addError($attribute, 'Заявка не может быть создана, так как нет правил для игры');
}
}
else
{
$this->addError($attribute, 'Текущая игра №'.$this->game_id.' не найдена в базе данных');
}
}
Теперь подобрались к сути вопроса
Все эта канитель с правилами нужна для того, что бы легко можно было добавлять правила или удалять правила из игр, а так же их менять.
Проблема появилась тут:
К примеру пользователь может играть на интерес, а может на рейтинг или на деньги или еще на что. Тоесть когда идет игра на интерес все хорошо, проблем нет. Когда игра идет на рейтинг, нужно дополнительное правило (bet, ставка).
Вот тут я ломаю голову. Во всех правилах у нас есть четкие варианты выбора. Тоесть либо игра на пары либо нет (1 или 0, друго-го нет). В даном же случае пользователь должен сам ввести значения правил. А если еще нужно ограничить диапазон ставки, к примеру он может ставить от 1 единицы до 1000 единиц.
Получается мне в мой цикл проверки значений правил нужно дописывать еще проверку на номер правила (если есть правило ставка), то нужно проверить его значение. А если таких правил которые подрозумивают свободный ввод значение будет несколько, но нужно для каждого правила лепить проверку. Собственно код разрастется и постоянно нужно будет туда лазить.
Отсюда появилась идея как бы это все дело оптимизировать и записать фильтры-правил в базу данных. Но не как не получается сделать это на практике. Покапал в сторону паттерна стратегии, но все равно пока нет идей как бы это все зауниверсалить.
Подскажите пожалуйста как можно такое дело сделать универсальным, что бы можно можно было сделать какие то фильтры правил. К примеру добавить в таблицу правил поле фильтры и как-то там шамать