Esempio n. 1
0
        /// <summary>
        /// Performs the 3 functions which we regularly do in this order
        /// 1. Combine the values into a single integer
        /// 2. Add the probability to that stored against the integer in stateProb array
        /// 3. Enqueue the integer state (unless already queued)
        /// </summary>
        static void combineQueueUpdate(ref double[] stateProb, ref distinctIntQueue Q, double prob,
                                       int t_elapsed, int T_R, int t_M, int t_K, compStage compStg)
        {
            int S = combineState(t_elapsed, T_R, t_M, t_K, compStg);

            // ADD the probability.
            stateProb[S] += prob;
            Q.Enqueue(S);
        }
Esempio n. 2
0
        // Gets the decompressed stage - see pdf.
        static stage getFullStage(compStage compStg, int t_M, int t_K)
        {
            switch (compStg)
            {
            case compStage.Skedar1:
                // If we aren't killing we're awaiting.
                if (t_K == 0)
                {
                    return(stage.Skedar1Await);
                }
                else
                {
                    return(stage.Skedar1Kill);
                }

            case compStage.JustJoannaMoving:
                return(stage.JustJoannaMoving);

            case compStage.BothMoving:
                // If the movement timer has elapsed, we're killing,
                // Else one of us is still moving (or spawning).
                if (t_M == 0)
                {
                    return(stage.Skedar2Kill);
                }
                else
                {
                    return(stage.BothMoving);
                }

            case compStage.Skedar3:
                // Movement timer set to 1 indicates success state, see pdf.
                if (t_M != 0)
                {
                    return(stage.Success);
                }

                // Otherwise it's the standard kill timer distinction
                if (t_K != 0)
                {
                    return(stage.Skedar3Kill);
                }
                else
                {
                    return(stage.Skedar3Await);
                }

            default:
                // Cheer up compiler!
                return((stage)(-1));
            }
        }
Esempio n. 3
0
        // ==============================

        /// <summary>
        /// Combines all the values into a single integer
        /// </summary>
        static int combineState(int t_elapsed, int T_R, int t_M, int t_K, compStage compStg)
        {
            int res = t_elapsed;

            res *= (100 + 1);
            res += T_R;

            // Note the +1 as ever.
            res *= (t_open + 2);
            res += t_M + 1;

            res *= (t_kill + 1);
            res += t_K;

            res *= 4;
            res += (int)compStg;

            return(res);
        }
Esempio n. 4
0
        /// <summary>
        /// Extracts the state from the single integer into the 5 items. Inverse of the above.
        /// </summary>
        static void recoverState(int entireState, out int t_elapsed, out int T_R, out int t_M, out int t_K, out compStage compStg)
        {
            compStg      = (compStage)(entireState % 4);
            entireState /= 4;

            t_K          = entireState % (t_kill + 1);
            entireState /= (t_kill + 1);

            // Corresponding -1
            t_M          = entireState % (t_open + 2) - 1;
            entireState /= (t_open + 2);

            T_R          = entireState % (100 + 1);
            entireState /= (100 + 1);

            t_elapsed = entireState;
        }
Esempio n. 5
0
        /// <summary>
        /// Gets one or two (normally two) states from one by applying the Right Timer transitions.
        /// Adds these to the Queue for continuing the breadth first search.
        /// Where the right timer is no longer relevant (for Skedar3Kill) this just queues the single state.
        /// </summary>
        /// <param name="basePr">The base probability for the stage we are considering Right Timer transitions from</param>
        /// <param name="compStg">The compressed stage</param>
        static void doRightTimerTransitionsAndQueue(ref double[] stateProb, ref distinctIntQueue Q, double basePr, int t_elapsed, int T_R, int t_M, int t_K, compStage compStg)
        {
            // If already 0, we've stopped (Skedar #3 is spawned), so just make the call
            if (T_R == 0)
            {
                combineQueueUpdate(ref stateProb, ref Q, basePr, t_elapsed, T_R, t_M, t_K, compStg);
            }
            else
            {
                // If the timer is not 1, do the event that we don't finish the timer (just timer changes)
                // Also adjust base probability for 1/256 of success next
                if (T_R != 1)
                {
                    combineQueueUpdate(ref stateProb, ref Q, basePr * q, t_elapsed, T_R - 1, t_M, t_K, compStg);
                    basePr /= 256;
                }

                // Now consider the reset event. Set timer back to 100.
                // Determine full stage to determine flow on
                T_R = 100;
                switch (compStg)
                {
                // More interesting stages, set the movement time to t_open when Joanna is still at Skedar #1.
                // But only set it once - there was a bug here where we kept reseting.
                case compStage.Skedar1:
                    // NTS: Awkward case where we used Parent's full stage was here, but being able to use current compressed is ideal.
                    //      Indeed it also would effect the bottom two - it was a bad idea.
                    if (t_M == -1)
                    {
                        t_M = t_open;
                    }
                    break;

                case compStage.JustJoannaMoving:
                    // If Joanna is already moving, update timer to max of time for Joanna and time for Skedar #2
                    // Notice here we actually change stage, preventing running this twice.
                    if (t_open > t_M)
                    {
                        t_M = t_open;
                    }
                    compStg = compStage.BothMoving;
                    break;

                case compStage.Skedar3:
                    // Set to 0 to show we're done with all events, stopping the timer.
                    // This is slightly cleaner, since the right timer would otherwise run while we're killing Skedar #3.
                    // Also observe we must be in Skedar3Await, since timer is running, so set kill timer
                    T_R = 0;
                    t_K = t_kill;
                    break;

                    // In full states BothMoving and Skedar2Kill Skedar #2 is spawned and not killed, so we only reset the timer (above the switch).
                }

                // Finally we queue this reset-timer state.
                combineQueueUpdate(ref stateProb, ref Q, basePr, t_elapsed, T_R, t_M, t_K, compStg);
            }
        }