Eu tenho o próximo problema.
Um item pode ter muitos estados:
NORMAL = 0000000
DRY = 0000001
HOT = 0000010
BURNING = 0000100
WET = 0001000
COLD = 0010000
FROZEN = 0100000
POISONED= 1000000
Um item pode ter alguns estados ao mesmo tempo, mas nem todos
- É impossível estar seco e molhado ao mesmo tempo.
- Se você FRIO um item MOLHADO, ele se transforma em CONGELADO.
- Se você aquece um item MOLHADO, ele se transforma em NORMAL
- Um item pode ser QUEIMADOR e VENENO
Etc.
Tentei definir sinalizadores binários para estados e use AND para combinar estados diferentes, verificando antes se é possível ou não fazê-lo ou mude para outro status.
Existe uma abordagem concreta para resolver esse problema de maneira eficiente, sem ter uma opção interminável que verifique cada estado com cada novo estado?
É relativamente fácil verificar dois estados diferentes, mas se existe um terceiro estado, não é trivial.
c++
rpg
design-patterns
binary
vgonisanz
fonte
fonte
Respostas:
Quando preciso usar sinalizadores, geralmente faço algo nesse sentido.
Isso torna muito fácil usá-los para coisas como apply_cold () e você pode obviamente criar em seu estado condições como seco e úmido.
fonte
Duas observações:
COLD
eHOT
são transições da maneira que você as menciona, não estados.A combinação dessas observações resultaria em algo assim:
fonte
Representando seus estados como máscara de bits como você escreve, você pode apenas traduzir suas descrições das restrições em código:
Você pode agrupar isso em um
makeStateConsistent()
que você pode chamar antes de testar os bits de estado para garantir que o estado faça sentido.No entanto, uma limitação dessa abordagem é que ela não pode explicar a ordem das mudanças de estado. Por exemplo, se você deseja obter um resultado diferente para itens quentes que ficam úmidos do que para itens quentes que ficam quentes, não é possível fazer o seguinte: tudo o
makeStateConsistent()
que o método vê é um objeto quente e úmido, sem informações sobre como tem que ser assim.Em vez disso, o que você poderia fazer é tornar o estado do item privado (pelo menos conceitualmente) e manipulá-lo através de um conjunto de métodos como
coolItem()
,heatItem()
,wetItem()
,dryItem()
e assim por diante. Dessa forma, os próprios métodos de mudança de estado podem cuidar de quaisquer alterações adicionais. Por exemplo, oheatItem()
método pode ser algo como isto:Obviamente, você ainda pode querer ter um
makeStateConsistent()
método como backup, caso tenha algum erro nos métodos de alteração de estado.Além disso, em alguns casos, você pode simplificar seu código eliminando estados desnecessários. Por exemplo, você realmente precisa de um
FROZEN
estado separado ou seria suficiente apenas tratar itens frios e molhados como congelados?fonte