/*
         * private RectangleF GetRectangle(Coords positionTile)
         * {
         *  return new RectangleF(positionTile.X * Constants.TileBitmapSize * this._zoom, positionTile.Y * Constants.TileBitmapSize * this._zoom,
         *      (Constants.TileBitmapSize) * this._zoom, (Constants.TileBitmapSize) * this._zoom);
         * }
         */
        #region Tile drawers

        // Draw tile bitmap
        private void TileDrawBitmap(Graphics g, Coords position, Bitmap image)
        {
            Point anchor = new Point((Int32)(position.X * _zoom), (Int32)(position.Y * _zoom));

            g.DrawImageUnscaled(image, anchor);
        }
 private void DrawEllipseAtPixel(Graphics g, Coords pixel, UInt16 radiusX, UInt16 radiusY)
 {
     g.DrawEllipse(new Pen(Constants.BoundingCircleColor), (pixel.X - radiusX) * this._zoom, (pixel.Y - radiusY) * this._zoom,
                   radiusX * 2 * this._zoom, radiusY * 2 * this._zoom);
 }
 public float GetMapValue(Coords number)
 {
     // Perhaps should throw exception
     return(this._map[number.X, number.Y]);
 }
 public void ClippingBoxesRemoveFrom(Coords box, Footballer removeMe)
 {
     _clippingBoxes[box.X, box.Y].Remove(removeMe);
 }
Beispiel #5
0
 public float DistanceTo(Coords c)
 {
     return((float)Math.Sqrt(Math.Pow((this.X - c.X), 2) + Math.Pow((this.Y - c.Y), 2)));
 }
        /// <summary>
        /// Generates the influence map.
        /// Uses a silly recursive algorithm.
        /// Stopping conditions: Let's use two, to avoid stupid infinite loops.
        /// One is a distance threshold check.
        /// Second is a min influence threshold check.
        /// </summary>
        public float[,] GenerateInfluenceMap(UInt16 sizex, UInt16 sizey, Coords source, InfluenceSpreadFunction f)
        {
            float[,] influenceMap = new float[sizex, sizey];

            // boolean array to keep note of which tiles have been processed
            BitArray[] takenCareOf = new BitArray[sizex];
            for (int i = 0; i < sizex; ++i)
            {
                takenCareOf[i] = new BitArray(sizey);
            }
            takenCareOf[source.X][source.Y] = true;

            // sets up two queues - one for the current pass, one for the next one
            // distance increments by one at each pass
            // if too slow, the process should be broken up so it does a number of passes each tick
            Queue <Coords> currentQueue = new Queue <Coords>();
            Queue <Coords> nextQueue    = new Queue <Coords>();

            currentQueue.Enqueue(source);

            UInt32 currentDistance = 0;

            // main loop
            // Stopping conditions: the two queues are exhausted, OR InfluenceMapMaxDistance is reached
            while
            (
                ((currentQueue.Count > 0) & (nextQueue.Count > 0))
                |
                (currentDistance < Constants.InfluenceMapMaxDistance)
            )
            {
                // Checks if it's time to start the next pass
                if (currentQueue.Count == 0)
                {
                    currentQueue = nextQueue;
                    nextQueue    = new Queue <Coords>();
                    currentDistance++;
                    continue;
                }

                Coords currentCoords = currentQueue.Peek();

                // Analyzes the neighbors of the current Tile for possible additions to nextQueue
                for (byte i = 0; i < 8; i++)
                {
                    Direction currentDir = (Direction)i;
                    Coords    toCheck    = StaticMathFunctions.CoordsNeighboringInDirection(currentCoords, currentDir);
                    if (toCheck.X >= 0 && toCheck.X < sizex && toCheck.Y >= 0 && toCheck.Y < sizey)
                    {
                        if (!takenCareOf[toCheck.X][toCheck.Y])
                        {
                            nextQueue.Enqueue(toCheck);
                            takenCareOf[toCheck.X][toCheck.Y] = true;
                        }
                    }
                }

                float newVal = f(currentDistance);

                // Check to avert infnite / excessively deep loop
                if (newVal > Constants.InfluenceMapMinThreshold)
                {
                    influenceMap[currentCoords.X, currentCoords.Y] = newVal;
                }

                currentQueue.Dequeue();
            }

            return(influenceMap);
        }
 private Coords VertexBottomLeft(Coords box)
 {
     return(new Coords(_pixelsPerBoxX * box.X, _pixelsPerBoxY * (box.Y + 1) - 1));
 }
Beispiel #8
0
 public Coords(Coords c)
 {
     _X = c.X;
     _Y = c.Y;
 }
        // returns true if the two circles collide
        private bool CollisionCheckEllipses(Coords center1, UInt16 radius1X, UInt16 radius1Y, Coords center2, UInt16 radius2X, UInt16 radius2Y)
        {
            UInt16 radiusSumX = (UInt16)(radius1X + radius2X);
            UInt16 radiusSumY = (UInt16)(radius1Y + radius2Y);

            // IS this even correct? It is for circles. Should be for ellipses.
            return(CollisionCheckPixelInEllipse(center1, center2, radiusSumX, radiusSumY));
        }
 private Coords VertexTopRight(Coords box)
 {
     return(new Coords(_pixelsPerBoxX * (box.X + 1) - 1, _pixelsPerBoxY * box.Y));
 }
 private Coords VertexTopLeft(Coords box)
 {
     return(new Coords(_pixelsPerBoxX * box.X, _pixelsPerBoxY * box.Y));
 }
        /*
         * /// <summary>
         * /// Returns all footballers clipped by the agent; empty if none.
         * /// </summary>
         * public List<Footballer> CreatureClippingCheck(Footballer critter, Coords potentialPosition, bool creaturesClipCheck)
         * {
         *  // obtain new entry tiles
         *  LinkedList<Coords> newEntries = this.TilesCoveredByEllipse(potentialPosition, critter.RadiusX, critter.RadiusY);
         *
         *  // if the flags demands it, check if there is a creature in the way
         *  if (creaturesClipCheck)
         *  {
         *      if (this.PotentialCreatureToCreatureCollision(critter, potentialPosition))
         *      {
         *          return CollisionType.Footballer;
         *      }
         *  }
         *
         *  return CollisionType.None;
         * }
         */

        public LinkedList <Coords> TilesCoveredByEllipse(Coords center, UInt16 radiusX, UInt16 radiusY)
        {
            if (PotentialOutOfBoundsEllipse(center, radiusX, radiusY))
            {
                return(null);
            }

            LinkedList <Coords> returnValue = new LinkedList <Coords>();

            Coords current = new Coords((Int32)(center.X / _pixelsPerBoxX), (Int32)(center.Y / _pixelsPerBoxY));

            // add tile on which center-pixel lies (if it's passable)
            returnValue.AddLast(current);

            #region overlap to the right check
            if ((center.X + radiusX) / _pixelsPerBoxX > current.X) // overlap to the right
            {
                Coords tileRight = new Coords(current.X + 1, current.Y);

                returnValue.AddLast(tileRight);

                if ((center.Y + radiusY) / _pixelsPerBoxY > current.Y) // overlap also to the bottom
                {
                    Coords tileBottom = new Coords(current.X, current.Y + 1);

                    returnValue.AddLast(tileBottom);

                    Coords tileBottomRight = new Coords(current.X + 1, current.Y + 1);                          // bottom-right inspection
                    if (CollisionCheckPixelInEllipse(VertexTopLeft(tileBottomRight), center, radiusX, radiusY)) // we're inside!
                    {
                        returnValue.AddLast(tileBottomRight);
                    }
                }
                else if ((center.Y - radiusY) / _pixelsPerBoxY < current.Y) // overlap also to the top
                {
                    Coords tileTop = new Coords(current.X, current.Y - 1);

                    returnValue.AddLast(tileTop);

                    Coords tileTopRight = new Coords(current.X + 1, current.Y - 1);                             // top-right inspection
                    if (CollisionCheckPixelInEllipse(VertexBottomLeft(tileTopRight), center, radiusX, radiusY)) // we're inside!
                    {
                        returnValue.AddLast(tileTopRight);
                    }
                }
            }
            #endregion
            #region overlap to the left check
            else if ((center.X - radiusX) / _pixelsPerBoxX < current.X) // overlap to the left
            {
                Coords tileLeft = new Coords(current.X - 1, current.Y);

                returnValue.AddLast(tileLeft);

                if ((center.Y + radiusY) / _pixelsPerBoxY > current.Y) // overlap also to the bottom
                {
                    Coords tileBottom = new Coords(current.X, current.Y + 1);

                    returnValue.AddLast(tileBottom);

                    Coords tileBottomLeft = new Coords(current.X - 1, current.Y + 1);                           // bottom-left inspection
                    if (CollisionCheckPixelInEllipse(VertexTopRight(tileBottomLeft), center, radiusX, radiusY)) // we're inside!
                    {
                        returnValue.AddLast(tileBottomLeft);
                    }
                }
                else if ((center.Y - radiusY) / _pixelsPerBoxY < current.Y) // overlap also to the top
                {
                    Coords tileTop = new Coords(current.X, current.Y - 1);

                    returnValue.AddLast(tileTop);

                    Coords tileTopLeft = new Coords(current.X - 1, current.Y - 1);                              // top-left inspection
                    if (CollisionCheckPixelInEllipse(VertexBottonRight(tileTopLeft), center, radiusX, radiusY)) // we're inside!
                    {
                        returnValue.AddLast(tileTopLeft);
                    }
                }
            }
            #endregion
            #region in between
            else // still have to check Y
            {
                if ((center.Y + radiusY) / _pixelsPerBoxY > current.Y) // overlap also to the bottom
                {
                    Coords tileBottom = new Coords(current.X, current.Y + 1);

                    returnValue.AddLast(tileBottom);
                }
                else if ((center.Y - radiusY) / _pixelsPerBoxY < current.Y) // overlap also to the top
                {
                    Coords tileTop = new Coords(current.X, current.Y - 1);

                    returnValue.AddLast(tileTop);
                }
            }
            #endregion

            // clean-up

            foreach (Coords c in returnValue)
            {
                if (!CheckInBounds(c))
                {
                    returnValue.Remove(c);
                }
            }


            return(returnValue);
        }
        /// <summary>
        ///  Returns footballers overlapped by agent.
        /// </summary>
        public List <Footballer> PotentialFootballerToFootballerCollision(Footballer critter, Coords potentialPosition)
        {
            List <Footballer> returnVal = new List <Footballer>();

            UInt16 critterRadiusX = critter.RadiusX;
            UInt16 critterRadiusY = critter.RadiusY;

            LinkedList <Coords> checkList = this.TilesCoveredByEllipse(potentialPosition, critterRadiusX, critterRadiusY);

            foreach (Coords checkme in checkList)
            {
                foreach (Footballer obstacle in _clippingBoxes[checkme.X, checkme.Y])
                {
                    // ignore self
                    if (obstacle == critter)
                    {
                        continue;
                    }

                    if (CollisionCheckEllipses(potentialPosition, critterRadiusX, critterRadiusY,
                                               new Coords(obstacle.PositionDouble), obstacle.RadiusX, obstacle.RadiusY))
                    {
                        returnVal.Add(obstacle);
                    }
                }
            }

            return(returnVal);
        }
Beispiel #14
0
        /*
         * public static Direction OppositeDirection(Direction d)
         * {
         *  return (Direction)(((byte)d + 4) % 8);
         * }
         */
        /*
         * public static Direction DirectionToTheRight(Direction d)
         * {
         *  return (Direction)(((byte)d + 1) % 8);
         * }
         */

        /*
         * public static Direction DirectionToTheLeft(Direction d)
         * {
         *  return (Direction)(((byte)d + 7) % 8);
         * }
         */

        /*
         * public static Coords CoordsAverage(Coords c1, Coords c2)
         * {
         *  return new Coords((Int32)0.5 * (c1.X + c2.X), (Int32)0.5 * (c1.Y + c2.Y));
         * }
         */

        /*
         * public static bool CoordinateIsInBox(Coords c, Coords boxTopLeft, Coords boxBottomRight)
         * {
         *  return (((c.X >= boxTopLeft.X) && (c.X <= boxBottomRight.X)) && ((c.Y >= boxTopLeft.Y) && (c.Y <= boxBottomRight.Y)));
         * }
         */


        /// <summary>
        /// Returns the eucledean distance between two Coords
        /// </summary>
        public static float DistanceBetweenTwoCoordsEucledean(Coords c1, Coords c2)
        {
            return((float)Math.Sqrt(Math.Pow((c1.X - c2.X), 2) + Math.Pow((c1.Y - c2.Y), 2)));
        }
 private Coords VertexBottonRight(Coords box)
 {
     return(new Coords(_pixelsPerBoxX * (box.X + 1) - 1, _pixelsPerBoxY * (box.Y + 1) - 1));
 }
Beispiel #16
0
 /// <summary>
 /// returns the distance between two Coords
 /// </summary>
 public static float DistanceBetweenTwoCoordss(Coords c1, Coords c2)
 {
     return(Math.Max(Math.Abs(c1.X - c2.X), Math.Abs(c1.Y - c2.Y)));
 }
Beispiel #17
0
 private Tile(Map home, Coords position)
 {
     this.InhabitedMap = home;
     this.Position     = position;
 }
Beispiel #18
0
 public Vector2d(Coords c)
 {
     _X = c.X;
     _Y = c.Y;
 }
Beispiel #19
0
 public Tile(Map home, Coords position, SpriteTile tileBitmap)
     : this(home, position)
 {
     this._myBitmap = tileBitmap;
 }
 public InfluenceSourceMap(UInt16 sizex, UInt16 sizey, Coords source, UInt16 distance) : base(sizex, sizey)
 {
     _source            = source;
     _effectiveDistance = distance;
 }
        /// <summary>
        /// Coords the painting of the portion of the map between the two Coords parameters.
        /// </summary>
        public void Paint(Graphics g, Coords topLeft, Coords bottomRight)
        {
            // The algorithm is as follows:
            // 1) AT INIT: Imports and resizes the bitmaps.
            // 2) AT ZOOM: Resizes bitmaps.
            // 3) AT PAINT: The Form determines what portion of the map should be painted and calls Painter.
            // Painter goes through the Tiles and draws them, row by row, from left-to-right from
            // top-to-bottom.

            #region Tiles

            Int32 pixelsX = 0;
            // We assume the validity check for the two coords has been done in the caller class.
            for (Int32 i = 0; i < Constants.MapSizeX; ++i)
            {
                if (i > 0)
                {
                    pixelsX += Constants.TileSizesX[i - 1];
                }


                Int32 pixelsY = 0;
                for (Int32 j = 0; j < Constants.MapSizeY; ++j)
                {
                    Coords currentCoords = new Coords(i, j);
                    Tile   currentTile   = this._currentMap.GetTile(i, j);

                    if (j > 0)
                    {
                        pixelsY += Constants.TileSizesY[j - 1];
                    }

                    this.TileDrawBitmap(g, new Coords(pixelsX, pixelsY), this.Tiles[(sbyte)currentTile.MyBitmap]);


                    foreach (Footballer critter in _currentMap.Roster.Values)
                    {
                        this.AddForPaintingFootballer(critter);
                    }
                }
            }

            #endregion

            #region Props and Footballers

            // The tiles have informed the painter about the Footballers he's supposed to draw.
            foreach (Footballer critter in this._FootballersToDraw)
            {
                this.FillPlayerEllipse(g, critter.PositionDouble, 10, 8, critter.Team.TeamColor);

                this.DrawBitmapAtPixel(g, new Coords((Int32)critter.PositionDouble.X, (Int32)critter.PositionDouble.Y),
                                       this.Footballers[(sbyte)critter.MyBitmap]);

                Vector2d delta = critter.FacingDirection;
                delta.ScaleToLength(50);
                this.DrawLine(g, critter.PositionDouble, critter.PositionDouble + delta);
            }

            // Draw the labels
            foreach (Footballer critter in this._FootballersToDraw)
            {
                //FIX
                // draw labels
                if ((critter.LabelUpper != null) && (critter.LabelUpper.Length > 0))
                {
                    this.DrawLabel(g, critter.PositionDouble + new Vector2d(0, -200), critter.LabelUpper);
                }

                if ((critter.LabelLower != null) && (critter.LabelLower.Length > 0))
                {
                    //this.DrawLabel(g, new Coords(CoordsType.Pixel, critter.PositionPixel.X, critter.PositionPixel.Y + critter.RadiusY), critter.LabelLower);
                }
            }

            for (int i = 0; i < Props.Length; ++i)
            {
                DrawProp(g, Constants.PropLocations[i], Props[i]);
            }

            #endregion

            #region Nets, Ball, and Info

            // DrawGhostBall if option is enabled
            if (this._ghost != null)
            {
                //BallGhost ghost = new BallGhost(this._currentMap.BallReference);
                for (int i = 0; i < Constants.GhostBallTimeLength; ++i)
                {
                    for (int j = 0; j < Constants.GhostBallDrawInterval; ++j)
                    {
                        _ghost.UpdateMotion3D();
                    }
                    this.DrawGhostBall(g, _ghost);
                }
            }

            if (Constants.ShowTrajectory)
            {
                if (this._currentMap.BallReference.Projection.Count > 0)
                {
                    foreach (Vector3d v in this._currentMap.BallReference.Projection)
                    {
                        BallGhost ghost = new BallGhost(this._currentMap.BallReference);
                        //ghost.SpawnAt(v.ProjectionXY());
                        ghost.Stop();
                        ghost.Position3d = v;
                        this.DrawGhostBall(g, ghost);
                    }
                }
            }

            BallPosition ballPos = DetermineBallPosition(_currentMap.BallReference);

            // Nets
            if (ballPos == BallPosition.BehindGoal)
            {
                this.DrawSomeBall(g, _currentMap.BallReference, this.Balls[(sbyte)SpriteBall.Standard]);
            }
            DrawNetYAxis(g, Constants.NetsBackLeft);
            DrawNetYAxis(g, Constants.NetsBackRight);
            DrawNetXAxis(g, Constants.NetsBackLeft, Constants.GoalTop);
            DrawNetXAxis(g, Constants.GoalRight, Constants.GoalTop);
            if (ballPos == BallPosition.InsideGoal)
            {
                this.DrawSomeBall(g, _currentMap.BallReference, this.Balls[(sbyte)SpriteBall.Standard]);
            }
            DrawNetXAxis(g, Constants.NetsBackLeft, Constants.GoalBottom);
            DrawNetXAxis(g, Constants.GoalRight, Constants.GoalBottom);
            DrawNetZAxis(g, Constants.NetsBackLeft);
            DrawNetZAxis(g, Constants.GoalRight);
            DrawGoals(g);
            if (ballPos == BallPosition.Visible)
            {
                this.DrawSomeBall(g, _currentMap.BallReference, this.Balls[(sbyte)SpriteBall.Standard]);
            }


            DrawBallParameters(g, topLeft);
            DrawShotParameters(g, topLeft);

            this.DrawInfluenceMap(g, _currentMap.MatchOnMap.TeamLeft.TeamInfluenceMap, topLeft, _currentMap.MatchOnMap.TeamLeft.TeamColor, true);
            this.DrawInfluenceMap(g, _currentMap.MatchOnMap.TeamRight.TeamInfluenceMap, topLeft, _currentMap.MatchOnMap.TeamRight.TeamColor, false);

            #endregion

            // Clean up the ID list.
            this._FootballersToDraw.Clear();
        }
        /// <summary>
        /// The passed 'updater' is generic. It was added to the 'map' at oldsource. We want to substract it, and add it at
        /// newSource.
        /// </summary>
        public void UpdateMapViaSourceMap(InfluenceMap map, InfluenceSourceMap updater, Coords oldSource, Coords newSource)
        {
            if (oldSource == newSource)
            {
                return;
            }

            InfluenceSourceMap oldInfMap = ShiftInfluenceSourceMap(updater, oldSource);
            InfluenceSourceMap newInfMap = ShiftInfluenceSourceMap(updater, newSource);

            map.Substract(oldInfMap);
            map.Add(newInfMap);
        }
        private void DrawProp(Graphics g, Coords topLeft, Bitmap image)
        {
            Point anchor = new Point((Int32)(topLeft.X * _zoom), (Int32)(topLeft.Y * _zoom));

            g.DrawImageUnscaled(image, new Point(anchor.X, anchor.Y));
        }
 // Self-explanatory
 public void SetMapValue(Coords number, float newValue)
 {
     // Perhaps should throw exception
     this._map[number.X, number.Y] = newValue;
 }
 public void ClippingBoxesAddTo(Coords box, Footballer newGuy)
 {
     _clippingBoxes[box.X, box.Y].Add(newGuy);
 }