nepster-web
@nepster-web

Правила игры, проверка правил?

Пишу игровой портал, вот возник вопрос с реализацией универсальных правил. Пытался уже это дело реализовать и накосячил, вот приходится переделывать.

Значит в чем суть, пользователь создает игру в дурака к примеру, ожидает соперника и играет.
Создать игру можно выбрав правила:
- Кол-во игроков (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 единиц.

Получается мне в мой цикл проверки значений правил нужно дописывать еще проверку на номер правила (если есть правило ставка), то нужно проверить его значение. А если таких правил которые подрозумивают свободный ввод значение будет несколько, но нужно для каждого правила лепить проверку. Собственно код разрастется и постоянно нужно будет туда лазить.

Отсюда появилась идея как бы это все дело оптимизировать и записать фильтры-правил в базу данных. Но не как не получается сделать это на практике. Покапал в сторону паттерна стратегии, но все равно пока нет идей как бы это все зауниверсалить.

Подскажите пожалуйста как можно такое дело сделать универсальным, что бы можно можно было сделать какие то фильтры правил. К примеру добавить в таблицу правил поле фильтры и как-то там шамать
  • Вопрос задан
  • 2848 просмотров
Решения вопроса 1
@rowdyro
Я бы ввел в таблицу games_rules параметр type, который может принимать значения:
'choice', 'range'.

В случае choice параметр options содержит json
key=>value
В случае range
min=>{MIN_VALUE}, max=>{MAX_VALUE}

Дальше делаете классы для каждого type, которые знают свой формат options, знают как проверять условия и какой рисовать контрол (select,input & etc). Оборачиваете все это дело в фабрику профит.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Моё личное мнение:
- У Вас неправильный подход к организации хранения игровых данных.
Избавляйтесь от лишних таблиц с правилами, т.е. загоняйте все данные в одну таблицу. Вам нужна одна таблица с состоянием игры и правилами сразу. Проверку на возможность условий (правил) нужно выполнить на уровне скриптов, как и серверных, так и клиентских. С таким подходом вся ваша работа будет с одной таблицей, никаких сложных запросов и мучений.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы