Я решил проблему так:
class States_path
{
public enum States
{
RESET,
IDLE,
DRSELECT,
DRCAPTURE,
DRSHIFT,
DRPAUSE,
DREXIT1,
DREXIT2,
DRUPDATE,
IRSELECT,
IRCAPTURE,
IRSHIFT,
IRPAUSE,
IREXIT1,
IREXIT2,
IRUPDATE
}
private States NextState(States current_states, bool tms)
{
switch (current_states)
{
case States.RESET:
return tms ? States.RESET : States.IDLE;
case States.IDLE:
return tms ? States.DRSELECT : current_states;
case States.DRSELECT:
return tms ? States.IRSELECT : States.DRCAPTURE;
case States.IRSELECT:
return tms ? States.RESET : States.IRCAPTURE;
case States.DRCAPTURE:
return tms ? States.DREXIT1 : States.DRSHIFT;
case States.DRSHIFT:
return tms ? States.DREXIT1 : current_states;
case States.DREXIT1:
return tms ? States.DRUPDATE : States.DRPAUSE;
case States.DRPAUSE:
return tms ? States.DREXIT2 : current_states;
case States.DREXIT2:
return tms ? States.DRUPDATE : States.DRSHIFT;
case States.DRUPDATE:
return tms ? States.DRSELECT : States.IDLE;
case States.IRCAPTURE:
return tms ? States.IREXIT1 : States.IRSHIFT;
case States.IRSHIFT:
return tms ? States.IREXIT1 : current_states;
case States.IREXIT1:
return tms ? States.IRUPDATE : States.IRPAUSE;
case States.IRPAUSE:
return tms ? States.IREXIT2 : current_states;
case States.IREXIT2:
return tms ? States.IRUPDATE : States.IRSHIFT;
case States.IRUPDATE:
return tms ? States.DRSELECT : States.IDLE;
default:
throw new Exception("Illegal state detected!");
}
}
private bool[] statePath(States current, States end_state)
{
return StatePathRecurse(current, end_state, 0);
}
private bool[] StatePathRecurse(States current, States end_state,int recursions)
{
// Function must not recurse over the entire diagram
if(++ recursions == Enum.GetNames(typeof(States)).Length)
{
// Send error in form of empty bool[]
return new bool[0];
}
bool[] path_false = CheckNextState(false);
bool[] path_true = CheckNextState(true);
// Which path to return?
// No matter what, the arrays must be larger than 0 before we can return it.
// In case both arrays are filled, we must find wich is shorter
if((path_false.Length > 0) && (path_true.Length > 0))
{
// Find the shortest path
return (path_false.Length > path_true.Length) ? path_true : path_false;
}
// In case only one of the arrays are filled
else
{
return path_false;
}
bool[] CheckNextState(bool tms)
{
States next = NextState(current, tms);
if (next == end_state)
{
// Search done, return the correct bool
return new bool[1] { tms };
}
else if (next == current)
{
// Looping in the a stable state - this is an error.
return new bool[0];
}
else
{
// Not done with the search - keep recursing
bool[] cont = StatePathRecurse(next, end_state, recursions);
if (cont.Length == 0)
{
// Error! Array must have a length
return cont;
}
else
{
// Array ok - send back
bool[] result = new bool[1 + cont.Length];
// Adding the last recieved tms to result
result[0] = tms;
// Combining the recursive bool[] cont to the result
cont.CopyTo(result, 1);
return result;
}
}
}
}
}