public MarkovChain()
        {
            Mouse1 = new MarkovState
                {
                    Coords = Event.Start.EventCoords,
                    EmptyStepCount = 0,
                    CurrentEvent = Event.Start
                };
            Mouse2 = new MarkovState
                {
                    Coords = Event.Start.EventCoords,
                    EmptyStepCount = 0,
                    CurrentEvent = Event.Start
                };

            States.Enqueue(new List<MarkovState>{Mouse1, Mouse2});
        }
        private void TryAddEvent(MarkovState state, MarkovState newState)
        {
            if (state.EmptyStepCount >= MaxEmptySize)
                return;

            if (state.CurrentEvent.Type == Event.EventType.StartEvent)
            {
                state.EventsProbability.Add(newState, 1);
                return;
            }

            var prob = GetMoveProbability(state.Coords, newState.Coords, newState.CurrentEvent.Type);

            state.EventsProbability.Add(newState, prob);
        }
        private List<MarkovState> GenerateWay(MarkovState state)
        {
            var way = new List<MarkovState>();

            for(int i = 0; i < OutputLength && state != null && state.CurrentEvent.Type != Event.EventType.StartEvent; i++)
            {
                way.Add(state);
                state = state.PreviousState;
            }

            way.Reverse();
            return way;
        }
        private void TryAddEmptyEvent(MarkovState state, List<MarkovState> outMarkovStates)
        {
            if (state.EmptyStepCount >= MaxEmptySize)
                return;

            var newState = new MarkovState
                {
                    Coords = state.Coords,
                    EmptyStepCount = state.EmptyStepCount + 1,
                    CurrentEvent = Event.Empty,
                    PreviousState = state
                };

            outMarkovStates.Add(newState);

            state.EventsProbability.Add(newState, EmptyPenalty);
        }
        public Tuple<List<MarkovState>, List<MarkovState>> NextStep(IEnumerable<Event> currentEvents)
        {
            var currentStates = States.Last();
            var newStates = new List<MarkovState>();

            foreach (var state in currentStates)
            {
                TryAddEmptyEvent(state, newStates);
            }

            foreach (var newEvent in currentEvents)
            {
                var newState = new MarkovState
                    {
                        Coords = newEvent.EventCoords,
                        CurrentEvent = newEvent,
                        EmptyStepCount = 0
                    };

                newStates.Add(newState);

                foreach (var state in currentStates)
                {
                    TryAddEvent(state, newState);
                }
            }

            States.Enqueue(newStates);

            if(States.Count <= MaxQueueSize)
                return Tuple.Create(new List<MarkovState>(), new List<MarkovState>());

            var graph = GenerateGraph();
            var ways = MaxFlowMinCost<MarkovState>.GetMinCostSize2Flow(graph.Start1, graph.Start2, graph.End);

            for (int i = 1; i < ways.Item1.Count - 1; i++)
            {
                ways.Item1[i].PreviousState = ways.Item1[i - 1];
            }
            for (int i = 1; i < ways.Item2.Count - 1; i++)
            {
                ways.Item2[i].PreviousState = ways.Item2[i - 1];
            }
            Mouse1 = ways.Item1[1];
            Mouse2 = ways.Item2[1];
            var way1 = GenerateWay(ways.Item1[ways.Item1.Count - 2]);
            var way2 = GenerateWay(ways.Item2[ways.Item2.Count - 2]);

            States.Dequeue();

            return Tuple.Create(way1, way2);
        }