コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <summary>
        /// The scheduler updates its map's actors for the current tick.
        /// </summary>
        public void Update()
        {
            _gameMap.MatchOnMap.Update();

            foreach (KeyValuePair <UInt32, Footballer> kvp in _gameMap.Roster)
            {
                Footballer someGuy = kvp.Value;

                Brain currentBrain = someGuy.FootballerBrain;
                if (currentBrain != null)
                {
                    currentBrain.Update();
                }

                // update inf map if necessary.
                // should ignore the GKs...
                if (_timeCounter % Constants.InfMapUpdatePeriod == someGuy.UniqueID)
                {
                    Coords newInfMapPosition = new Coords((Int32)(someGuy.PositionDouble.X / Constants.InfMapDefaultBoxSizeX),
                                                          (Int32)(someGuy.PositionDouble.Y / Constants.InfMapDefaultBoxSizeY));
                    _gameMap.InfMapGenerator.UpdateMapViaSourceMap(someGuy.Team.TeamInfluenceMap,
                                                                   _gameMap.DefaultInfSourceMap, someGuy.PositionAtLastInfMapUpdate, newInfMapPosition);
                    someGuy.PositionAtLastInfMapUpdate = newInfMapPosition;
                }

                this._timeCounter++;
            }
            _gameMap.BallReference.UpdateMotion3D();
        }
コード例 #3
0
        private DoubleFootballerPair GetBestLobPass()
        {
            List <Footballer> roster = _owner.Team.TeamRoster;

            Footballer best    = null;
            double     bestVal = 0;

            for (int i = 0; i < roster.Count; ++i)
            {
                Footballer current = roster[i];
                if (current == _owner)
                {
                    continue;
                }

                double currentVal = EvaluatorPassLob(current);

                if (currentVal > bestVal)
                {
                    bestVal = currentVal;
                    best    = current;
                }
            }

            return(new DoubleFootballerPair(bestVal, best));
        }
コード例 #4
0
        /// <summary>
        /// Returns a double that measures the usefulness of a lob pass to passTarget
        /// </summary>
        private double EvaluatorPassLob(Footballer passTarget)
        {
            double evaluation = 0;

            Vector2d passVector = passTarget.PositionDouble - _owner.PositionDouble;

            // add bonus for long passes (0,1)
            evaluation += passVector.Length() / Constants.ActualXMax;

            // add bonus for going in the direction of enemy goal (0,1)
            Vector2d goalPosition = Constants.Uprights[0]; //upper-left post

            if (!_owner.Team.AttackingLeft)
            {
                goalPosition = Constants.Uprights[2]; //upper-right post
            }
            double angle = passVector.AngleBetween(goalPosition - _owner.PositionDouble);

            angle       = Math.Abs(angle - Math.PI);
            evaluation += (angle / Math.PI);

            // add large bonus if target is alone.
            InfluenceMap enemyMap     = _owner.EnemyTeam.TeamInfluenceMap;
            double       interdiction = enemyMap.SumInArea(passTarget.PositionOnInfMap(), (UInt16)(passVector.Length() / (0.1 * Constants.ActualXMax) + 1));

            if (interdiction < 1)
            {
                evaluation += 3;
            }

            return(evaluation);
        }
コード例 #5
0
        public ActionPassToSpot(Footballer owner, Vector2d target, PassType typeOfPass)
            : base(owner)
        {
            _target     = target;
            _typeOfPass = typeOfPass;

            // begin to turn to target.
            _owner.TurnToFace(target - _owner.PositionDouble);
        }
コード例 #6
0
        public Int32 CompareTo(object obj)
        {
            if (!(obj is Footballer))
            {
                throw new Exception("Bad Footballer comparison.");
            }

            Footballer compared = (Footballer)obj;

            return((Int32)(this._uniqueID - compared._uniqueID));
        }
コード例 #7
0
        public void HandleCollisions(Footballer someGuy, Vector2d oldPosition)
        {
            this.UpdateFootballerBoxes(someGuy, oldPosition);

            List <Footballer> collisions = this.PotentialFootballerToFootballerCollision(someGuy, new Coords(someGuy.PositionDouble));

            for (int i = 0; i < collisions.Count; ++i)
            {
                this.HandleCollisionBetweenTwoPlayers(someGuy, collisions[i]);
            }
        }
コード例 #8
0
        public void RegisterFootballer(Footballer someGuy)
        {
            LinkedList <Coords> steppedOn = TilesCoveredByEllipse(new Coords(someGuy.PositionDouble), someGuy.RadiusX, someGuy.RadiusY);

            foreach (Coords c in steppedOn)
            {
                this.ClippingBoxesAddTo(c, someGuy);
            }

            _occupiedBoxes.Add(someGuy, steppedOn);
        }
コード例 #9
0
        public bool ReadyForOtherTeamToTakeKickOff()
        {
            for (int i = 0; i < _teamRoster.Count; ++i)
            {
                Footballer current = _teamRoster[i];
                if (!current.IsNear(current.DefaultPositionInHalf()))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #10
0
        /*
         * /// <summary>
         * /// Performs a terrain passability check betwee two points by doing pixel validity checks at interval delta.
         * /// </summary>
         * public CollisionType RayTracerPassabilityCheckRough(Footballer client, Vector v1, Vector v2, double delta)
         * {
         *  Vector difference = v2-v1;
         *  Vector deltaV = difference;
         *  deltaV.ScaleToLength(delta);
         *
         *  Vector currentPosition = v1;
         *
         *  for (int i = 0; i < difference.Length() / deltaV.Length(); ++i)
         *  {
         *      Coords pixel = new Coords(currentPosition);
         *      currentPosition += deltaV;
         *  }
         *
         *  return CollisionType.None;
         * }
         *
         * /// <summary>
         * /// Returns the Bresenham line between p0 and p1; Borrowed the code
         * /// from some dude whose name I don't have, who in turn borrowed from Wikipedia.
         * /// </summary>
         * private List<Coords> BresenhamLine(Coords p0, Coords p1)
         * {
         *  List<Coords> returnList = new List<Coords>();
         *
         *  Boolean steep = Math.Abs(p1.Y - p0.Y) > Math.Abs(p1.X - p0.X);
         *
         *  if (steep == true)
         *  {
         *      Coords tmpPoint = new Coords(CoordsType.Tile,p0.X, p0.Y);
         *      p0 = new Coords(CoordsType.Tile,tmpPoint.Y, tmpPoint.X);
         *
         *      tmpPoint = p1;
         *      p1 = new Coords(CoordsType.Tile,tmpPoint.Y, tmpPoint.X);
         *  }
         *
         *  Int32 deltaX = Math.Abs(p1.X - p0.X);
         *  Int32 deltaY = Math.Abs(p1.Y - p0.Y);
         *  Int32 error = 0;
         *  Int32 deltaError = deltaY;
         *  Int32 yStep = 0;
         *  Int32 xStep = 0;
         *  Int32 y = p0.Y;
         *  Int32 x = p0.X;
         *
         *  if (p0.Y < p1.Y)
         *  {
         *      yStep = 1;
         *  }
         *  else
         *  {
         *      yStep = -1;
         *  }
         *
         *  if (p0.X < p1.X)
         *  {
         *      xStep = 1;
         *  }
         *  else
         *  {
         *      xStep = -1;
         *  }
         *
         *  Int32 tmpX = 0;
         *  Int32 tmpY = 0;
         *
         *  while (x != p1.X)
         *  {
         *
         *      x += xStep;
         *      error += deltaError;
         *
         *      //if the error exceeds the X delta then
         *      //move one along on the Y axis
         *      if ((2 * error) > deltaX)
         *      {
         *          y += yStep;
         *          error -= deltaX;
         *      }
         *
         *      //flip the coords if they're steep
         *      if (steep)
         *      {
         *          tmpX = y;
         *          tmpY = x;
         *      }
         *      else
         *      {
         *          tmpX = x;
         *          tmpY = y;
         *      }
         *
         *      //check the point generated is legal
         *      //and if it is add it to the list
         *      if (this.CheckInBounds(new Coords(CoordsType.Tile,tmpX, tmpY)) == true)
         *      {
         *          returnList.Add(new Coords(CoordsType.Tile,tmpX, tmpY));
         *      }
         *      else
         *      {   //a bad point has been found, so return the list thus far
         *          return returnList;
         *      }
         *
         *  }
         *
         *  return returnList;
         * }
         */
        #endregion

        #region Item / Footballer spawners

        /// <summary>
        /// Spawns the player on the 'ground' at 'startPoint'
        /// returns a reference to the Player so one can more easily take care of references.
        /// </summary>
        public Footballer SpawnFootballer(Vector2d startPoint, Vector2d defaultPlayingPosition, Team team)
        {
            Footballer newGuy = new Footballer(this, startPoint, defaultPlayingPosition, this.IssueFootballerID(), team);

            Coords             infMapPosition = new Coords((Int32)(startPoint.X / Constants.InfMapDefaultBoxSizeX), (Int32)(startPoint.Y / Constants.InfMapDefaultBoxSizeY));
            InfluenceSourceMap updater        = _infMapGenerator.ShiftInfluenceSourceMap(_defaultInfSourceMap, infMapPosition);

            newGuy.Team.TeamInfluenceMap.Add(updater);
            //_teamInfluenceMaps[(sbyte)team].Add( updater);
            newGuy.PositionAtLastInfMapUpdate = infMapPosition;

            return(newGuy);
        }
コード例 #11
0
        /// <summary>
        /// Gives the ball a velocity vector and a spin vector.
        /// </summary>
        public virtual void Kick(Vector3d velocity, Vector3d spin, Footballer kicker)
        {
            if (kicker != null)
            {
                _lastTouch = kicker.Team;
            }

            this._velocity = velocity;
            this._spin3d   = spin;
            if (spin.Length() > 0 && (spin.X != 0 || spin.Y != 0) && (velocity.X != 0 || velocity.Y != 0))
            {
                this.RealignSpin();
            }

            ConstructProjection();
        }
コード例 #12
0
        /// <summary>
        /// Returns a double that measures the usefulness of a ground pass to passTarget
        /// </summary>
        private double EvaluatorPassGround(Footballer passTarget)
        {
            double evaluation = 0;

            Vector2d passVector = passTarget.PositionDouble - _owner.PositionDouble;

            // add bonus for short passes (1,e)
            evaluation += Math.Pow(Math.E, (1 - passVector.Length() / Constants.ActualXMax));

            // add bonus for going in the direction of enemy goal (0,1)
            Vector2d goalPosition = Constants.Uprights[0]; //upper-left post

            if (!_owner.Team.AttackingLeft)
            {
                goalPosition = Constants.Uprights[2]; //upper-right post
            }
            double angle = passVector.AngleBetween(goalPosition - _owner.PositionDouble);

            angle       = Math.Abs(angle - Math.PI);
            evaluation += (angle / Math.PI);

            // add large bonus if lane of passing is empty (0 or 3).
            List <Coords> lane         = _owner.InhabitedMap.RayTracer(_owner.PositionOnInfMap(), passTarget.PositionOnInfMap());
            InfluenceMap  enemyMap     = _owner.EnemyTeam.TeamInfluenceMap;
            double        interdiction = 0;

            for (int i = 0; i < lane.Count; ++i)
            {
                // these should be weighted somehow
                double toAdd = enemyMap.GetMapValue(lane[i]);
                if (toAdd > 0.5)
                {
                    evaluation += toAdd;
                }
            }
            if (interdiction == 0)
            {
                evaluation += 3;
            }

            // there should be a bonus for players making runs

            return(evaluation);
        }
コード例 #13
0
        public Footballer PlayerNearestToBall()
        {
            Footballer nearest   = null;
            double     smallestD = Constants.ActualXMax;

            for (int i = 0; i < _teamRoster.Count; ++i)
            {
                Footballer current  = _teamRoster[i];
                double     currentD = current.DistanceToBall();

                if (currentD < smallestD)
                {
                    nearest   = current;
                    smallestD = currentD;
                }
            }

            return(nearest);
        }
コード例 #14
0
        private void HandleCollisionBetweenTwoPlayers(Footballer first, Footballer second)
        {
            double distance          = first.PositionDouble.DistanceTo(second.PositionDouble);
            double preferredDistance = Math.Sqrt(Math.Pow(first.RadiusX + second.RadiusX, 2) + Math.Pow(first.RadiusY + second.RadiusY, 2));

            double deltaOver2 = 0.5 * (preferredDistance - distance);

            if (deltaOver2 < 0)
            {
                return;
            }

            // push both actors in opposite direction, by a vector of length delta/2.
            Vector2d mover = first.PositionDouble - second.PositionDouble;

            mover.ScaleToLength(deltaOver2);
            first.PositionDouble  += mover;
            second.PositionDouble -= mover;

            // this might have cause other collisions. the algo needs fixing.
        }
コード例 #15
0
        private Footballer LookForPass()
        {
            Footballer target = null;


            // pick random target

            List <Footballer> roster     = _owner.Team.TeamRoster;
            UInt16            choices    = (UInt16)roster.Count;
            RandomStuff       randomator = _owner.InhabitedMap.Randomator;
            UInt32            choice     = randomator.NSidedDice(choices, 1) - 1;

            while (choice == _owner.UniqueID && roster.Count > 1)
            {
                choice = randomator.NSidedDice(choices, 1) - 1;
            }

            target = roster[(Int32)choice];

            return(target);
        }
コード例 #16
0
        public bool ReadyToTakeKickOff()
        {
            for (int i = 0; i < _teamRoster.Count - 2; ++i)
            {
                Footballer current = _teamRoster[i];
                if (!current.IsNear(current.DefaultPositionInHalf()))
                {
                    return(false);
                }
            }

            for (int i = _teamRoster.Count - 2; i < _teamRoster.Count; ++i)
            {
                Footballer current = _teamRoster[i];
                if (!current.IsNear(Constants.CenterPoint))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #17
0
        public Footballer NearestTeammate(Footballer guy)
        {
            Footballer nearest   = null;
            double     smallestD = Constants.ActualXMax;

            for (int i = 0; i < _teamRoster.Count; ++i)
            {
                Footballer current = _teamRoster[i];
                if (current == guy)
                {
                    continue;
                }
                double currentD = current.DistanceToPlayer(guy);

                if (currentD < smallestD)
                {
                    nearest   = current;
                    smallestD = currentD;
                }
            }

            return(nearest);
        }
コード例 #18
0
        public void UpdateFootballerBoxes(Footballer someGuy, Vector2d oldPosition)
        {
            Coords oldCoords = new Coords((Int32)(oldPosition.X / _pixelsPerBoxX), (Int32)(oldPosition.Y / _pixelsPerBoxY));
            Coords newCoords = new Coords((Int32)(someGuy.PositionDouble.X / _pixelsPerBoxX), (Int32)(someGuy.PositionDouble.Y / _pixelsPerBoxY));

            if (oldCoords == newCoords)
            {
                // nothing to do
                return;
            }

            LinkedList <Coords> steppedOn = TilesCoveredByEllipse(new Coords(someGuy.PositionDouble), someGuy.RadiusX, someGuy.RadiusY);

            foreach (Coords c in _occupiedBoxes[someGuy])
            {
                this.ClippingBoxesRemoveFrom(c, someGuy);
            }
            foreach (Coords c in steppedOn)
            {
                this.ClippingBoxesAddTo(c, someGuy);
            }

            _occupiedBoxes[someGuy] = steppedOn;
        }
コード例 #19
0
 public ActionTakeAShot(Footballer owner)
     : base(owner)
 {
     // turn to face goal
     //_owner.TurnToFace(new Vector2d(Constants.GoalLeft, Constants.GoalTop) - _owner.PositionDouble);
 }
コード例 #20
0
 /// <summary>
 /// Add Footballer to the menagerie. They 'key' is the Footballer ID.
 /// </summary>
 public void RosterAddFootballerTo(UInt32 key, Footballer newGuy)
 {
     this._roster[key] = newGuy;
     //this._teamRoster[(sbyte)newGuy.Team][key] = newGuy;
 }
コード例 #21
0
 public Action(Footballer owner)
 {
     _owner = owner;
 }
コード例 #22
0
 public double DistanceToPlayer(Footballer someGuy)
 {
     return((this._positionDouble - someGuy.PositionDouble).Length());
 }
コード例 #23
0
 public void AddForPaintingFootballer(Footballer critter)
 {
     this._FootballersToDraw.Add(critter);
 }
コード例 #24
0
 public DoubleFootballerPair(double val, Footballer guy)
 {
     value  = val;
     player = guy;
 }
コード例 #25
0
 public ActionWait(Footballer owner, UInt16 releaseTime)
     : base(owner)
 {
     _releaseTime = releaseTime;
 }
コード例 #26
0
 public ActionGoto(Footballer owner, Vector2d target) : base(owner)
 {
     _target = target;
     _owner.MoveTo(_target);
 }
コード例 #27
0
 public ActionStumble(Footballer owner)
     : base(owner)
 {
 }
コード例 #28
0
 public ActionChallenge(Footballer owner, Vector2d direction)
     : base(owner)
 {
     _direction = direction;
 }
コード例 #29
0
 public ActionAnticipate(Footballer owner)
     : base(owner)
 {
     _owner.Stop();
 }
コード例 #30
0
 public ActionDribbleTo(Footballer owner, Vector2d target) : base(owner)
 {
     _target = target;
 }