Skip to content

Instantly share code, notes, and snippets.

@coproduto
Last active January 5, 2024 16:07
Show Gist options
  • Save coproduto/5656c3cd7e0f2eed6ccd08f26bb4fd26 to your computer and use it in GitHub Desktop.
Save coproduto/5656c3cd7e0f2eed6ccd08f26bb4fd26 to your computer and use it in GitHub Desktop.
const makeRuleSet = (rules) =>
new Map(
rules
.flat()
.map(([lprop, rprop, effects]) => [[lprop, rprop], effects])
);
const simpleRule = (rule) => [rule];
const commutativeRule = (rule) => [rule, reverseRule(rule)]
const reverseRule = (rule) => {
const [lprop, rprop, effect] = rule;
return [rprop, lprop, effect];
};
// uma regra é dada por uma tripla [propriedade, propriedade, efeito]
// um efeito é um array de novas propriedades que devem ser adicionadas ou retiradas
// à entidade sobre a qual a avaliação de regras está sendo feita
// a regra abaixo indica que quando um objeto pegando fogo interage com um objeto
// inflamável, o objeto inflamável deve pegar fogo, e que a regra vale nos dois sentidos
// (i.e. se um objeto inflamável interage com um objeto pegando fogo, o mesmo ocorre)
const flammabilityRule = commutativeRule(['on_fire', 'flammable', [['add_property', 'on_fire']]]);
// a regra abaixo indica que quando um objeto molhado interage com um objeto
// pegando fogo, esse objeto apaga, e vale nos dois sentidos
const quenchRule = commutativeRule(['on_fire', 'wet', [['remove_property', 'on_fire']]]);
// a regra abaixo indica que quando um objeto pesado interage com um objeto frágil,
// o objeto frágil quebra. Essa regra não vale nos dois sentidos.
const crushRule = simpleRule(['heavy', 'fragile', [['add_property', 'crushed']]]);
// a função applyRuleSet recebe as propriedades de dois objetos que interagem
// e retorna os efeitos a serem aplicados sobre o segundo objeto
const applyRuleSetOnRight = (ruleSet, leftProperties, rightProperties) => {
let results = [];
for (const lprop of leftProperties) {
for (const rprop of rightProperties) {
const effects = ruleSet.get([lprop, rprop]);
if (effects) {
results = results.concat(effects);
}
}
}
return results;
};
const ruleSet = makeRuleSet([flammabilityRule, quenchRule, crushRule]);
// Aí pra cada par de objetos objA, objB que pode interagir você chamaria
// applyRuleSetOnRight(ruleSet, objA.properties, objB.properties);
// e aí o valor de retorno seriam as alterações a aplicar no objB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment