Esempio n. 1
0
    private void OnRingAskingToBeSelected(SelectableRing ring)
    {
        if (!isStarted)
        {
            //the exercise hasn't started yet
            return;
        }

        //Collision to the pin of the ring selected (to avoid innecesary animations)
        lastPinWithCollision = pins[ring.pin].GetInstanceID();

        //Only the last ring can be selected
        if (pins[ring.pin].ringPeek().GetInstanceID() == ring.GetInstanceID())
        {
            //Removing the ring from his current Pin so it can be moved
            pins[ring.pin].ringPop();
            ring.SelectionAllowed();
            aRingIsSelected = true;
        }
                #if UNITY_EDITOR
        else
        {
            aRingIsSelected = true;
            //For QA (have fun Roy!)
            QA_OnRingAskingToBeSelected(ring);
        }
                #endif
    }
Esempio n. 2
0
    /**
     * Add a ring to be used on the exercise
     **/
    public void AddRingReference(SelectableRing ring)
    {
        rings.Add(ring);

        //Ring delegates
        ring.OnCanceled         += OnRingSelectionCanceled;
        ring.AskSelectionPermit += OnRingAskingToBeSelected;
        ring.OnDropped          += OnRingDropped;
    }
Esempio n. 3
0
    /**
     * Remove and return the last ring (Last In First Out)
     **/
    public SelectableRing ringPop()
    {
        if (!isEmpty())
        {
            SelectableRing result = ringsStack[ringsStack.Count - 1];
            ringsStack.RemoveAt(ringsStack.Count - 1);
            return(result);
        }

        return(null);
    }
Esempio n. 4
0
    private IEnumerator DoSteps()
    {
        Vector3 pos;
        float   duration;
        float   moveDuration = intoPinAnimation.duration;

        //Lets make ir faster
        intoPinAnimation.duration = intoPinAnimation.duration * 0.85f;
        while (currentSolutionStep < solutionSteps.Count)
        {
            SelectableRing ring = solutionSteps[currentSolutionStep].ring.ringReference;
            Pin            from = solutionSteps[currentSolutionStep].from.pinReference;
            Pin            to   = solutionSteps[currentSolutionStep].to.pinReference;

            //Logic status
            from.ringPop();
            AddRingToPin(ring, to.index);
            movesCount++;

            //visual ststus
            ring.DoSelectionEffect();

            //A little wait
            yield return(new WaitForSeconds(0.15f));

            //Alittle move upward
            pos      = ring.transform.position;
            pos.y   += separationBetweenRings;
            duration = intoPinAnimation.duration;

            intoPinAnimation.duration    = 0.1f;
            intoPinAnimation.target      = ring.transform;
            intoPinAnimation.destination = pos;
            intoPinAnimation.Play();

            yield return(new WaitForSeconds(0.11f));

            intoPinAnimation.duration = duration;
            PositionateRingOnPin(ring, to.index, to.ringCount(), true);

            //We wait for the visuals again
            yield return(new WaitForSeconds(intoPinAnimation.duration * 0.85f));

            ring.SortingOrderForSelection(false);
            currentSolutionStep++;
        }

        intoPinAnimation.duration = moveDuration;

        CheckIfExerciseIsCompleted(solutionSteps[solutionSteps.Count - 1].to.index);
    }
Esempio n. 5
0
    private void QA_OnRingAskingToBeSelected(SelectableRing ring)
    {
        if (!multipleSelectionAllowed)
        {
            return;
        }


        Pin pin = pins[ring.pin];

        multipleRingSelection.Clear();

        //Select the ring and everything above him
        int selectedIndex = -1;

        for (int i = 0; i < pin.ringsStack.Count; i++)
        {
            //Search for the selected ring
            if (selectedIndex < 0)
            {
                if (pin.ringsStack[i].GetInstanceID() == ring.GetInstanceID())
                {
                    selectedIndex = i;
                    multipleRingSelection.Add(pin.ringsStack[i]);
                }
            }
            else
            {
                //Every ring after the selected should be added
                multipleRingSelection.Add(pin.ringsStack[i]);
            }
        }

        //Remove all the selected rings from the pin
        pin.ringsStack.RemoveRange(selectedIndex, multipleRingSelection.Count);

        //All the selected rings follow the movements of the one selected by the input
        StartCoroutine("MultipleSelectionVisualUpdate");

        //Allow selection and visually select the extra rings
        ring.SelectionAllowed();
        foreach (SelectableRing r in multipleRingSelection)
        {
            r.DoSelectionEffect();
        }

        isMultipleSelectionActive = true;
    }
    /**
     * Search among the ringNodes for the one that has a reference that matched with the one provided
     **/
    private RingNode getRingNodeFromReference(SelectableRing reference)
    {
        foreach (RingNode ring in rings)
        {
            /*
             * WARNING: We found a bug using GetInstanceID in getPinContainingRing and change it for a size comparation
             * but since the size of this reference it is not guaranteed to be always the same we hope for the best
             */
            if (ring.ringReference.GetInstanceID() == reference.GetInstanceID())
            {
                return(ring);
            }
        }

        return(null);
    }
Esempio n. 7
0
    /**
     * Animation effect to move the ring over the pin
     **/
    public void MoveRingOverPinEffect(SelectableRing ring, int pinIndex)
    {
        //Pin position
        Vector3 expectedPosition = pins[pinIndex].transform.position;

        //Y based on the pin height
        expectedPosition.y = pinHeightReference.position.y;

        //Coroutine params
        EffectParams effectParams = new EffectParams();

        effectParams.ring      = ring;
        effectParams.pin       = pins[pinIndex];
        effectParams.ringIndex = pins[pinIndex].ringCount();

        overPinAnimation.destination = expectedPosition;
        overPinAnimation.target      = ring.transform;
        overPinAnimation.Play();

        StartCoroutine("WaitingForMoveRingOverEffectToFinish", effectParams);
    }
Esempio n. 8
0
    /**
     * Visual positionation of the ring on the indicated pin.
     *
     **/
    public void PositionateRingOnPin(SelectableRing ring, Pin pin, int ringIndex, bool animate = false)
    {
        //Pin position
        Vector3 expectedPosition = pin.transform.position;

        //Ring sorting order (so the rings dont overlap)
        ring.setFrontSortingOrder(ringIndex);

        //Y position based on the ring index
        expectedPosition.y += (ringIndex - 1) * separationBetweenRings;

        if (animate)
        {
            intoPinAnimation.destination          = expectedPosition;
            intoPinAnimation.target               = ring.transform;
            intoPinAnimation.OnAnimationComplete += AfterDropAnimation;            //some effects after the animation
            intoPinAnimation.Play();
        }
        else
        {
            ring.transform.position = expectedPosition;
        }
    }
Esempio n. 9
0
    /**
     * When the selection was canceled by game external factors
     **/
    private void OnRingSelectionCanceled(SelectableRing ring)
    {
        if (!isStarted)
        {
            //the exercise hasn't started yet
            return;
        }

        aRingIsSelected = false;

        //Return the ring to his previous position
        AddRingToPin(ring, ring.pin);
        //TODO Without animation? We have to review the possible causes for a touch cancel and then decide
        PositionateRingOnPin(ring, ring.pin, pins[ring.pin].ringCount(), false);     //visual add


        //QA: If there is a multiple selection active then this should be managed
                #if UNITY_EDITOR
        if (isMultipleSelectionActive)
        {
            //Stop the visual updating
            StopCoroutine("MultipleSelectionVisualUpdate");

            //Every ring back to his previous pin
            for (int i = 1; i < multipleRingSelection.Count; i++)
            {
                AddRingToPin(multipleRingSelection[i], ring.pin);                                            //logical
                //TODO Without animation? We have to review the possible causes for a touch cancel and then decide
                PositionateRingOnPin(multipleRingSelection[i], ring.pin, pins[ring.pin].ringCount(), false); //visual
            }

            //Stop multiple selection
            isMultipleSelectionActive = false;
        }
                #endif
    }
Esempio n. 10
0
 /**
  * Add the ring to the indicated pin without validation.
  **/
 public void AddRingToPin(SelectableRing ring, int pinIndex)
 {
     ring.pin = pinIndex;
     pins[pinIndex].ringPush(ring);
 }
Esempio n. 11
0
 /**
  * Visual positionation of the ring on the indicated pin.
  **/
 public void PositionateRingOnPin(SelectableRing ring, int pinIndex, int ringIndex, bool animate = false)
 {
     PositionateRingOnPin(ring, pins[pinIndex], ringIndex, animate);
 }
Esempio n. 12
0
    private void OnRingDropped(SelectableRing ring)
    {
        if (!isStarted)
        {
            //the exercise hasn't started yet
            return;
        }

        aRingIsSelected = false;

        //check if the ring was dropped on a pin
        if (lastPinWithCollision != -1)
        {
            //The ring were dropen in the lastPinWithCollision ring
            for (int i = 0; i < pins.Count; i++)
            {
                if (pins[i].GetInstanceID() == lastPinWithCollision)
                {
                    //Pin found

                    /*
                     * Lets see is this ring could be dropped here.
                     * The ring can only be droopped on empty Pins or when the last ring on the pin
                     * is smaller.
                     */
                    if (pins[i].isEmpty() || pins[i].ringPeek().sizeIndicator >= ring.sizeIndicator)
                    {
                        //Allowed

                        //we count the move only if the ring is dropped on another pin
                        if (ring.pin != i)                       //the ring remember the previous pin until a new one is added
                        {
                            movesCount++;
                        }

                        AddRingToPin(ring, i);                                    //loginc add
                        PositionateRingOnPin(ring, i, pins[i].ringCount(), true); //visual add

                        //QA: If there is a multiple selection active then we manage it
                                                #if UNITY_EDITOR
                        if (isMultipleSelectionActive)
                        {
                            //The visual position should not be modified since every ring is folowing the selected one
                            for (int j = 1; j < multipleRingSelection.Count; j++)
                            {
                                //Add the selected rings to the pin
                                AddRingToPin(multipleRingSelection[j], i);                               //loginc add

                                //Z sorting for all the extra selected rings(so the rings dont overlap)
                                multipleRingSelection[j].setFrontSortingOrder(pins[i].ringCount());
                                multipleRingSelection[j].SortingOrderForSelection(false);
                            }
                        }
                                                #endif

                        //if this isn't the starter pin then we check if the exercise is completed
                        if (starterPin != i)
                        {
                            CheckIfExerciseIsCompleted(i);
                        }

                        break;
                    }
                    else
                    {
                        //Denied

                        soundManager.PlayFX("denied");

                        //The ring is returned to his previous Pin
                        AddRingToPin(ring, ring.pin);                       //loginc add
                        MoveRingOverPinEffect(ring, ring.pin);              //visual add

                        //QA: If there is a multiple selection active then we manage it
                                                #if UNITY_EDITOR
                        if (isMultipleSelectionActive)
                        {
                            //The visual position should not be modified since every ring is folowing the selected one
                            for (int j = 1; j < multipleRingSelection.Count; j++)
                            {
                                //Add the selected rings to the pin
                                AddRingToPin(multipleRingSelection[j], ring.pin);                               //loginc add

                                //Z sorting for all the extra selected rings(so the rings dont overlap)
                                multipleRingSelection[j].setFrontSortingOrder(pins[ring.pin].ringCount());
                                multipleRingSelection[j].SortingOrderForSelection(false);
                            }
                        }
                                                #endif
                    }
                }
            }
        }
        else
        {
            //Pin dropped on the void
            //The ring is returned to his previous Pin
            AddRingToPin(ring, ring.pin);           //loginc add
            MoveRingOverPinEffect(ring, ring.pin);  //visual add

            //QA: If there is a multiple selection active then we manage it
                        #if UNITY_EDITOR
            if (isMultipleSelectionActive)
            {
                //The visual position should not be modified since every ring is folowing the selected one
                for (int j = 1; j < multipleRingSelection.Count; j++)
                {
                    //Add the selected rings to the pin
                    AddRingToPin(multipleRingSelection[j], ring.pin);                   //loginc add

                    //Z sorting for all the extra selected rings(so the rings dont overlap)
                    multipleRingSelection[j].setFrontSortingOrder(pins[ring.pin].ringCount());
                    multipleRingSelection[j].SortingOrderForSelection(false);
                }
            }
                        #endif
        }


        //QA
                #if UNITY_EDITOR
        if (isMultipleSelectionActive)
        {
            //Stop updating the selected rings when the effect finished
            intoPinAnimation.OnAnimationComplete += QA_OnDroppedAnimationComplete;
        }
                #endif
    }
Esempio n. 13
0
    public int index;                         //Index reference used in the ExerciseSolver

    public RingNode(SelectableRing reference, int ringSize)
    {
        ringReference = reference;
        pendingPaths  = new List <ExercisePath>();
        size          = ringSize;
    }
Esempio n. 14
0
 private void AddRing(SelectableRing ring, int size)
 {
     rings.Add(new RingNode(ring, size));
     rings[rings.Count - 1].index = rings.Count - 1;
 }
Esempio n. 15
0
    [HideInInspector] public int index;                                    //Index in the exercise

    /**
     * Ring added to the stack
     */
    public void ringPush(SelectableRing ring)
    {
        ringsStack.Add(ring);
    }
    /**
     * Array partition for QuickSort.
     *
     * Partition selects a pivot and sort from start to end every value
     * so the values greater than pivote are to his right and the lesser ones are to his left.
     *
     * TODO: Support for reverse sorting order
     **/
    private static int partition(List <SelectableRing> target, int start, int end)
    {
        //TODO pick a better pivot
        //pivot selection (last for simplicity)
        SelectableRing pivot = target[end - 1];
        int            left, right;

        left  = start;
        right = end - 2;

        //We iterate until all the values greater than pivot are to his right and the lesser ones to his left
        while (left + 1 < right)
        {
            //find a left reference that is greater than pivot
            while (target[left].sizeIndicator <= pivot.sizeIndicator && left + 1 < right)
            {
                left++;
            }

            //find a right reference that is lesser than pivot
            while (target[right].sizeIndicator > pivot.sizeIndicator && right - 1 > left)
            {
                right--;
            }

            /*
             * Left is greater than pivot and right is less or equal so we swap.
             */
            if (target[left].sizeIndicator > pivot.sizeIndicator && target[right].sizeIndicator <= pivot.sizeIndicator)
            {
                //swap
                //TODO some XOR optimization
                SelectableRing tmp = target[left];
                target[left]  = target[right];
                target[right] = tmp;
                left++;
            }
        }


        //move the pivot to final position that is greater than him
        if (target[left].sizeIndicator > pivot.sizeIndicator)
        {
            //swap
            //TODO some XOR optimization
            SelectableRing tmp = target[left];
            target[left]    = target[end - 1];
            target[end - 1] = tmp;

            //new pivot position
            return(left);
        }
        else if (target[right].sizeIndicator > pivot.sizeIndicator)
        {
            //swap
            //TODO some XOR optimization
            SelectableRing tmp = target[right];
            target[right]   = target[end - 1];
            target[end - 1] = tmp;

            //new pivot position
            return(right);
        }

        //the pivote doesn't move
        return(end - 1);
    }