public Ellipse(Vector centerPt, int radius1, int radius2)
 {
     Geometry = new EllipseGeometry(centerPt.ToWindowsPt(), (double)radius1, (double)radius2);
     DrawMe = true;
     BoundingRectangle = Geometry.Bounds;
     CenterPoint = centerPt;
 }
예제 #2
0
        public static bool CheckForCollisionBetweenCircleAndLine(Vector p, double r, Vector s, Vector e)
        {
            var result = false;
            var d = e - s;
            var f = s - p;
            var a = d ^ d;
            var b = 2 * f ^ d;
            var c = f ^ f + (-r * r);

            var discriminant = b * b - 4 * a * c;
            if (discriminant >= 0)
            {
                discriminant = Math.Sqrt(discriminant);
                var t1 = (-b - discriminant) / (2 * a);
                var t2 = (-b + discriminant) / (2 * a);

                if (t1 >= 0 && t1 <= 1)
                {
                    result = true;
                }

                if (t2 >= 0 && t2 <= 1)
                {
                    result = true;
                }
            }

            return result;
        }
 public Ellipse(Vector centerPt, Tuple<int,int> radii)
 {
     Geometry = new EllipseGeometry(centerPt.ToWindowsPt(), (double)radii.Item1, (double)radii.Item2);
     DrawMe = true;
     BoundingRectangle = Geometry.Bounds;
     CenterPoint = centerPt;
 }
예제 #4
0
파일: Line.cs 프로젝트: yojig/CloudBall
 internal static Line Normal(Line line, Vector point)
 {
     if (line.K == 0) return new Line(0, 0);
     var kn = Math.Round(-1f / line.K, 1);
     var bn = Math.Round(point.Y - kn * point.X, 1);
     return new Line(kn, bn);
 }
예제 #5
0
        public void DoAction(Game game, Player self)
        {
            var ball = game.Ball;
            var goal = Field.EnemyGoal.Center;

            if (ball.Owner == self)
            {
                var closestToGoal = goal.GetClosest(game.Enemy);
                if (closestToGoal.GetDistanceTo(goal) > Field.EnemyGoal.Height*0.7)
                {
                    self.ActionShootGoal();
                    return;
                }

                var enemyToGoal = game.Enemy.Players
                    .Where(pl => pl.Position.X > self.Position.X - 40)
                    .Select(pl => new { pl, dist = pl.GetDistanceTo(self) })
                    .OrderBy(tp => tp.dist)
                    .FirstOrDefault();

                if (enemyToGoal != null && enemyToGoal.dist < 120)
                {
                    self.ActionShoot(game.GetSmartShoot(self));
                    return;
                }

                var closestEnemy = self.GetClosest(game.Enemy);
                if (self.GetDistanceTo(closestEnemy) < 50)
                {
                    self.ActionShoot(game.GetSmartShoot(self));
                    return;
                }

                self.ActionGo(goal);
                return;
            }

            if (Utility.TryField(game, self))
                return;

            var centerX = goal.X*0.8;

            IPosition target;
            if (ball.Position.X > goal.X * 0.6)
            {
                var targetX = Math.Max(centerX, ball.Position.X * 0.95);
                var mul = ball.Position.Y < goal.Y ? 1 : -1;
                var targetY = goal.Y + Field.EnemyGoal.Height * 0.6 * mul;

                target = new Vector(targetX, targetY);
            }
            else
            {
                target = new Vector(centerX, goal.Y);
            }


            self.ActionGo(target);
        }
예제 #6
0
        private FoodElement(Vector position)
        {
            var config = ConfigManager.Current;

            Position = position;
            Radius = config.FoodElementRadius;
            HealthPoints = config.FoodElementHealthPoints;
        }
예제 #7
0
 public LineSegment(Vector start, Angle angle, double length)
 {
     this.StartingPos = start;
     this.magnitude = length;
     this.angle = angle;
     components.Add(magnitude * Math.Cos(angle.InRadians()));
     components.Add(magnitude * Math.Sin(angle.InRadians()));
     this.EndingPos = new Vector(StartingPos.GetX() + XComponent(),
                                 StartingPos.GetY() + YComponent());
     this.slope = Slope();
 }
예제 #8
0
 public LineSegment(double magnitude, Angle angle, Vector midpoint)
 {
     this.magnitude = magnitude;
     this.angle = angle;
     this.StartingPos = new Vector( midpoint.GetX() - .5*magnitude *Math.Cos(angle.InRadians()),
                         midpoint.GetY() - .5*magnitude * Math.Sin(angle.InRadians()));
     this.EndingPos = new Vector(midpoint.GetX() + .5 * magnitude * Math.Cos(angle.InRadians()),
                         midpoint.GetY() + .5 * magnitude * Math.Sin(angle.InRadians()));
     components.Add(EndingPos.GetX() - StartingPos.GetX());
     components.Add(EndingPos.GetY() - StartingPos.GetY());
 }
예제 #9
0
 public Angle AngleBetweenPoints(Vector CenterPoint)
 {
     Vector endPointToCenter = new LineSegment(EndingPos, CenterPoint).TranlsateToVector();
     Vector incomingVector = new LineSegment(EndingPos, StartingPos).TranlsateToVector();
     if ((endPointToCenter.Magnitude() * incomingVector.Magnitude() == 0))
         throw new DivideByZeroException();
     double cosineOfTheAngle = (incomingVector * endPointToCenter) / (endPointToCenter.Magnitude() * incomingVector.Magnitude());
     if (cosineOfTheAngle > 1 || cosineOfTheAngle < -1)
         throw new Exception("Out of range of  acos");
     Angle angleToReturn = new Angle(Math.Acos(cosineOfTheAngle));
     return angleToReturn;
 }
 public Ellipse(Vector centerPt, int radius1, int radius2)
 {
     this.CenterPoint = centerPt;
     this.Radius1 = radius1;
     this.Radius2 = radius2;
     this.BoundingRectangle = new System.Drawing.Rectangle((int)CenterPoint.GetX() - Radius1,
                             (int)CenterPoint.GetY() - Radius2,
                             (int)Radius1 * 2,
                             (int)Radius2 * 2);
     this.Geometry = new System.Windows.Media.EllipseGeometry(CenterPoint.AsWindowsPoint(), (double)Radius1, (double)Radius2);
     this.DrawMe = true;
 }
예제 #11
0
 public LineSegment(Vector start, Vector end)
 {
     if (start.NumberOfDimensions != end.NumberOfDimensions)
         throw new Exception("Inconsistent dimensionalities");
     this.NumberOfDimensions = start.NumberOfDimensions;
     this.StartingPos = start;
     this.EndingPos = end;
     components.Add(EndingPos.GetX() - StartingPos.GetX());
     components.Add(EndingPos.GetY() - StartingPos.GetY());
     this.angle = Angle();
     this.slope = Slope();
     this.magnitude = Magnitude();
 }
예제 #12
0
		public float GetDistanceToGoalSquared(Vector position)
		{
			// above the goal
			if (position.Y <= Field.MyGoal.Top.Y)
			{
				return (Field.MyGoal.Top - position).LengthSquared;
			}
			if (position.Y >= Field.MyGoal.Bottom.Y)
			{
				return (Field.MyGoal.Bottom - position).LengthSquared;
			}
			var dX = Field.Borders.X - position.X;

			return dX * dX;
		}
예제 #13
0
        public static Vector GetNormalToVector(Vector pos, Vector ballPos, Vector ballDirection)
        {
            var hypotenuse = (pos - ballPos);
            var dotProduct = hypotenuse.Dot(ballDirection);
            var magnitudeH = Math.Sqrt(hypotenuse.X * hypotenuse.X + hypotenuse.Y * hypotenuse.Y);
            var magnituteD = Math.Sqrt(ballDirection.X * ballDirection.X + ballDirection.Y * ballDirection.Y);

            var cos = dotProduct / (magnitudeH * magnituteD);

            //var angle = Math.Acos(cos);
            var directionLength = hypotenuse.Length * cos;
            var scaledDirection = ballDirection.Unit() * directionLength;

            var result = (ballPos + scaledDirection) - pos;
            return result;
        }
예제 #14
0
 internal void InitiateRandomWalk(Vector startingPosition = null, double stepSize = 5, int numberOfSteps = 100000)
 {
     this.numberOfSteps = numberOfSteps;
     startingPosition = CurrentPosition;
     if (startingPosition == null) {
         CurrentPosition = new Vector(boardBounds.Width / 2, boardBounds.Height / 2);
     }
     Vector endingPosition = null;
     for (stepCounter = 0; stepCounter < numberOfSteps; stepCounter++) {
         double angleToWalk = newDirectionGenerator();
         double x2 = CurrentPosition.GetX() + stepSize * Math.Cos(angleToWalk);
         double y2 = CurrentPosition.GetY() + stepSize * Math.Sin(angleToWalk);
         endingPosition = new Vector(x2, y2);
         LineSegment newPath = new LineSegment(CurrentPosition, endingPosition);
         pathWalker(newPath, Color.Blue);
         testForCollisionAndAdd(newPath);
     }
 }
예제 #15
0
		public Vector Shoot(Vector source, Vector target, float str)
		{
			var vector = target - source;
			if (vector.Length != 0)
			{
				vector.Normalize();
			}
			str = Math.Max(0, Math.Min(Constants.PlayerMaxShootStr, str));
			var d = Rnd.NextDouble();
			var num2 = Rnd.NextDouble();
			var num3 = Math.Sqrt(-2.0 * Math.Log(d)) * Math.Sin(Math.PI * 2.0 * num2);
			var num4 = ((str / Constants.PlayerMaxShootStr) * Constants.BallMaxStrStd) * num3;
			vector.X = (float)((vector.X * Math.Cos(num4)) - (vector.Y * Math.Sin(num4)));
			vector.Y = (float)((vector.X * Math.Sin(num4)) - (vector.Y * Math.Cos(num4)));

			var result = ((vector * str) * Constants.BallMaxVelocity) / Constants.PlayerMaxShootStr;
			return result;
		}
예제 #16
0
파일: Agent.cs 프로젝트: ngkolev/smartworld
        private Agent(World world, Vector position, Vector lookAt)
        {
            var config = ConfigManager.Current;

            World = world;
            Position = position;
            LookAt = lookAt;
            Speed = config.AgentSpeed;
            EyeAngle = config.AgentEyeAngle;
            Health = config.AgentInitialHealth;
            Radius = config.AgentRadius;
            RotationAngle = config.AgentRotationAngle;
            HealthFactor = config.AgentHealthFactor;
            AgeFactor = config.AgentAgeFactor;
            TickLength = config.TickLength;

            Brain = new Network(NUMBER_OF_INPUTS, config.NumberOfNeuronsInHiddenLayer, NUMBER_OF_OUTPUTS);
        }
예제 #17
0
        public BasicFluid2D(int max_x, int max_y)
        {
            if (max_x != max_y) throw new ArgumentException();
            this.max_x = max_x;
            this.max_y = max_y;

            u_x = new double[max_x + 1, max_y];
            u_y = new double[max_x, max_y + 1];
            cells = new GridCell[max_x, max_y];
            A = new SparseMatrix(max_x * max_y);
            for (int i = 0; i < max_x; i++)
                for (int j = 0; j < max_y; j++)
                {
                    A[i * max_x + j, i * max_x + j] = 2 + (i == 0 || i + 1 == max_x ? 1 : 0) + (j == 0 || j + 1 == max_y ? 1 : 0);
                    if (i > 0)
                        A[(i - 1) * max_x + j, i * max_x + j] = A[i * max_x + j, (i - 1) * max_x + j] = -1;
                    if (j > 0)
                        A[i * max_x + j - 1, i * max_x + j] = A[i * max_x + j, i * max_x + j - 1] = -1;
                    if (i < max_x - 1)
                        A[(i + 1) * max_x + j, i * max_x + j] = A[i * max_x + j, (i + 1) * max_x + j] = -1;
                    if (j < max_y - 1)
                        A[i * max_x + j + 1, i * max_x + j] = A[i * max_x + j, i * max_x + j + 1] = -1;
                    cells[i, j] = new GridCell();
                    //cells[i, j].Adiag = (short)(2 + (i == 0 || i + 1 == max_x ? 1 : 0) + (j == 0 || j + 1 == max_y ? 1 : 0));
                    //cells[i, j].Aplusi = (short)(i + 1 < max_x ? -1 : 0);
                    //cells[i, j].Aplusj = (short)(j + 1 < max_y ? -1 : 0);
                    if (new Vector2(i - max_x / 2, j - max_y / 2).LengthSquared < max_x * max_y / 16)
                        cells[i, j].ImplicitSurface = 5;
                }
            using (TextWriter tw = new StreamWriter("output.txt")) tw.WriteLine(A.ToMatrixString(900, 900));
            solver = new
                MathNet.Numerics.LinearAlgebra.Double.Solvers.Preconditioners.IncompleteLU();
            solver.Initialize(A);
            p = new DenseVector(max_x * max_y);
            d = new DenseVector(max_x * max_y);
        }
예제 #18
0
 private void pathWalker(LineSegment path, Color color)
 {
     stepCounter++;
     if (color == null)
         color = Color.Brown;
     printToBoard(path, color);
     fullPathWalked.Add(path);
     CurrentPosition = path.EndingPos;
 }
예제 #19
0
 public static bool CheckForCollisionBetweenCircles(Vector p1, double r1, Vector p2, double r2)
 {
     return (p2.X - p1.X).Sqr() + (p1.Y - p2.Y).Sqr() <= (r1 + r2).Sqr();
 }
예제 #20
0
		private static bool MightCatch(Vector oppoVector, Vector targetVector, float power, float z)
		{
			var accuracy = Statistics.GetAccuracy(power, z);
			return Math.Abs(Theta.Create(oppoVector, targetVector)) < accuracy;
		}
예제 #21
0
파일: MadGuys.cs 프로젝트: yojig/CloudBall
        public void Action(Team myTeam, Team enemyTeam, Ball ball, MatchInfo matchInfo)
        {
            foreach (Player player in myTeam.Players)
            {
                Player closestEnemy = player.GetClosest(enemyTeam);
                switch (player.PlayerType)
                {
                    case PlayerType.Keeper:
                        if (ball.Owner == player)
                        {
                            var partner = player.GetClosestUncovered(myTeam, enemyTeam);
                            if (partner != null)
                            {
                                var power = player.GetDistanceTo(partner) / 10;
                                player.ActionShoot(partner, power);
                                continue;
                            }
                            else
                            {
                                // todo: shoot just to enemy side
                                player.ActionShootGoal();
                                continue;
                            }
                        }
                        if (player.GetDistanceTo(ball) < 50 
                            && player.CanPickUpBall(ball))
                        {
                            player.ActionPickUpBall();
                            continue;
                        }
                        if (ball.GetClosest(myTeam) == player
                            && ball.GetClosest(enemyTeam).GetDistanceTo(ball) < player.GetDistanceTo(ball)
                            && ball.GetDistanceTo(Field.MyGoal.Center) < 400)
                        {
                            player.ActionGo(ball.Position);
                            continue;
                        }

                        var direction = GoalKeeper.ChooseDirection(player, ball);
                        player.ActionGo(direction);
                        continue;

                    default:
                        if (ball.Owner == player)
                            if (player.GetDistanceTo(Field.EnemyGoal.Center) > 400)
                            {
                                var inters = player.GetClosestInterceptors(enemyTeam, 400);
                                if (!inters.Any())
                                {
                                    player.ActionGo(Field.EnemyGoal.Center);
                                    continue;
                                }
                                else if (inters.Count() >= 3)
                                {
                                    var partner = player.GetClosestUncovered(myTeam, enemyTeam);
                                    if (partner != null) player.ActionShoot(partner, 100);
                                }
                                var goalDirect = (Field.EnemyGoal.Center - player.Position).GetDirection();
                                var direct = (from i in inters
                                              select (i.Velocity) + (player.Position - i.Position).GetDirection() * (1 - i.GetDistanceTo(player) / 500))
                                              .Aggregate(Vector.Zero, (acc, v) => acc + v).GetDirection() + goalDirect;
                                var dest = player.Position + direct;
                                //if (direct.X < -50 && partner != null)
                                //{
                                //    player.ActionShoot(partner, 100);
                                //    continue;
                                //}
                                //else 
                                //    if (dest.Y < Field.Borders.Top.Y + 200
                                //    || dest.Y > Field.Borders.Bottom.Y - 200)
                                //{
                                //    player.ActionGo(dest + goalDirect * 2);
                                //    continue;
                                //}
                                //else 
                                //        if (dest.X > Field.Borders.Right.X - 100)
                                //{
                                //    player.ActionGo(Field.Borders.Center);
                                //    continue;
                                //}
                                //else 
                                //if (Field.Borders.Contains(dest))
                                //{
                                    player.ActionGo(dest);
                                    continue;
                                //}
                                //else
                                //{
                                //    player.ActionGo(Field.EnemyGoal.Center);
                                //    continue;
                                //}
                            }
                            else
                            {
                                //var goalkepers = from ep in enemyTeam.InFrontOf(player)
                                //                 ;

                                player.ActionShootGoal();
                            }
                        break;
                }

                if (ball.Owner == player) //Allways shoots for the enemy goal.
                { }
                else if (player.CanPickUpBall(ball)) //Picks up the ball if posible.
                    player.ActionPickUpBall();

                else if (player.CanTackle(closestEnemy)
                         && ball.Owner == closestEnemy) //Tackles any enemy that is close.
                    player.ActionTackle(closestEnemy);

                else if (player == ball.GetClosest(myTeam)) //If the player is closest to the ball, go for it.
                {
                    var balldirect = ball.Velocity.GetDirection();
                    var ndirect = new Vector(-balldirect.Y, balldirect.X);
                    var direct = (ball.Position - player.Position).GetDirection() * 10;
                    if (direct.Length < 50)
                        player.ActionGo(ball);
                    else
                        player.ActionGo(direct + ndirect);
                }
                else if (player.CanTackle(closestEnemy)) //Tackles any enemy that is close.
                    player.ActionTackle(closestEnemy);
                else //If the player cannot do anything urgently usefull, move to a good position.
                {
                    if (player.PlayerType == PlayerType.Keeper) //The keeper protects the goal.
                    { }
                    //The keeper positions himself 50 units out from the goal                                                                                                            //at the same height as the ball, although never leaving the goal
                    else if (player.PlayerType == PlayerType.LeftDefender)
                        player.ActionGo(new Vector(Field.Borders.Width * 0.2, ball.Position.Y));
                    //The left defender helps protect the goal
                    else if (player.PlayerType == PlayerType.RightDefender)
                        player.ActionGo(Field.MyGoal.GetClosest(enemyTeam));
                    //The right defender chases the enemy closest to myGoal
                    else if (player.PlayerType == PlayerType.RightForward)
                        player.ActionGo((Field.Borders.Center + Field.Borders.Bottom + ball.Position) / 3);
                    //Right forward stays in position on the midline, untill the ball comes close.
                    else if (player.PlayerType == PlayerType.LeftForward)
                        player.ActionGo((Field.Borders.Center + Field.Borders.Top + ball.Position) / 3);
                    //Left forward stays in position on the midline, untill the ball comes close.
                    else if (player.PlayerType == PlayerType.CenterForward)
                        player.ActionGo((Field.Borders.Center + Field.EnemyGoal.Center + ball.Position) / 3);
                    //Center forward stays in position on the enemy side of the field.
                }
            }
        }
예제 #22
0
        /// <summary>
        /// フェンスの位置によって、ボールの位置を補正する
        /// (人の位置を補正する場合にも使用できる。ゴロと同じ扱いのため、isFlyをfalseで指定する)
        /// </summary>
        /// <param name="basePoint">ボール位置</param>
        /// <param name="move">移動するVector</param>
        /// <param name="isFly">フライか</param>
        /// <param name="fenseReflect">外野フェンスに当たったか</param>
        /// <param name="fenseOver">外野フェンスを超えたか</param>
        /// <returns>補正後の位置</returns>
        private static MPoint ChangePointByFense(MPoint basePoint, Vector move, bool isFly, 
												out bool fenseReflect, out bool fenseOver)
        {
            fenseReflect = false;
            fenseOver = false;
            MPoint result = basePoint + move;

            // 捕逸か後方にファウルした場合、画面外にでないように補正
            // (フライの場合は補正せず、呼び出し元で判定)
            if (!isFly && result.Y < Constants.MinScreenPoint.Y)
            {
                return new MPoint(result.X, Constants.MinScreenPoint.Y);
            }

            // フェンスの手前であれば何もせずに値を返す
            // (後方のフェンスをフライで超える場合もそのまま返す)
            if ((result - Constants.PointHomeBase).Length < Constants.BaseToFenceDistance ||
                result.Y < Constants.MinScreenPoint.Y)
            {
                return result;
            }

            // 以下、フェンスを超える場合

            // フライでフェンス超えた場合はホームラン
            if (isFly)
            {
                fenseOver = true;
                return result;
            }

            // 以下、フェンスを超えるゴロの場合

            // フェンスを超える判定結果を設定
            fenseReflect = true;

            // フェンスを超える場合、フェンスまでで止める
            result = basePoint;
            do
            {
                // 超えるまで少しずつ足す
                result = result + new Vector(move.X * 0.1, move.Y * 0.1);
            }
            while ((result - Constants.PointHomeBase).Length < Constants.BaseToFenceDistance);

            // 最後に少しだけ超えた分の距離を戻す
            result = result - new Vector(move.X * 0.1, move.Y * 0.1);

            // フェンスの手前に補正した座標を返す
            return result;
        }
예제 #23
0
 /// <summary>
 /// フェンスの位置によって、守備メンバの位置を補正する
 /// </summary>
 /// <param name="basePoint">元の位置</param>
 /// <param name="move">移動ベクトル</param>
 /// <returns>移動後の位置</returns>
 private static MPoint ChangePointByFense(MPoint basePoint, Vector move)
 {
     bool fenseReflect;
     bool fenseOver;
     // isFlyをfalseで実行することで、ゴロ扱いし、フェンスを超えないように移動する
     return ChangePointByFense(basePoint, move, false, out fenseReflect, out fenseOver);
 }
예제 #24
0
파일: Line.cs 프로젝트: yojig/CloudBall
 internal static double B0(Vector p2, Vector p1)
 {
     return Math.Round(p2.Y - K0(p2, p1) * p2.X, 1);
 }
예제 #25
0
파일: Line.cs 프로젝트: yojig/CloudBall
 internal static double K0(Vector p2, Vector p1)
 {
     if (p2.X - p1.X == 0) return 0;
     return Math.Round((p2.Y - p1.Y) / (p2.X - p1.X), 1);
 }
예제 #26
0
        /// <summary>
        /// 指定時間後の守備メンバの位置を返す
        /// </summary>
        /// <param name="memberAbility">対象メンバ</param>
        /// <param name="goalPoint">目標位置位置</param>
        /// <param name="fitureSecond">指定時間</param>
        /// <returns>指定時間後の守備メンバの位置</returns>
        private MPoint GetDefenseMovePoint(GameMemberAbility memberAbility, MPoint goalPoint, int fitureSecond)
        {
            // 指定時間後の守備メンバの移動距離を取得
            double moveDistance = GetDefenseMoveDistance(memberAbility, fitureSecond);

            // 指定秒数後のメンバ位置を取得
            MPoint fitureMemberPoint;
            {
                MPoint memberPoint = GameData.GetDefensePoint(memberAbility.DefensePosition);

                // 目的位置とメンバの位置関係から進行方向のベクトルを取得
                Vector memberToGoalVector = (goalPoint - memberPoint);

                if (memberToGoalVector.Length > moveDistance)
                {
                    // ベクトルを正規化
                    double normalizing = memberToGoalVector.Length > 0 ? memberToGoalVector.Length : 1;
                    memberToGoalVector = new Vector(memberToGoalVector.X / normalizing, memberToGoalVector.Y / normalizing);

                    // 正規化したベクトルと移動距離から移動ベクトルを算出
                    Vector moveVector = new Vector(moveDistance * memberToGoalVector.X, moveDistance * memberToGoalVector.Y);

                    // フェンスによる位置の補正
                    fitureMemberPoint = ChangePointByFense(memberPoint, moveVector);
                }
                else
                {
                    // 目標位置までの距離が移動可能距離より小さい場合は、目標位置がそのまま最終位置になる
                    fitureMemberPoint = goalPoint;
                }

            }
            return fitureMemberPoint;
        }
예제 #27
0
파일: Line.cs 프로젝트: yojig/CloudBall
 internal static Line One(Vector p2, Vector p1)
 {
     return new Line(K0(p2, p1), B0(p2, p1));
 }
예제 #28
0
        /// <summary>
        /// 指定時間後の打球のボール位置を取得する
        /// </summary>
        /// <param name="battedBoll">打球</param>
        /// <param name="fitureSecond">指定時間</param>
        /// <param name="fenseReflect">フェンスに当たったか</param>
        /// <param name="fenseOver">フェンスを超えたか</param>
        /// <returns>ボール位置</returns>
        private MPoint GetFitureBollPoint(BattedBoll battedBoll, int fitureSecond, 
										 out bool fenseReflect, out bool fenseOver)
        {
            fenseReflect = false;
            fenseOver = false;

            double bollSpeed = battedBoll.Speed;
            MPoint fitureBollPoint = GameData.BollPoint;

            for (int second = 0; second < fitureSecond; second++)
            {
                Vector fitureMove = new Vector(bollSpeed * Math.Sin(battedBoll.SideDirection * Math.PI / 180),
                                               bollSpeed * Math.Cos(battedBoll.SideDirection * Math.PI / 180));

                // ゴロかフライか
                bool isFly = GameData.RemainingDropTime - second >= 0;

                // フェンスの補正
                fitureBollPoint = ChangePointByFense(fitureBollPoint, fitureMove, isFly, out fenseReflect, out fenseOver);

                // 打球速度の減速
                bollSpeed = GetBollSpeed(isFly, GameData.DefenseTermPassedSecond + second, fitureBollPoint, bollSpeed);

                if (isFly)
                {
                    // フライの場合

                    // フェンスを超えたらその時点の位置を返す
                    // (ゴロになるまで計算するとフェンスに跳ね返る可能性があるため)
                    if (fenseOver)
                    {
                        return fitureBollPoint;
                    }
                }
                else
                {
                    // ゴロの場合

                    // フェンスに当たった場合は速度0になるため、その時点の位置を返す
                    if (fenseReflect)
                    {
                        return fitureBollPoint;
                    }
                }
            }

            return fitureBollPoint;
        }
예제 #29
0
        public void DoAction(Game game, Player self)
        {
            var ball = game.Ball;
            var goal = Field.EnemyGoal.Center;

            if (ball.Owner == self)
            {
                var closestToGoal = goal.GetClosest(game.Enemy);
                if (closestToGoal.GetDistanceTo(goal) > Field.EnemyGoal.Height * 0.8)
                {
                    self.ActionShootGoal();
                    return;
                }

                var enemyToGoal = game.Enemy.Players
                    .Where(pl => pl.Position.X > self.Position.X - 40)
                    .Select(pl => new { pl, dist = pl.GetDistanceTo(self) })
                    .OrderBy(tp => tp.dist)
                    .FirstOrDefault();

                if (enemyToGoal != null && enemyToGoal.dist < 120)
                {
                    self.ActionShoot(game.GetSmartShoot(self));
                    return;
                }

                var closestEnemy = self.GetClosest(game.Enemy);
                if (self.GetDistanceTo(closestEnemy) < 50)
                {
                    self.ActionShoot(game.GetSmartShoot(self));
                    return;
                }

                self.ActionGo(Field.EnemyGoal.Bottom);
                return;
            }

            if (Utility.TryField(game, self))
                return;

            IPosition target;
            if (game.InAttack)
            {
                if (ball.Position.X > goal.X * 0.6)
                {
                    var centerX = goal.X * 0.82;
                    var targetX = Math.Max(centerX, ball.Position.X * 0.95);
                    var targetY = goal.Y - Field.EnemyGoal.Height * 0.75;

                    target = new Vector(targetX, targetY);
                }
                else
                {
                    target = new Vector(Field.Borders.Bottom.X, Field.MyGoal.Height * 0.7);
                }
            }
            else
            {
                var closestUpperPlayers = game.Enemy.Players
                    .Where(pl => pl.Position.Y < Field.Borders.Center.Y)
                    .Select(pl => new {pl, dist = pl.GetDistanceTo(Field.MyGoal.Top)})
                    .OrderBy(tp => tp.dist);

                if (closestUpperPlayers.Count() > 1)
                {
                    target = closestUpperPlayers.Skip(1).First().pl;
                }
                else
                {
                    target = new Vector(Field.Borders.Top.X, Field.MyGoal.Height * 0.7);
                }
            }

            self.ActionGo(target);
        }
예제 #30
0
        /// <summary>
        /// 送球中のボール位置更新
        /// </summary>
        private void MoveThrowBoll()
        {
            // 送球中のボール位置更新
            Vector totalMove = ThrowTargetPoint - ThrowStartPoint;
            Vector bollMove = new Vector(totalMove.X * GameData.DefenseTermPassedSecond / ThrowReachTime,
                                         totalMove.Y * GameData.DefenseTermPassedSecond / ThrowReachTime);
            GameData.BollPoint = ThrowStartPoint + bollMove;

            // 送球完了したか
            if (GameData.DefenseTermPassedSecond >= ThrowReachTime)
            {
                // 送球完了

                // ボール保持メンバの更新
                GameData.BollKeepingPosition = GetBaseCoverPosition(ThrowTargetBase);

                // 送球完了によるフォースアウトとタッチアウトの処理
                UpdateByThrowFinish(ThrowTargetBase);
            }
        }