1

I have website to perform match action. I am writing code to restrict some of the action based on current match stage. For example, If first half is current stage then I should restrict direct end match without second half. For each stage, I have multiple restrict stages. Below is my stage enum.

public enum MatchStage
    {
        FirstHalfAssumedStartTime = 1,
        FirstHalfAssumedEndTime = 2,
        SecondHalfAssumedStartTime = 3,
        SecondHalfAssumedEndTime = 4,
        ExtraFirstHalfAssumedStartTime = 5,
        ExtraFirstHalfAssumedEndTime = 6,
        ExtraSecondHalfAssumedStartTime = 7,
        ExtraSecondHalfAssumedEndTime = 8,
        PauseStartTime = 9,
        PauseEndTime = 10,
        EndMatchTime = 11
    }

I would like to make below method work. I want to call something like currentSiteCoreStage.RestrictedStages which returns List of restricted stages. How can I achieve this?

public static bool IsProposedStageValid(MatchStage currentSiteCoreStage, MatchStage proposedStage )
        {
            if (currentSiteCoreStage.RestrictedStages.Contains(proposedStage)) // I am hoping to make this work
                return false;
        }
Ashif Nataliya
  • 912
  • 2
  • 13
  • 28
  • What is `RestrictedStages` ? – Thomas Ayoub Mar 31 '17 at 13:46
  • I would use more positive way - get next possible stages instead of stages which you are not interested in. E.g. if you are at `ExtraFirstHalfAssumedStartTime` then it looks like you have only one option to continue – Sergey Berezovskiy Mar 31 '17 at 13:47
  • @ThomasAyoub nothing is defined yet. I am not sure even something like this possible or not. I am open for better solution as well. I am thinking this line "currentSiteCoreStage.RestrictedStages.Contains" because it make sense and explains purpose. – Ashif Nataliya Mar 31 '17 at 13:49
  • Why not a single [Multimap](http://stackoverflow.com/questions/380595/multimap-in-net)? I'd normally also recommend listing valid transitions rather than banned ones. – Damien_The_Unbeliever Mar 31 '17 at 13:51
  • @SergeyBerezovskiy That is also fine. But how do I get list of interested stages? where to define those? in another enum? – Ashif Nataliya Mar 31 '17 at 13:52
  • Your currentSiteCoreStage is of type MatchStage (enum), which doesn't have a property RestrictedStages... How are you doing 'currentSiteCoreStage.RestrictedStages'? – haku Mar 31 '17 at 13:59
  • @NoSaidTheCompiler Created extension method on MatchStage – Ashif Nataliya Mar 31 '17 at 14:15

3 Answers3

3

What you have here is actually state machine. You can create method which defines possible stage transitions for each stage supported by your application. E.g. (of course you don't have to use iterators, you can simply return array of stages from each case block):

public static IEnumerable<MatchStage> GetAvailableStageTransitions(MatchStage stage)
{
    switch (stage)
    {
        case MatchStage.FirstHalfAssumedStartTime:
            yield return MatchStage.FirstHalfAssumedEndTime;
            yield return MatchStage.PauseStartTime;
            yield break;
        case MatchStage.SecondHalfAssumedStartTime:
            yield return MatchStage.SecondHalfAssumedEndTime;
            yield return MatchStage.PauseStartTime;
            yield break;
        // etc
        default:
            throw new NotSupportedException($"Stage {stage} is not supported.");
    }
}

Then checking if proposed stage is available:

GetAvailableStageTransitions(currentSiteCoreStage).Contains(proposedStage)

Depending on complexity of your system you can think about incapsulating state transions and logic realted to each state into state objects. For more details read about State Design Pattern.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
0

Maybe consider something like this: 1: Your enum

2:

public class Stage
{
    public MatchStage MathStage { get; set; }
    public List<MatchStage> PossibleStages { get; set; }
}

3.

public static bool IsProposedStageValid(Stage currentSiteCoreStage, MatchStage proposedStage)
{
     if (currentSiteCoreStage.PossibleStages.Contains(proposedStage)) // I am hoping to make this work
     return false;

     return true;
}

Example:

Stage st1 = new Stage
{
      MathStage = MatchStage.FirstHalfAssumedStartTime,
      PossibleStages = new List<MatchStage> { MatchStage.FirstHalfAssumedEndTime }
};

bool res = IsProposedStageValid(st1, MatchStage.PauseEndTime);
daniell89
  • 1,832
  • 16
  • 28
0

One approach is to have a class that knows about your current stage and can generate RestrictedStages based on the current stage. Something like:

public enum Stage
{
    First, Second, Third
}

public class CoreStage
{
    public Stage CurrentStage { get; private set; }

    public IEnumerable<Stage> RestrictedStages { get; private set; }

    public CoreStage(Stage currentStage)
    {
        CurrentStage = currentStage;
        RestrictedStages = GenerateRestrictedStages();
    }

    private IEnumerable<Stage> GenerateRestrictedStages()
    {
        //apply your logic to determine Restricted stages based on current stage.
        return null;
    }
}

Now in your IsProposedStageValid method would look sth like below:

public static bool IsProposedStageValid(Stage currentSiteCoreStage, Stage proposedStage)
    {
        var coreStage = new CoreStage(currentSiteCoreStage);
        if (coreStage.RestrictedStages.Contains(proposedStage))
        {
            //do whatever you want.
        }
        return false;
    }
haku
  • 4,105
  • 7
  • 38
  • 63