Skip to content

Instantly share code, notes, and snippets.

@jasielmacedo
Last active June 4, 2021 20:04
Show Gist options
  • Save jasielmacedo/cec0ddb340ac5ab5a1e4d5f8cd055072 to your computer and use it in GitHub Desktop.
Save jasielmacedo/cec0ddb340ac5ab5a1e4d5f8cd055072 to your computer and use it in GitHub Desktop.
Código Exemplo de maquina de estado finito
const ESTADO_PARADO = 'parado';
const ESTADO_PATRULHANDO = 'patrulhando';
const ESTADO_PROCURANDO_INIMIGO = 'procurando';
const ESTADO_ATACANDO = 'atacando';
const ESTADO_MORTO = 'morto';
class Guardiao {
constructor() {
this.estado_atual = ESTADO_PARADO;
this.vida = 100;
this.alvo = null;
this.pode_patrulhar = true;
}
// funcao que sera responsavel por orquestrar os estados
maquinaDeEstado = () => {
if (this.vida <= 0) this.mudaDeEstado(ESTADO_MORTO);
switch (this.estado_atual) {
case ESTADO_PATRULHANDO:
this.processa_patrulhando();
break;
case ESTADO_PROCURANDO_INIMIGO:
this.processa_procurando();
break;
case ESTADO_ATACANDO:
this.processa_atacando();
break;
case ESTADO_MORTO:
this.processa_morto();
break;
case ESTADO_PARADO:
default:
this.processa_parado();
}
};
// evento chamado quando desejamos mudar o estado da maquina
// podemos simplesmente mudar a variavel, mas fazedo isso teremos mais controle
// possibilitando disparo de eventos quando essa ação ocorrer.
mudaDeEstado = novoEstado => {
if (novoEstado == this.estado_atual) return;
this.estado_atual = novoEstado;
console.log(`Novo estado: ${this.estado_atual}`);
};
processa_parado = () => {
// muda de estado quando encontra um alvo
if (this.verificaAlvoExisteEstaVivo()) this.mudaDeEstado(ESTADO_PROCURANDO_INIMIGO);
// se puder patrulhar muda para o estado de patrulha
if (this.pode_patrulhar) this.mudaDeEstado(ESTADO_PATRULHANDO);
};
processa_patrulhando = () => {
// simulamos aqui uma procura por alvos ao redor
this.verificaTemInimigosAoRedor();
// se o alvo foi encontrado e tiver vivo vamos atras dele
if (this.verificaAlvoExisteEstaVivo()) {
this.mudaDeEstado(ESTADO_PROCURANDO_INIMIGO);
return;
}
this.caminhaPraLaEPraCa();
// se por algum acaso ele nao puder mais patrulhar, voltamos a ficar parado
if (!this.pode_patrulhar) this.mudaDeEstado(ESTADO_PARADO);
};
processa_procurando = () => {
if (!this.verificaAlvoExisteEstaVivo()) {
this.mudaDeEstado(ESTADO_PARADO);
return;
}
// se aproxima do alvo
this.caminhaAteOAlvo();
if (this.verificaPossoAtacarOAlvo()) {
this.mudaDeEstado(ESTADO_ATACANDO);
return;
}
};
processa_atacando = () => {
// quer dizer que a missao foi cumprida posso voltar ao estado inicial
if (!this.verificaAlvoExisteEstaVivo()) {
this.mudaDeEstado(ESTADO_PARADO);
return;
}
this.ataque();
// se por alguma razao o alvo se afastou. precisamos corrigir isso.
if (this.verificaPossoAtacarOAlvo()) {
this.mudaDeEstado(ESTADO_PROCURANDO_INIMIGO);
return;
}
};
processa_morto = () => {
// se a vida aumentar, ressucita o guardiao
if (this.verificaEstouVivo()) this.mudaDeEstado(ESTADO_PARADO);
};
ataque = () => {
console.log('Atira contra o alvo');
this.alvo.vida -= 1;
};
caminhaPraLaEPraCa = () => {
console.log('Executa acao de caminhar');
};
caminhaAteOAlvo = () => {
console.log('Executa acao de caminhar ate o alvo');
};
verificaTemInimigosAoRedor = () => {
if (this.verificaAlvoExisteEstaVivo()) return;
// exemplo de alvo encontrado
this.alvo = new Guardiao();
};
verificaEstouVivo = () => this.vida > 0;
verificaAlvoExisteEstaVivo = () => !!this.alvo && this.alvo.verificaEstouVivo();
// simula um calculo de distancia
verificaPossoAtacarOAlvo = () => true;
}
const inimigoPrincipal = new Guardiao();
const fps = 30;
const maxSeconds = 20;
const interval = setInterval(inimigoPrincipal.maquinaDeEstado, 1000 / fps);
setTimeout(() => {
clearInterval(interval);
}, 1000 * maxSeconds);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment