Ejemplo n.º 1
0
 /// <summary>
 /// Activate delay stoppers per current rod before next action
 /// </summary>
 /// <param name="action">Action to be perfomed</param>
 private void ActivateDelay(RodAction action)
 {
     if (action.Linear != eLinearMove.NA || action.Rotation != eRotationalMove.NA)
     {
         _sectorWatch[action.RodType] = Stopwatch.StartNew();
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Main Decision Flow Method decides on action and sets property of responding player
        /// </summary>
        /// <param name="rod">Rod to use for decision</param>
        /// <param name="bfc">Ball Future coordinates</param>
        /// <returns>Rod Action to perform</returns>
        public override RodAction Decide(IRod rod, BallCoordinates bfc)
        {
            RodAction action = new RodAction(rod.RodType);

            //Action will be ignored if not enough time passed since last request was made inside sector
            if (!IgnoreDecision(rod.RodType))
            {
                //Get relative Y position and set Responding Player
                eYPositionPlayerRelative relativeY = BallYPositionToPlayerYCoordinate(bfc.Y, rod);

                //Get relative X position
                eXPositionRodRelative relativeX = BallXPositionToRodXPosition(bfc.X, rod);

                /*
                 * Beta Version of inner DECISION TREE
                 */
                switch (relativeX)
                {
                    case eXPositionRodRelative.FRONT:
                        switch (relativeY)
                        {
                            case eYPositionPlayerRelative.RIGHT:
                            case eYPositionPlayerRelative.LEFT:
                                switch (rod.State.ServoPosition)
                                {
                                    case eRotationalMove.RISE:
                                    case eRotationalMove.DEFENCE:
                                        action = new RodAction(rod.RodType, eRotationalMove.DEFENCE, eLinearMove.BALL_Y);
                                        break;
                                    case eRotationalMove.KICK:
                                        action = new RodAction(rod.RodType, eRotationalMove.DEFENCE, eLinearMove.NA);
                                        break;
                                }
                                break;
                            case eYPositionPlayerRelative.CENTER:
                                switch (rod.State.ServoPosition)
                                {
                                    case eRotationalMove.RISE:
                                    case eRotationalMove.DEFENCE:
                                        action = new RodAction(rod.RodType, eRotationalMove.KICK, eLinearMove.NA);
                                        break;
                                    case eRotationalMove.KICK:
                                        if (_helper.IsEnoughSpaceToMove(rod, rod.State.DcPosition, BALL_RADIUS))
                                        {
                                            action = new RodAction(rod.RodType, eRotationalMove.NA, eLinearMove.RIGHT_BALL_DIAMETER);
                                        }
                                        else
                                        {
                                            action = new RodAction(rod.RodType, eRotationalMove.NA, eLinearMove.LEFT_BALL_DIAMETER);
                                        }
                                        break;
                                }
                                break;
                        }
                        break;
                    case eXPositionRodRelative.CENTER:
                    case eXPositionRodRelative.BACK:
                        switch (relativeY)
                        {
                            case eYPositionPlayerRelative.RIGHT:
                            case eYPositionPlayerRelative.LEFT:
                                switch (rod.State.ServoPosition)
                                {
                                    case eRotationalMove.RISE:
                                        action = new RodAction(rod.RodType, eRotationalMove.RISE, eLinearMove.BALL_Y);
                                        break;
                                    case eRotationalMove.DEFENCE:
                                        action = new RodAction(rod.RodType, eRotationalMove.RISE, eLinearMove.NA);
                                        break;
                                    case eRotationalMove.KICK:
                                        action = new RodAction(rod.RodType, eRotationalMove.DEFENCE, eLinearMove.NA);
                                        break;
                                }
                                break;
                            case eYPositionPlayerRelative.CENTER:
                                switch (rod.State.ServoPosition)
                                {
                                    case eRotationalMove.RISE:
                                        action = new RodAction(rod.RodType, eRotationalMove.KICK, eLinearMove.NA);
                                        break;
                                    case eRotationalMove.DEFENCE:
                                    case eRotationalMove.KICK:
                                        if (_helper.IsEnoughSpaceToMove(rod, rod.State.DcPosition, BALL_RADIUS))
                                        {
                                            action = new RodAction(rod.RodType, eRotationalMove.NA, eLinearMove.RIGHT_BALL_DIAMETER);
                                        }
                                        else
                                        {
                                            action = new RodAction(rod.RodType, eRotationalMove.NA, eLinearMove.LEFT_BALL_DIAMETER);
                                        }
                                        break;
                                }
                                break;
                        }
                        break;
                }
                Log.Print(String.Format("Defined action for {0}: [{1}] [{2}]", rod.RodType, action.Rotation, action.Linear),
                    eCategory.Info, LogTag.DECISION);
                ActivateDelay(action);

                //Define actual desired rod coordinate to move to
                int startStopperDesiredY = CalculateNewRodCoordinate(rod, RespondingPlayer, bfc, action.Linear);
                action.DcCoordinate = rod.NearestPossibleDcPosition(startStopperDesiredY);
            }
            else
            {
                Log.Print(String.Format("Ignoring inner tree of {0} for {1} milliseconds", rod.RodType,
                    (ACTION_DELAY - _sectorWatch[rod.RodType].Elapsed).TotalMilliseconds), eCategory.Debug, LogTag.DECISION);
            }

            //Set last decided rod and player coordinates if it was defined
            if (action.Linear!=eLinearMove.NA) rod.State.DcPosition = action.DcCoordinate;
            if (_helper.ShouldSetServoStateFromTree(rod.RodType))
                if (action.Rotation != eRotationalMove.NA) rod.State.ServoPosition = action.Rotation;

            return action;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Choose player to respond on current rod and action to perform
        /// </summary>
        /// <param name="rod">Current rod</param>
        /// <param name="bfc">Ball Future Coordinates</param>
        /// <param name="respondingPlayer">Responding Player index (1 based) on current rod [out]</param>
        /// <returns>Rod Action to be performed</returns>
        protected RodAction DefineActionAndRespondingPlayer(IRod rod, BallCoordinates bfc, out int respondingPlayer)
        {
            if (rod == null)
                throw new ArgumentException(String.Format(
                     "[{0}] Unable to define action and responding player while rod argument is NULL!",
                        MethodBase.GetCurrentMethod().Name));

            if (bfc == null || !bfc.IsDefined)
                throw new ArgumentException(String.Format(
                    "[{0}] Unable to define action and responding player while ball coordinates are NULL or UNDEFINED!",
                        MethodBase.GetCurrentMethod().Name));

            RodAction action = null;
            respondingPlayer = -1;
            switch (_helper.IsBallInSector(bfc.X, rod.RodXCoordinate, rod.DynamicSector))
            {
                //Ball is in Current Rod Sector
                case eXPositionSectorRelative.IN_SECTOR:
                    action = SubTree.Decide(rod, bfc);
                    respondingPlayer = SubTree.RespondingPlayer;
                    break;

                    /* OLD :
                     *  //The Big Sub Tree
                     *  action = EnterDecisionTreeBallInSector(rod, bfc, out respondingPlayer);
                     */

                //Ball is ahead of Current Rod Sector
                case eXPositionSectorRelative.AHEAD_SECTOR:
                    //Ball Vector Direction is TO Current Rod and we have intersection point
                    if (_helper.IsBallVectorToRod(bfc.Vector) &&
                            rod.Intersection.IsDefined)
                    {
                        action = new RodAction(rod.RodType, eRotationalMove.DEFENCE, eLinearMove.VECTOR_BASED);
                        
                        //Define responding player index
                        BallYPositionToPlayerYCoordinate(bfc.Y, rod);
                        respondingPlayer = this.RespondingPlayer;
                    }
                    else
                    {
                        //Ball Vector Direction is FROM Current Rod
                        action = new RodAction(rod.RodType, eRotationalMove.DEFENCE, eLinearMove.BEST_EFFORT);
                    }
                    break;
                //Ball is behind Current Rod Sector
                case eXPositionSectorRelative.BEHIND_SECTOR:
                    action = new RodAction(rod.RodType, eRotationalMove.RISE, eLinearMove.BEST_EFFORT);
                    break;
            }
            return action;
        }