private Point GetGoalSpeed(AHEntities.Action direction, double x, double y, Point Pg)
        {
            Point  Vg;
            Random random = new Random();

            switch (direction)
            {
            case AHEntities.Action.ATTACK_LEFT:
                Vg = new Point(random.Next(400, 600), -random.Next(200, 300));
                break;

            case AHEntities.Action.ATTACK_RIGHT:
                Vg = new Point(random.Next(400, 600), random.Next(200, 300));
                break;

            case AHEntities.Action.ATTACK_MIDDLE:
                int    Vx = random.Next(500, 700);
                double t  = (1180.0 - x) / Vx;
                int    Vy = -Convert.ToInt32(t * y);
                Vg = new Point(Vx, Vy);
                break;

            default:
                Vg = new Point();
                break;
            }
            return(Vg);
        }
 public SimpleLinesActionPlanningStrategy(WorldModel WM)
 {
     worldModel = WM;
     mLogger    = Logger.Logger.Instance;
     random     = new Random();
     lastPlan   = null;
     lastAction = AHEntities.Action.LEAVE;
 }
        private PointParams CalculateDirectedAttack(AHEntities.Action direction, Point puckP, Point puckV, double puckR,
                                                    double xline, int tableW, int tableH)
        {
            PointParams finalConditions = new PointParams();

            double[] crossParamsAttack = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, puckR, xline, tableW, tableH);

            Point XYi = GetCollissionPoint(puckV.X, puckV.Y, xline, crossParamsAttack[0], direction);
            // Detemine speeds at the goal.
            Point  Pg     = new Point(1180, 0);
            Point  speedG = GetGoalSpeed(direction, xline, crossParamsAttack[0], Pg);
            double thetaG = -speedG.X / rp; // constrain on the angle speed at the goal
            double vG     = speedG.Norm();

            double vPS;
            Point  speedPS;
            double thetaPS, thetaPSdot;

            if (direction != AHEntities.Action.ATTACK_MIDDLE)
            {
                // calculating angles
                double alpha = CalculateAlpha(speedG, AHEntities.Action.ATTACK_RIGHT);
                double beta  = CalculateBeta(direction, xline, crossParamsAttack[0], tableH, Pg, alpha);
                // calculating post strike prameters
                vPS        = -vG / e * Math.Sin(alpha) / Math.Sin(beta);
                speedPS    = new Point(vPS * Math.Cos(beta), vPS * Math.Sin(beta));
                thetaPS    = Math.Atan2(speedPS.Y, speedPS.X);
                thetaPSdot = 2 * vG / (rp * e) * Math.Sin(alpha) / Math.Tan(beta) - 3 * vG / rp * Math.Cos(alpha);
            }
            else // direction == MIDDLE
            {
                // calculating post strike prameters
                vPS        = 0;
                speedPS    = new Point();
                thetaPS    = 0;
                thetaPSdot = 0;
            }

            // calculating frames rotation angle
            double thetaP = Math.Atan2(puckV.Y, puckV.X);
            double thetaC = CalculateRotationAngle(thetaPS, thetaPSdot, thetaP, puckR, vPS, puckV.Norm());
            // transform puck and ps velocities to impact frame
            Point impactVps = TransformFrames(thetaC, speedPS, true);
            Point impactVp  = TransformFrames(thetaC, puckV, true);
            // calculate control velocities
            Point impactVm = CalculateImpactVelocities(impactVp, impactVps, thetaP, thetaPS, rp);
            // transform to XY
            Point vM = TransformFrames(thetaC, impactVm, false);

            // create finalConditions.
            Point target = CalculateTargetPoint(XYi, new Point(AHEntities.EstimateLineCrossing.attackLine, crossParamsAttack[0]));

            finalConditions.AddParameters(target);
            finalConditions.AddParameters(vM);
            finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParamsAttack[1]);

            return(finalConditions);
        }
 private double CalculateAlpha(Point SpeedGoal, AHEntities.Action direction)
 {
     if (direction == AHEntities.Action.ATTACK_LEFT)
     {
         return(Math.Atan2(-SpeedGoal.Y, SpeedGoal.X));
     }
     else
     {
         return(Math.Atan2(SpeedGoal.Y, SpeedGoal.X));
     }
 }
        private PointParams CalculateNaiveDirectedAttack(AHEntities.Action direction, Point puckPline, double time,
                                                         double xline, double puckRadius, double malletRadius, int tableW, int tableH, double velocity)
        {
            PointParams finalConditions = new PointParams();
            Point       collisionPoint, targetPoint, targetVelocity;

            collisionPoint = GetNaiveCollisionPoint(direction, puckPline, puckRadius - 2, tableW, tableH);
            targetPoint    = GetNaiveTargetPoint(puckPline, collisionPoint, malletRadius - 2);
            targetVelocity = GetNaiveTargetVelocity(collisionPoint, targetPoint, velocity);

            finalConditions.AddParameters(targetPoint);
            finalConditions.AddParameters(targetVelocity);
            finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(time);

            return(finalConditions);
        }
        private double CalculateBeta(AHEntities.Action direction, double x, double y, double tableY, Point Pg, double alpha)
        {
            double yp, a1;

            if (direction == AHEntities.Action.ATTACK_LEFT)
            {
                a1 = tableY / 2 - Pg.Y;
                yp = tableY / 2 - y;
            }
            else // ATTACK_RIGHT
            {
                a1 = Pg.Y - tableY / 2;
                yp = tableY / 2 - y;
            }
            double b1   = a1 / Math.Tan(alpha);
            double b2   = (Pg.X - x) - b1;
            double beta = Math.Atan2(yp, b2);

            return(beta);
        }
        private Point GetNaiveCollisionPoint(AHEntities.Action direction, Point puckPline, double puckRadius, int tableW, int tableH)
        {
            Point  attackVector   = new Point();
            Point  collisionPoint = null;
            Point  wallCollision  = null;
            double ratio          = 0;

            switch (direction)
            {
            case AHEntities.Action.ATTACK_RIGHT:
                ratio         = Math.Abs(puckPline.Y - (-tableH / 2)) / (tableH / 2);
                wallCollision = new Point(Math.Abs(tableW / 2 - puckPline.X) / (1 + ratio) + puckPline.X, -tableH / 2);
                attackVector  = (wallCollision - puckPline).Normalize();
                attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius);
                collisionPoint = puckPline - attackVector;
                break;

            case AHEntities.Action.ATTACK_MIDDLE:
                attackVector.X = tableW / 2 - puckPline.X;
                attackVector.Y = -puckPline.Y;
                attackVector   = attackVector.Normalize();
                attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius);
                collisionPoint = puckPline - attackVector;
                break;

            case AHEntities.Action.ATTACK_LEFT:
                ratio         = Math.Abs(puckPline.Y - tableH / 2) / (tableH / 2);
                wallCollision = new Point(Math.Abs(tableW / 2 - puckPline.X) / (1 + ratio) + puckPline.X, tableH / 2);
                attackVector  = (wallCollision - puckPline).Normalize();
                attackVector.Set(attackVector.X * puckRadius, attackVector.Y * puckRadius);
                collisionPoint = puckPline - attackVector;
                break;

            default:
                collisionPoint = null;
                break;
            }

            return(collisionPoint);
        }
Пример #8
0
        public override AHEntities.ActionDirective SelectAction(SenseEventType planReason)
        {
            Dictionary <string, double> physicalState = WM.GetPhysicalState();

            double[] crossParamsGoal, crossParamsAttack, crossParamsDefense;
            bool     isThreat     = false;
            double   time2goal    = 0;
            double   time2attack  = 0;
            double   time2defense = 0;

            AHEntities.ActionDirective action = new ActionDirective();
            action.TimeStamp = DateTime.Now;

            #region stuck events handling
            if (planReason == SenseEventType.StuckPlayer)
            {
                action.Action   = AHEntities.Action.PREPARE;
                action.Duration = TimeSpan.FromSeconds(1);
                return(action);
            }
            if (planReason == SenseEventType.StuckAgent)
            {
                action.Action   = AHEntities.Action.STUCK_ATTACK;
                action.Duration = TimeSpan.FromSeconds(0.3);
                return(action);
            }

            #endregion stuck events handling

            #region Crossing calculations
            Point puckP = new Point(physicalState["PuckX"], physicalState["PuckY"]);
            Point puckV = new Point(physicalState["PuckVx"], physicalState["PuckVy"]);
            try
            {
                // (y, T)
                crossParamsGoal = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32,
                                                                           AHEntities.EstimateLineCrossing.goalLine, (int)global["Tablewidth"], (int)global["Tableheight"]);

                crossParamsDefense = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32,
                                                                              AHEntities.EstimateLineCrossing.defenseAttackLine, (int)global["Tablewidth"], (int)global["Tableheight"]);

                crossParamsAttack = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, 32,
                                                                             AHEntities.EstimateLineCrossing.attackLine, (int)global["Tablewidth"], (int)global["Tableheight"]);
            }
            catch (Exception)
            {
                action.Action   = AHEntities.Action.LEAVE;
                action.Duration = TimeSpan.FromSeconds(0);
                return(action);
            }
            #endregion Crossing calculations

            // not directed to the goal
            if (crossParamsGoal == null)
            {
                action.Action   = AHEntities.Action.PREPARE;
                action.Duration = TimeSpan.FromSeconds(1);
                return(action);
            }

            // is directed to the goal
            if ((crossParamsGoal[0] < 220) && (crossParamsGoal[0] > -220))
            {
                isThreat = true;
            }

            // time to reach the goal and attack lines
            time2goal    = crossParamsGoal[1];
            time2defense = crossParamsDefense[1];
            time2attack  = crossParamsAttack[1];

            #region emergency Block/Leave
            // puck is too fast, immidiate BLOCK or LEAVE
            if (time2goal < 0.2)
            {
                if (isThreat)
                {
                    action.Action   = AHEntities.Action.BLOCK;
                    action.Duration = TimeSpan.FromSeconds(time2goal);
                    return(action);
                }
                else
                {
                    action.Action   = AHEntities.Action.LEAVE;
                    action.Duration = TimeSpan.FromSeconds(0);
                    return(action);
                }
            }
            #endregion emergency Block/Leave

            if (time2attack < 0.5)      // defense attack (no time to calcualte elaborated attack
            {
                action.Action   = AHEntities.Action.DEFENSE_ATTACK;
                action.Duration = TimeSpan.FromSeconds(time2defense);
                return(action);
            }
            else // Directed attack
            {
                int    height = (int)global["Tableheight"] / 2;
                double rim    = height * 0.95;
                action.Duration = TimeSpan.FromSeconds(time2attack);

                // puck is crossing on the rim of the table
                if (Math.Abs(crossParamsAttack[0]) > rim)
                {
                    action.Action   = AHEntities.Action.DEFENSE_ATTACK;
                    action.Duration = TimeSpan.FromSeconds(time2defense);
                    return(action);
                }
                else // crossing on the inside of the table
                {
                    Random random = new Random();
                    AHEntities.Action[] attacks;
                    double outerTable = height * 0.65;
                    if (Math.Abs(crossParamsAttack[0]) > outerTable)    // outer part
                    {
                        if (crossParamsAttack[2] > height - outerTable) // Agent's left part
                        {
                            attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_RIGHT,
                                                                AHEntities.Action.ATTACK_MIDDLE };
                        }
                        else // Agent's right part
                        {
                            attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_LEFT,
                                                                AHEntities.Action.ATTACK_MIDDLE };
                        }
                    }
                    else // inner part
                    {
                        attacks = new AHEntities.Action[] { AHEntities.Action.ATTACK_LEFT,
                                                            AHEntities.Action.ATTACK_MIDDLE,
                                                            AHEntities.Action.ATTACK_RIGHT };
                    }
                    action.Action = attacks[random.Next(attacks.Length)];
                    return(action);
                }
            }
        }
        public override PointParams ActionPlanning(AHEntities.ActionDirective action, bool isNewPlaning)
        {
            AHEntities.Action A = action.Action;
            PointParams       finalConditions = null;
            Random            random = new Random();
            Point             puckP, puckV;

            physicalState = worldModel.GetPhysicalState();
            puckP         = new Point(physicalState["PuckX"], physicalState["PuckY"]);
            puckV         = new Point(physicalState["PuckVx"], physicalState["PuckVy"]);
            global        = worldModel.GetSize();
            Point crossing;

            double[] crossParams;

            switch (A)
            {
            case AHEntities.Action.BLOCK:
                #region BLOCK
                crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp,
                                                                       AHEntities.EstimateLineCrossing.blockLine, global[0], global[1]);
                crossing = new Point(AHEntities.EstimateLineCrossing.blockLine, crossParams[0]);
                Point defendPoint = AHEntities.EstimateLineCrossing.CalculateActionPoint(crossing,
                                                                                         new Point(crossParams[2], crossParams[3]), rp, rm);
                mLogger.AddLogMessage("LowLevel Planning BLOCK: estimated collission: mallet: " + defendPoint.ToString() +
                                      ", puck: " + crossing.ToString());
                finalConditions = new PointParams();
                finalConditions.AddParameters(defendPoint);
                finalConditions.AddParameters(new Point(0, 0));
                finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParams[1]);
                break;

                #endregion BLOCK
            case AHEntities.Action.LEAVE:
                #region LEAVE
                finalConditions = null;
                break;

                #endregion LEAVE
            case AHEntities.Action.ATTACK_RIGHT:
                #region ATTACK_RIGHT
                //finalConditions = CalculateDirectedAttack(AHEntities.Action.ATTACK_RIGHT, puckP, puckV, physicalState["PuckR"],
                //                  AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]);
                //break;
                #endregion ATTACK_RIGHT
            case AHEntities.Action.ATTACK_LEFT:
                #region ATTACK_LEFT
                //finalConditions = CalculateDirectedAttack(AHEntities.Action.ATTACK_LEFT, puckP, puckV, physicalState["PuckR"],
                //                  AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]);
                //break;
                #endregion ATTACK_LEFT
            case AHEntities.Action.ATTACK_MIDDLE:
                #region ATTACK_MIDDLE
                crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp,
                                                                       AHEntities.EstimateLineCrossing.attackLine, global[0], global[1]);
                mLogger.AddLogMessage("LowLevel: Puck Estimated at: (" + AHEntities.EstimateLineCrossing.attackLine.ToString() + "," + crossParams[0].ToString() + ") in " + crossParams[1].ToString() + " seconds");
                Point  puckPline = new Point(AHEntities.EstimateLineCrossing.attackLine, crossParams[0]);
                double velocity  = 1000;
                finalConditions = CalculateNaiveDirectedAttack(A, puckPline, crossParams[1],
                                                               AHEntities.EstimateLineCrossing.attackLine, rp, rm, global[0], global[1], velocity);
                break;

                #endregion ATTACK_MIDDLE
            case AHEntities.Action.DEFENSE_ATTACK:
                #region DEFENSE_ATTACK
                if (Math.Abs(puckV.X) < 0.01)
                {
                    break;
                }
                crossParams = AHEntities.EstimateLineCrossing.Estimate(puckP, puckV, rp,
                                                                       AHEntities.EstimateLineCrossing.defenseAttackLine, global[0], global[1]);
                if (crossParams == null)
                {
                    finalConditions = null;
                    break;
                }
                crossing = new Point(AHEntities.EstimateLineCrossing.defenseAttackLine, crossParams[0]);
                Point attackPoint = AHEntities.EstimateLineCrossing.CalculateActionPoint(new Point(AHEntities.EstimateLineCrossing.defenseAttackLine, crossParams[0]),
                                                                                         new Point(crossParams[2], crossParams[3]), rp, rm);
                mLogger.AddLogMessage("LowLevel Planning DEFENSE_ATTACK: estimated collission: mallet: " + attackPoint.ToString() +
                                      ", puck estimated at: " + crossing.ToString());

                finalConditions = new PointParams();
                finalConditions.AddParameters(attackPoint);
                double yvel = (attackPoint.Y > 0) ? (yvel = -200) : (yvel = 200);
                finalConditions.AddParameters(new Point(500, yvel));
                finalConditions.T = DateTime.Now + TimeSpan.FromSeconds(crossParams[1]);
                break;

                #endregion DEFENSE_ATTACK
            case AHEntities.Action.PREPARE:
                #region PREPARE
                finalConditions = new PointParams();
                finalConditions.AddParameters(new Point(-1000, 0));
                finalConditions.AddParameters(new Point(0, 0));
                finalConditions.T = action.TimeStamp + TimeSpan.FromSeconds(0.5);
                break;

                #endregion PREPARE
            case AHEntities.Action.STUCK_ATTACK:
                #region STUCK_ATTACK
                double stuckTime;
                stuckTime = (action.Duration - (DateTime.Now - action.TimeStamp)).TotalSeconds;
                Point stuckAttackPoint = AHEntities.EstimateLineCrossing.EstimateStuck(puckP, puckV, rp, global[0], global[1], stuckTime, rm);
                if (stuckAttackPoint == null)
                {
                    finalConditions = null;
                    break;
                }
                mLogger.AddLogMessage("LowLevel Planning STUCK_ATTACK: estimated collission: mallet: " + stuckAttackPoint.ToString());
                finalConditions = new PointParams();
                finalConditions.AddParameters(stuckAttackPoint);
                finalConditions.AddParameters(new Point(0, 0));
                finalConditions.T = action.TimeStamp + TimeSpan.FromSeconds(stuckTime);
                break;

                #endregion STUCK_ATTACK
            default:
                #region default
                finalConditions = null;
                break;
                #endregion default
            }

            //saving current planning (action and parameters)
            lastAction = A;
            if (finalConditions != null)
            {
                if (lastPlan == null)
                {
                    lastPlan = new PointParams();
                }
                lastPlan.Clear();
                lastPlan.AddParameters(finalConditions.GetParamsByIndex(1));
                lastPlan.AddParameters(finalConditions.GetParamsByIndex(2));
                lastPlan.T = finalConditions.T;
            }
            else
            {
                lastPlan = null;
            }

            return(finalConditions);
        }
        private Point GetCollissionPoint(double PuckVx, double PuckVy, double xLine, double y, AHEntities.Action attackDirection)
        {
            Point  XYi = new Point();
            Random random = new Random();
            int    a, b;


            switch (attackDirection)
            {
            case AHEntities.Action.ATTACK_LEFT:
                if (PuckVy > 0)
                {
                    a     = random.Next(5);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y + a;
                    XYi.X = xLine - b;
                }
                else
                {
                    a     = random.Next(10);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y - a;
                    XYi.X = xLine - b;
                }
                break;

            case AHEntities.Action.ATTACK_MIDDLE:
                if (PuckVy > 0)
                {
                    a     = random.Next(3);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y + a;
                    XYi.X = xLine - b;
                }
                else
                {
                    a     = random.Next(3);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y - a;
                    XYi.X = xLine - b;
                }
                break;

            case AHEntities.Action.ATTACK_RIGHT:
                if (PuckVy > 0)
                {
                    a     = random.Next(10);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y + a;
                    XYi.X = xLine - b;
                }
                else
                {
                    a     = random.Next(5);
                    b     = (int)Math.Round(Math.Sqrt(rp * rp - a * a));
                    XYi.Y = y - a;
                    XYi.X = xLine - b;
                }
                break;
            }
            return(XYi);
        }