Example #1
0
 protected Vector2 GetWhiteBallDesiredPosition(Ball targetBall, Vector2 pocketCenter)
 {
     Vector2 pocketToBallDirection = targetBall.Center - pocketCenter;
     pocketToBallDirection.Normalize();
     Vector2 whiteCenterTarget = targetBall.Center + 2 * Ball.Radius * pocketToBallDirection;
     return whiteCenterTarget;
 }
 private Vector2 GetClosestBallWithoutCollisions(Ball whiteBall)
 {
     Vector2 result = new Vector2(-1, -1);
     float minDistance = float.MaxValue;
     for (int i = 1; i < pool.Balls.Count; i++)
     {
         Ball ball = pool.Balls[i];
         if (ball.Inserted || !IsPlayersBall(ball))
         {
             continue;
         }
         float distanceToWhite = Vector2.Distance(whiteBall.Center, ball.Center);
         Vector2 pocket = GetClosestPocketCenter(ball);
         if (pocket.X == -1 && pocket.Y == -1) // the default false value
         {
             continue;
         }
         Vector2 imaginaryTargetCenter = GetWhiteBallDesiredPosition(ball, pocket);
         Ball imaginaryBall = new Ball(imaginaryTargetCenter, 100, false);
         if (minDistance > distanceToWhite && !HasCollision(whiteBall, imaginaryBall))
         {
             minDistance = distanceToWhite;
             result = imaginaryBall.Center;
         }
     }
     return result;
 }
Example #3
0
        public static bool DoesBallCollideWithOtherBall(Ball ball, Ball otherBall, out double collisionTime, 
                                                        Vector2 ballDir, Vector2 otherBallDir, float ballSpeed, float otherBallSpeed)
        {
            collisionTime = double.MaxValue;
            double dx = ball.Center.X - otherBall.Center.X;
            double dy = ball.Center.Y - otherBall.Center.Y;
            double dvx = ballDir.X * ballSpeed - otherBallDir.X * otherBallSpeed;
            double dvy = ballDir.Y * ballSpeed - otherBallDir.Y * otherBallSpeed;
            double r1 = Ball.Radius;
            double r2 = Ball.Radius;

            double d = (dx * dvx + dy * dvy) * (dx * dvx + dy * dvy) - (dvx * dvx + dvy * dvy) * (dx * dx + dy * dy - (r1 + r2) * (r1 + r2));

            if (d > 0.00005)
            {
                double t1 = -(dx * dvx + dy * dvy - Math.Sqrt(d)) / (dvx * dvx + dvy * dvy);
                double t2 = -(dx * dvx + dy * dvy + Math.Sqrt(d)) / (dvx * dvx + dvy * dvy);

                if (t1 > 0 || t2 > 0)
                {
                    if (t1 < collisionTime)
                    {
                        collisionTime = t1;
                    }
                    if (t2 < collisionTime)
                    {
                        collisionTime = t2;
                    }
                    return true;
                }
            }
            return false;
        }
Example #4
0
 protected Ball ChooseClosestBallFromRange(Ball whiteBall, int rangeStart, int rangeEnd)
 {
     if (player.ShouldPotBlack(pool.Balls))
     {
         return pool.Balls[8]; // this is the black ball
     }
     Ball result = null;
     float minDistance = float.MaxValue;
     for (int i = rangeStart; i < rangeEnd; i++)
     {
         if (i == 8)
         {
             continue;
         }
         if (pool.Balls[i].Inserted)
         {
             continue;
         }
         float distanceToWhite = Vector2.Distance(whiteBall.Center, pool.Balls[i].Center);
         if (minDistance > distanceToWhite)
         {
             result = pool.Balls[i];
             minDistance = distanceToWhite;
         }
     }
     return result;
 }
        private bool HasCollisionWithBall(Ball whiteBall, Ball targetBall, Ball possibleObstruction)
        {
            double time;
            Vector2 whiteBallDirection = targetBall.Center - whiteBall.Center;
            whiteBallDirection.Normalize();

            bool result = Physics.DoesBallCollideWithOtherBall(whiteBall, possibleObstruction, out time,
                                whiteBallDirection, Vector2.Zero, 500, 0);
            return result;
        }
Example #6
0
 protected bool IsPlayersBall(Ball ball)
 {
     if (player.ShouldPotBlack(pool.Balls))
     {
         return ball.Number == 8;
     }
     if (player.BallTypeChosen == BallType.None)
     {
         return ball.Number != 8 && ball.Number != 0;
     }
     if (player.BallTypeChosen == BallType.Solids)
     {
         return ball.Number < 8 && ball.Number > 0;
     }
     return ball.Number > 8;
 }
Example #7
0
        protected Vector2 GetClosestPocketCenter(Ball ball)
        {
            Vector2 result = new Vector2(-1,-1);
            float minDistance = Vector2.Distance(ball.Center, result);
            foreach (Vector2 pocket in pool.PocketCentres)
            {
                float currentDistance = Vector2.Distance(ball.Center, pocket);
                float distanceToWhite = Vector2.Distance(pool.Balls[0].Center, pocket);

                if (currentDistance < minDistance && distanceToWhite > currentDistance &&
                    GetCosAngle(pool.Balls[0].Center, ball.Center, pocket) < -0.4)
                {
                    result = pocket;
                    minDistance = currentDistance;
                }
            }
            return result;
        }
 private bool HasCollision(Ball whiteBall, Ball target)
 {
     double distanceToTarget = Vector2.DistanceSquared(whiteBall.Center, target.Center);
     for (int i = 1; i < pool.Balls.Count; i++)
     {
         Ball loopBall = pool.Balls[i];
         if (loopBall.Inserted || loopBall.Number == target.Number)
         {
             continue;
         }
         double distanceToLoopBall = Vector2.DistanceSquared(loopBall.Center, whiteBall.Center);
         if (HasCollisionWithBall(whiteBall, target, loopBall) && distanceToLoopBall < distanceToTarget)
         {
             return true;
         }
     }
     return false;
 }
Example #9
0
 private void DrawBall(Ball theBall, Color ballColor)
 {
     spriteBatch.Begin();
     Vector2 ballCenter = new Vector2(theBall.Center.X - Ball.Radius, theBall.Center.Y - Ball.Radius);
     spriteBatch.Draw(ball, ballCenter, ballColor);
     // drawing numbers for debug purposes.
     //spriteBatch.DrawString(tahoma, theBall.Number.ToString(), ballCenter, Color.Green);
     spriteBatch.End();
 }
Example #10
0
        float IntersectWithWalls(Ball ball, out Side side)
        {
            side = null;
            float minu = -1;
            for (int i = 0; i < Sides.Count; i++)
            {
                float x1 = ball.Center.X;
                float y1 = ball.Center.Y;
                float x2 = ball.Center.X + ball.Dir.X;
                float y2 = ball.Center.Y + ball.Dir.Y;
                float x3 = Sides[i].p1.X;
                float y3 = Sides[i].p1.Y;
                float x4 = Sides[i].p2.X;
                float y4 = Sides[i].p2.Y;

                if ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4) == 0)
                {
                    continue;
                }

                float px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) /
                            ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
                float py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) /
                            ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));

                float u = (px - ball.Center.X) / (ball.Dir.X);
                if (Math.Abs(ball.Dir.X) < Math.Abs(ball.Dir.Y) || (Math.Abs(u) < 0.0005 && u < 0 && ball.Dir.Y != 0))
                {
                    u = (py - ball.Center.Y) / (ball.Dir.Y);
                }

                float t = (px - x3) / (x4 - x3);
                if (x4 == x3)
                {
                    t = (py - y3) / (y4 - y3);
                }
                if (u < -0.00001 || t < 0 || t > 1.000005)
                {
                    continue;
                }

                if (Math.Abs(u) < 0.00001)
                {
                    u = 0;
                    Vector2 sidev = new Vector2(x4 - x3, y4 - y3);
                    Vector2 next = sidev + ball.Dir;
                    if (Utilities.Cross(sidev, next) < 0)
                    {
                        continue;
                    }
                }

                if (minu == -1 || u < minu)
                {
                    side = Sides[i];
                    minu = u;
                }
            }

            return Math.Max((ball.Dir.Length() * minu) / ball.Speed, 0);
        }
Example #11
0
        float IntersectWithBalls(Ball ball, out Ball firstColidingBall)
        {
            firstColidingBall = null;
            double firstBallCollisionTime = 1e50;

            for (int i = 0; i < Balls.Count; i++)
            {
                if (ball.Number == Balls[i].Number || Balls[i].Inserted)
                {
                    continue;
                }
                double currentBallCollisionTime;
                if (Physics.DoesBallCollideWithOtherBall(ball, Balls[i], out currentBallCollisionTime))
                {
                    if (currentBallCollisionTime < firstBallCollisionTime)
                    {
                        firstBallCollisionTime = currentBallCollisionTime;
                        firstColidingBall = Balls[i];
                    }
                }
            }
            return (float)Math.Max(firstBallCollisionTime, 0.001);
        }
Example #12
0
 void InsertedBall(Ball ball)
 {
     ballPotted = true;
     if (Player1.IsOnTurn)
     {
         HandleBallPotted(ball, Player1, Player2);
     }
     else
     {
         HandleBallPotted(ball, Player2, Player1);
     }
 }
Example #13
0
        private void HandleBallPotted(Ball ball, Player playerOnTurn, Player otherPlayer)
        {
            if (ball.Number == 0) // the white ball has been potted
            {
                shouldSwitchPlayers = true;
                Fault = true;
                return;
            }

            if (ball.Number == 8) // the black ball has been potted
            {
                if (playerOnTurn.ShouldPotBlack(Balls))
                {
                    playerOnTurn.Won = true;
                    otherPlayer.Won = false;
                }
                else
                {
                    playerOnTurn.Won = false;
                    otherPlayer.Won = true;
                }
            }

            if (playerOnTurn.BallTypeChosen == BallType.None) // noone has potted a ball yet
            {
                if (ball.Number > 8)  // a striped ball has been potted
                {
                    playerOnTurn.BallTypeChosen = BallType.Stripes;
                    otherPlayer.BallTypeChosen = BallType.Solids;
                }
                else // a solid ball has been potted
                {
                    playerOnTurn.BallTypeChosen = BallType.Solids;
                    otherPlayer.BallTypeChosen = BallType.Stripes;
                }
            }
            else if (playerOnTurn.BallTypeChosen == BallType.Solids) // the player should pot solids
            {
                if (ball.Number > 8) // the player potted stripe ball
                {
                    shouldSwitchPlayers = true;
                    Fault = true;
                }
            }
            else // the player should pot stripes
            {
                if (ball.Number < 8) // the player potted solid
                {
                    shouldSwitchPlayers = true;
                    Fault = true;
                }
            }
        }
Example #14
0
 public static bool DoesBallCollideWithOtherBall(Ball ball, Ball otherBall, out double collisionTime)
 {
     return DoesBallCollideWithOtherBall(ball, otherBall, out collisionTime, ball.Dir, otherBall.Dir, ball.Speed, otherBall.Speed);
 }
Example #15
0
 protected void PlaceWhiteBall(Ball whiteBall)
 {
     // Hardcoded position for the white ball;
     whiteBall.Center = new Vector2(200, 200);
     whiteBall.Inserted = false;
 }