Beispiel #1
0
    public List <IBloxVariable> GetVariablesInBloxScope2(ABlox blox)
    {
        List <IBloxVariable> variablesInScope = new List <IBloxVariable>();


        RootBlox rootBlox = GetRootBlox();

        if (rootBlox != null)
        {
            List <BloxIdent> bloxList = rootBlox.GetChildBloxListInVerticalOrder();
            //Params are not loaded in GetChildBloxListInVerticalOrder() method, so we evaluate according to the parent index
            //on that case
            BloxIdent bloxIdent  = bloxList.Find(b => b.blox == (blox.IsParam ? blox.ParentBlox : blox));
            BloxIdent bloxIdent2 = bloxList.Where(b => b.blox == (blox.IsParam ? blox.ParentBlox : blox)).FirstOrDefault();

            int indexOfBlox = -1;
            try
            {
                indexOfBlox = bloxList.IndexOf(bloxIdent);
            }
            catch (Exception ex) { }

            if (indexOfBlox >= 0)
            {
                // Gets all the bloxes above this one, that are variables
                // Although pure Blox objects cannot be cast as IBloxVariable,
                // objects of classes that inherit from Blox, and implement IBloxVariable, can
                variablesInScope = bloxList.GetRange(0, indexOfBlox).Where(b => GameObjectHelper.CanBeCastedAs <IBloxVariable>(b.blox)).Select(b => (IBloxVariable)b.blox).ToList();
            }
        }
        return(variablesInScope);
    }
Beispiel #2
0
    private float GetParamSpacing(RootBlox rootBlox)
    {
        BoundingBox2D rootBBox         = GameObjectHelper.getBoundingBoxInWorld(rootBlox.gameObject);
        float         rootBloxWidth    = GameObjectHelper.getWidthFromBBox(rootBBox);
        float         bloxParamSpacing = rootBloxWidth / 10;

        return(bloxParamSpacing);
    }
Beispiel #3
0
    private float GetVerticalSpacing(RootBlox rootBlox)
    {
        BoundingBox2D rootBBox            = GameObjectHelper.getBoundingBoxInWorld(rootBlox.gameObject);
        float         rootBloxHeight      = GameObjectHelper.getHeightFromBBox(rootBBox);
        float         bloxVerticalSpacing = 2 * rootBloxHeight / 3;

        return(bloxVerticalSpacing);
    }
Beispiel #4
0
    /// <summary>
    /// What Hint looks for:
    /// Gets the placed bloxes
    /// looks at the bloxes that are expected to be placed
    ///
    /// looks for the expected patterns:
    /// Horizontal line
    /// Vertical line
    /// Olhar para o que se faz no final de cada padrão: virar à esquerda,ou à direita?
    ///
    /// </summary>
    public void LoadHint(RootBlox rootBlox)
    {
        // 1. Check for mandatory bloxes not used
        List <Tuple <Type, int> > usedBloxTypeCount = rootBlox.GetAllBloxesBellow().GroupBy(b => b.GetType()).Select(g => new Tuple <Type, int>(g.First().GetType(), g.Count())).ToList();

        List <ExpectedBlox> mandatoryBloxesNotUsed = LevelConfiguration.MandatoryBloxes.Where(mb => !usedBloxTypeCount.Exists(b => b.Item1 == mb.BloxType && b.Item2 >= mb.MinimumQuantity)).ToList();

        // 1. Check for optional bloxes not used
        List <ExpectedBlox> expectedOptionalBloxesNotUsed = LevelConfiguration.OptionalExpectedBloxes.Where(mb => !usedBloxTypeCount.Exists(b => b.Item1 == mb.BloxType && b.Item2 >= mb.MinimumQuantity)).ToList();
    }
Beispiel #5
0
    public void SetAllBloxesPositionsOnScreen()
    {
        RootBlox rootBlox = GetRootBlox();

        if (rootBlox != null)
        {
            float bloxVerticalSpacing = GetVerticalSpacing(rootBlox);
            float identSpacing        = GetIdentSpacing(rootBlox);
            float paramSpacing        = GetParamSpacing(rootBlox);
            SetChildBloxesPositionOnScreen(rootBlox, bloxVerticalSpacing, identSpacing, paramSpacing);
        }
    }
Beispiel #6
0
    public void NestObject(GameObject secondObject)
    {
        RootBlox rootBlox = GetRootBlox();

        if (rootBlox != null && NestingActive)
        {
            if (secondObject.GetComponent <ABlox>() != null && secondObject != null && ValidateNesting(secondObject))
            {
                ABlox         secondObjectBlox        = secondObject.GetComponent <ABlox>();
                Vector2       thisObjectPosition      = this.gameObject.transform.position;
                Vector2       secondObjectPosition    = secondObject.transform.position;
                RectTransform gameObjectTransform     = this.gameObject.GetComponent <RectTransform>();
                RectTransform collidedObjectTransform = secondObject.GetComponent <RectTransform>();
                BoundingBox2D thisBBox      = GameObjectHelper.getBoundingBoxInWorld(this.gameObject);
                BoundingBox2D secondObjBBox = GameObjectHelper.getBoundingBoxInWorld(secondObject);

                float thisObjectWidth   = GameObjectHelper.getWidthFromBBox(thisBBox);
                float secondObjectWidth = GameObjectHelper.getWidthFromBBox(secondObjBBox);

                float thisObjectHeight   = GameObjectHelper.getHeightFromBBox(thisBBox);
                float secondObjectHeight = GameObjectHelper.getHeightFromBBox(secondObjBBox);

                //checks if second object top is bellow this object center
                if (secondObjBBox.top.y < thisObjectPosition.y)
                {
                    if (!secondObjectBlox.IsParam && ValidateNestToBottom(secondObject) && MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.left.x, thisObjectWidth / 4))
                    {
                        AddToBottom(secondObjectBlox);
                        OnNestToBottom();
                    }
                    else if (!secondObjectBlox.IsParam && ValidateNestToBottomIdented(secondObject) && MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.bottom.x, thisObjectWidth / 4))
                    {
                        AddToBottomIdented(secondObjectBlox);
                        OnNestToBottomIdented();
                    }
                }
                else //if it is above
                {
                    // Checks if the left parth of the second object is near the right part of the first, and verifies if they are kind of aligned
                    if (ValidateNestToTheSide(secondObject) && MathHelper.IsNearby(secondObjBBox.left.y, thisBBox.right.y, thisObjectHeight / 4) &&
                        MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.right.x, thisObjectWidth / 4))
                    {
                        // Nest side to side
                        AddParam(secondObjectBlox);
                        OnNestToSide();
                    }
                }
                OnNest();
                SetAllBloxesPositionsOnScreen();
            }
        }
    }
Beispiel #7
0
    /// <summary>
    /// Gets all the variable bloxes on the scope of a blox. They are presented in the following order:
    /// the one closest to blox, to the one closest to root.
    /// </summary>
    /// <param name="blox"></param>
    /// <returns></returns>

    public List <IBloxVariable> GetVariablesInBloxScope(ABlox blox)
    {
        List <IBloxVariable> variablesInScope = new List <IBloxVariable>();

        RootBlox rootBlox = GetRootBlox();

        if (rootBlox != null)
        {
            List <ABlox> bloxesInScope = blox.GetBloxesInScope(blox);
            variablesInScope = bloxesInScope.Where(b => GameObjectHelper.CanBeCastedAs <IBloxVariable>(b)).Select(b => (IBloxVariable)b).ToList();
        }
        return(variablesInScope);
    }
Beispiel #8
0
    public void OnDrag(PointerEventData eventData)
    {
        IsBeingDragged         = true;
        bloxTransform.position = eventData.position;


        // If this blox has child bloxes and params, sets their positions in
        // order to drag them also
        RootBlox rootBlox = GetRootBlox();

        if (rootBlox != null)
        {
            float bloxVerticalSpacing = GetVerticalSpacing(rootBlox);
            float identSpacing        = GetIdentSpacing(rootBlox);
            float paramSpacing        = GetParamSpacing(rootBlox);
            // Sets the child blox and params position while dragging, for them to follow this blox
            // Those bloxes nesting is temporarily disabled
            SetChildBloxesPositionOnScreen(this, bloxVerticalSpacing, identSpacing, paramSpacing, false);
        }

        // Verifies if there are collided objects, and if
        // this object can be potentially nested to those
        if (collidedObjects.Count > 0)
        {
            // Although we are saving all the simultaneous collisions
            // We only want this object to nest with the highest ones
            float             maxY           = collidedObjects.Max(c => c.transform.position.y);
            List <GameObject> highestObjects = collidedObjects.Where(c => c.transform.position.y == maxY).Select(a => a.gameObject).ToList();
            ResetHightlight();
            foreach (GameObject collidedObject in highestObjects)
            {
                //If the collided object is a blox, checks if this is nestable to it, and hightlights if it is
                if (GameObjectHelper.HasComponent <ABlox>(collidedObject))
                {
                    NestingType nestingType = collidedObject.GetComponent <ABlox>().DetermineNestingType(this.gameObject);
                    if (nestingType != NestingType.NONE && GameObjectHelper.HasComponent <HighlightableButton>(collidedObject.gameObject))
                    {
                        HighlightableButton hB = collidedObject.gameObject.GetComponent <HighlightableButton>();
                        hB.HighlightButton(HighlightableButton.ButtonHighlight.Info);
                        hightlightableBloxes.Add(hB);
                    }
                }
            }
        }
    }
Beispiel #9
0
    /// <summary>
    /// Checks if object passed can be nested to this one, and returns nesting type
    /// </summary>
    /// <param name="secondObject"></param>
    /// <returns></returns>
    public NestingType DetermineNestingType(GameObject secondObject)
    {
        NestingType nestingType = NestingType.NONE;
        RootBlox    rootBlox    = GetRootBlox();

        if (rootBlox != null && NestingActive)
        {
            if (secondObject.GetComponent <ABlox>() != null && secondObject != null && ValidateNesting(secondObject))
            {
                ABlox         secondObjectBlox   = secondObject.GetComponent <ABlox>();
                Vector2       thisObjectPosition = this.gameObject.transform.position;
                BoundingBox2D thisBBox           = GameObjectHelper.getBoundingBoxInWorld(this.gameObject);
                BoundingBox2D secondObjBBox      = GameObjectHelper.getBoundingBoxInWorld(secondObject);

                float thisObjectWidth  = GameObjectHelper.getWidthFromBBox(thisBBox);
                float thisObjectHeight = GameObjectHelper.getHeightFromBBox(thisBBox);

                //checks if second object top is bellow this object center
                if (secondObjBBox.top.y < thisObjectPosition.y)
                {
                    if (!secondObjectBlox.IsParam && ValidateNestToBottom(secondObject) && MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.left.x, thisObjectWidth / 4))
                    {
                        nestingType = NestingType.BOTTOM;
                    }
                    else if (!secondObjectBlox.IsParam && ValidateNestToBottomIdented(secondObject) && MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.bottom.x, thisObjectWidth / 4))
                    {
                        nestingType = NestingType.BOTTOM_IDENTED;
                    }
                }
                else //if it is above
                {
                    // Checks if the left parth of the second object is near the right part of the first, and verifies if they are kind of aligned
                    if (ValidateNestToTheSide(secondObject) && MathHelper.IsNearby(secondObjBBox.left.y, thisBBox.right.y, thisObjectHeight / 4) &&
                        MathHelper.IsNearby(secondObjBBox.left.x, thisBBox.right.x, thisObjectWidth / 4))
                    {
                        // Nest side to side
                        nestingType = NestingType.SIDE;
                    }
                }
            }
        }
        return(nestingType);
    }
Beispiel #10
0
    public Evaluation EvaluateLevel(RootBlox rootBlox)
    {
        ObjectiveCheck check;
        int            stars = 0;
        /// Each level will have 5 objectives:
        ///     1 - Complete in time
        ///     2 - Use a number of attempts lesser than the maximum
        ///     3 - Use a number of blocks lesser than the maximum
        ///     4 - Use the expected optional bloxes
        ///     5 - Complete the in game objective (mandatory steps, bloxes, special actions)
        ///

        // 1. Time evaluation
        DateTime expectedEndTime = startTime.AddMinutes(LevelConfiguration.MaxTimeInMinutes);

        check.exceededMinutes = (DateTime.Now - expectedEndTime).TotalMinutes;

        // 2. Number of attempts
        check.exceededAttempts = numberOfAttempts - (int)LevelConfiguration.MaxAttempts;
        check.numberOfAttempts = numberOfAttempts;
        // 3. Use a number of code lines lesser than the maximum
        check.exceededLines = rootBlox.GetChildBloxListInVerticalOrder().Count - (int)LevelConfiguration.MaxCodeLinesExpected;
        check.usedLines     = rootBlox.GetChildBloxListInVerticalOrder().Count;

        // 4. Right steps. This is a mandatory object, so level shall fail when not accomplished
        // 4.1 Get all the mandatory steps that were executed, with the special action included
        // The final count should match the count of LevelConfiguration.MandatorySteps
        //var queryMandatoryStepsCompleted = from mandatoryStep in LevelConfiguration.MandatorySteps
        //                                   join plotTile in tilesInScene on mandatoryStep.CoordinateInPlot equals plotTile.PlotPosition
        //                                   where mandatoryStep != null && plotTile != null && plotTile.SpecialActionExecuted == mandatoryStep.SpecialAction && plotTile.Stepped
        //                                   select plotTile;

        var queryMandatoryStepsCompleted = LevelConfiguration.MandatorySteps.Where(ms => tilesInScene.Exists(t => t.Stepped && t.SpecialActionExecuted == ms.SpecialAction && t.PlotPosition == ms.CoordinateInPlot));

        bool allTheMandatoryStepsDone = queryMandatoryStepsCompleted.Count() == LevelConfiguration.MandatorySteps.Count;

        // 4.2 Get all the the not expected steps. It is mandatory that the user restricts to the mandatory steps
        var queryNotExpectedSteps = from plotTile in tilesInScene
                                    join mandatoryStep in LevelConfiguration.MandatorySteps on plotTile.PlotPosition equals mandatoryStep.CoordinateInPlot into mSteps
                                    from step in mSteps.DefaultIfEmpty()
                                    where step == null && plotTile.Stepped
                                    select plotTile;

        bool notExpectedStepsExist = queryNotExpectedSteps.Count() > 0;

        check.wrongSteps     = queryNotExpectedSteps.Count();
        check.mandatorySteps = !notExpectedStepsExist && allTheMandatoryStepsDone;


        // 5. This list contains the distinct blox types, and their count
        List <Tuple <Type, int> > usedBloxTypeCount = rootBlox.GetAllBloxesBellow().GroupBy(b => b.GetType()).Select(g => new Tuple <Type, int>(g.First().GetType(), g.Count())).ToList();

        List <ExpectedBlox> mandatoryBloxesFullyUsed = LevelConfiguration.MandatoryBloxes.Where(mb => usedBloxTypeCount.Exists(b => b.Item1 == mb.BloxType && b.Item2 >= mb.MinimumQuantity)).ToList();

        check.mandatoryBloxes = mandatoryBloxesFullyUsed.Count == LevelConfiguration.MandatoryBloxes.Count();


        List <ExpectedBlox> expectedOptionalBloxesUsed = LevelConfiguration.OptionalExpectedBloxes.Where(mb => usedBloxTypeCount.Exists(b => b.Item1 == mb.BloxType)).ToList();
        int numberOfOptionalBloxesUsed = usedBloxTypeCount
                                         // Gets all the used bloxes that are of the type of one expected to be used
                                         .Where(b => LevelConfiguration.OptionalExpectedBloxes.Exists(mb => mb.BloxType == b.Item1))
                                         // Gets the amount used. If the amount used is bigger than the minimum expected, uses the later value
                                         // If it is expected to use 2 bloxes of Int, and 1 of If, we don't want to classify a full use of option bloxes
                                         // if the user put 3 Int bloxes
                                         .Select(b => Math.Min(b.Item2, LevelConfiguration.OptionalExpectedBloxes.First(o => o.BloxType == b.Item1).MinimumQuantity)).Sum();


        check.optionalBloxesUsedPercentage = LevelConfiguration.OptionalExpectedBloxes.Count == 0 ? 1 : numberOfOptionalBloxesUsed * 1f / LevelConfiguration.OptionalExpectedBloxes.Select(o => o.MinimumQuantity).Sum();

        check.maxAttemptsExpected        = Convert.ToInt32(LevelConfiguration.MaxAttempts);
        check.maxLinesExpected           = Convert.ToInt32(LevelConfiguration.MaxCodeLinesExpected);
        check.maxMinutesExpected         = Convert.ToInt32(LevelConfiguration.MaxTimeInMinutes);
        check.maxOptionalBloxesExpected  = Convert.ToInt32(LevelConfiguration.OptionalExpectedBloxes.Select(o => o.MinimumQuantity).Sum());
        check.numberOfOptionalBloxesUsed = numberOfOptionalBloxesUsed;
        return(new Evaluation(check));
    }