private double EvaluatorDribble() { double evaluation = 0; // bonus for proximity to enemy goal (0,e-1). Vector2d goalPosition = Constants.Uprights[0]; //upper-left post if (!_owner.Team.AttackingLeft) { goalPosition = Constants.Uprights[2]; //upper-right post } Vector2d goalVector = goalPosition - _owner.PositionDouble; double maxShotDistance = 2000; if (goalVector.Length() < maxShotDistance) { evaluation += (Math.Pow(Math.E, (1 - goalVector.Length() / maxShotDistance)) - 1); } // bonus for player being under little pressure InfluenceMap enemyMap = _owner.EnemyTeam.TeamInfluenceMap; double interdiction = enemyMap.SumInArea(_owner.PositionOnInfMap(), 3); if (interdiction < 3) { evaluation += (3 - interdiction); } // there should be a dominating bonus for players with good dribbling ability return(evaluation); }
/// <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); }
public Team(List <Footballer> teamRoster, InfluenceMap teamInfMap, Match currentGame, bool goingLeft, Color teamColor) { _teamInfluenceMap = teamInfMap; _teamColor = teamColor; _teamRoster = teamRoster; _attackingLeft = goingLeft; _currentGame = currentGame; }
/// <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); }
public void Add(InfluenceMap summant) { if (this.Map.GetLength(0) != summant.Map.GetLength(0) || this.Map.GetLength(1) != summant.Map.GetLength(1)) { throw new Exception("attempted summation of influence maps of different dimensions"); } //InfluenceMap returnVal = new InfluenceMap((UInt16)map1.Map.GetLength(0), (UInt16)map1.Map.GetLength(1)); for (int i = 0; i < this.Map.GetLength(0); ++i) { for (int j = 0; j < this.Map.GetLength(1); ++j) { this.Map[i, j] += summant.Map[i, j]; } } }
private double EvaluatorShot() { double evaluation = 0; // large bonus for proximity to goal (1,e). Vector2d goalPosition = Constants.Uprights[0]; //upper-left post if (!_owner.Team.AttackingLeft) { goalPosition = Constants.Uprights[2]; //upper-right post } Vector2d goalVector = goalPosition - _owner.PositionDouble; double maxShotDistance = 2000; if (goalVector.Length() < maxShotDistance) { evaluation += Math.Pow(Math.E, (1 - goalVector.Length() / maxShotDistance)); } // large bonus for clear line of shot // add large bonus if lane of passing is empty (0,3). List <Coords> lane = _owner.InhabitedMap.RayTracer(_owner.PositionOnInfMap(), StaticMathFunctions.PositionOnFieldToInfMapCoords(goalPosition)); 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.7) { evaluation += toAdd; } } if (interdiction < 3) { evaluation += (3 - interdiction); } // there should be a bonus for easy shots // there should be a monster bonus for when the GK is out of position return(evaluation); }
/// <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); }
private void DrawInfluenceMap(Graphics g, InfluenceMap map, Coords topLeft, Color teamColor, bool left) { float[,] actualMap = map.Map; sbyte teamVal = left ? (sbyte)0 : (sbyte)1; PointF anchor = new PointF(teamVal * 0.6f * _mainFrame.Width + topLeft.X * this._zoom, topLeft.Y * this._zoom + 0.6f * _mainFrame.Height); PointF boxSize = new PointF(0.4f * _mainFrame.Width / actualMap.GetLength(0), 0.4f * _mainFrame.Height / actualMap.GetLength(1)); for (int i = 0; i < actualMap.GetLength(0); ++i) { for (int j = 0; j < actualMap.GetLength(1); ++j) { Color TransparentColor = Color.FromArgb((Int32)(actualMap[i, j] * 50), teamColor.R, teamColor.G, teamColor.B); Brush myBrush = new SolidBrush(TransparentColor); g.FillRectangle(myBrush, anchor.X + i * boxSize.X, anchor.Y + j * boxSize.Y, boxSize.X, boxSize.Y); } } }