Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

164
Visualizações
How to write a state machine so that I don't have to duplicate states with 99% similar code?

I am making an city management game, where workers are completely controlled by state machines. I have an "issue" where I find my self re-writing a lot of states that are 99% similar. Usually the only difference in some of the states is which state it should go to when it is completed.

For example, the below state is used for delivering resources, this is something all professions do but I have a write a specific one for each profession, since they all lead to different states on complete.

public class BakerDeliverGrainState : BaseWorkerState, IState
{
    public void Enter()
    {
        //Go to storage
        SetDestination(storage.position);
    }

    public void Execute()
    {
        if (unit.ReachedDestination())
        {
            //Reached destination, state completed
            storage.Store(unit.TakeResource());
            unit.stateMachine.ChangeState(new BakerWorkState(unit)); //This is the line that seperates the states. For example a blacksmith will go to "BlacksmithWorkState", and so on.
        }
    }

    public void Exit()
    {
        
    }
}

Is there some way I can pass which state to change to in a constructor? Or some other way I can adjust my design that will not require me to re-write so much code.

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

How about passing an anonymous function into the constructor which will create the new state?

public class BaseWorkerState
{
   protected Func<Unit, IState> createCompletedState;
  
   // Use this constructor for states where you don't need to customize the
   // next state
   public BaseWorkerState()
   {
   }

   // Use this constructor for states where you do need to customize the 
   // next state
   public BaseWorkerState(Func<Unit, IState> createCompletedState)
   {
      this.createCompletedState = createCompletedState;
   }
}

public class BakerDeliverGrainState : BaseWorkerState, IState
{
   public BakerDeliverGrainState(Func<Unit, IState> createCompletedState) 
      : base(createCompletedState)
   {
   }

   public void Execute()
   {
      if (unit.ReachedDestination())
      {
         // Reached destination, state completed
         storage.Store(unit.TakeResource());
         unit.stateMachine.ChangeState(this.createCompletedState(unit));
       }
   }
}

Then when you create a state for each unit type, you can pass in a function that will create the appropriate "on complete" state (I'm guessing at the architecture of your Unit class).

// When the baker is done delivering grain, he'll go into this state
public class BakerIdleState: IState
{
   public BakerIdleState(Unit unit) : base(unit)
   {
   }  
}

public class Baker : Unit
{
   public void DeliverGrain()
   {
      var newState = new BakerDeliverGrainState(unit => 
      {
         return new BakerIdleState(unit);
      }); 
      this.stateMachine.ChangeState(newState);
   }
}

Of course, if the child state (BakerIdleState) also required customization, then you'd have to do the same thing to set that state's next state and this would grow more complicated.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda