public static Position GetVector(Position source, Position target) { double distance = Calc.GetDistance(source, target); double deltaX = (target.X - source.X) / distance; double deltaY = (target.Y - source.Y) / distance; return new Position(deltaX,deltaY); }
static void EvaluatePool() { Position poolCenter = new Position(0, 0); // checks for collision between frogs - both are dead if (Calc.GetDistance(frogs[0].Pos, frogs[1].Pos) < 2 * Frog.FrogRadius) { algoAlive[0] = false; algoAlive[1] = false; return; } // checks for collision between each frog and pool border - each is dead for (int i = 0; i < frogs.Length; i++) { if (Calc.GetDistance(frogs[i].Pos, poolCenter) + Frog.FrogRadius > Frog.PoolRadus) { algoAlive[i] = false; return; } } // checks for collision with enemy bullet for (int i = 0; i < frogs.Length; i++) { for (int bul = 0; bul < bullets[i].Count; bul++) { for (int j = 0; j < Bullet.BulletSpeed; j++) { if (Calc.GetDistance(bullets[i][bul].Pos, frogs[frogs.Length - i - 1].Pos) < Frog.FrogRadius) { algoAlive[frogs.Length - i - 1] = false; } // adds single target vector to current bullet position bullets[i][bul].Pos = bullets[i][bul].Pos.Add(bullets[i][bul].Target); // checks for out of pool condition if (Calc.GetDistance(bullets[i][bul].Pos, poolCenter) > Frog.PoolRadus) { bullets[i].RemoveAt(bul); break; } } } } // update pool radius Frog.PoolRadus--; }
public Position Add(Position vector) { return new Position(this.X + vector.X, this.Y + vector.Y); }
public static double GetDistance(Position source, Position target) { return Math.Sqrt((source.X - target.X) * (source.X - target.X) + (source.Y - target.Y) * (source.Y - target.Y)); }
public static Position RotateVectorCounterClockwise(Position source) { // (x,y) => (y, -x) return new Position(source.Y, -source.X); }
public static Position RotateVectorClockwise(Position source) { // (x,y) => (-y, x) return new Position(-source.Y, source.X); }
public static bool HasImpact(Position source, double radius, Position target) { return (GetDistance(source, target) <= radius); }
static void SaveMove( string text = "") { text = text.Replace(Environment.NewLine, " "); string[] input = text.Split(' '); // shoot first from current position if it can if (input.Length > 3 && input[3] == "shoot" && frogs[bothAlgosCounter % 2].TimeToReload == 0) { Position target = new Position(double.Parse(input[4]), double.Parse(input[5])); Position vector = Calc.GetVector(frogs[bothAlgosCounter % 2].Pos, target); // puts bullet ar pair of current position and single vector for the next move bullets[bothAlgosCounter % 2].Add( new Bullet(frogs[bothAlgosCounter % 2].Pos.X, frogs[bothAlgosCounter % 2].Pos.Y, vector.X, vector.Y)); // sets reload waiting time frogs[bothAlgosCounter % 2].TimeToReload = 8; } // then moves to new position if (input[0] == "move") { // gets the requested new position and if it is above distance of MaxJumpDistance (2.0) // calculates the vector, scales it and add it to the current position Position next = new Position(double.Parse(input[1]), double.Parse(input[2])); if (Calc.GetDistance(frogs[bothAlgosCounter % 2].Pos, next) > Frog.MaxJumpDistance) { frogs[bothAlgosCounter % 2].Pos = frogs[bothAlgosCounter % 2].Pos.Add(Calc.GetVector(frogs[bothAlgosCounter % 2].Pos, next).Scale(2.0)); } else { frogs[bothAlgosCounter % 2].Pos = next; } } }
public bool GetShoot(out Position target) { bool shoot = (this.IsShooting && this.CanShoot); target = new Position(this.ShootTargetPos.X, this.ShootTargetPos.Y); // copy return shoot; }
public bool RunFromPoolBorder() { bool moved = false; Position center = new Position(0, 0); Position toCheck = this.Pos; double distanceToBorder = PoolRadus - (Calc.GetDistance(toCheck, center) + FrogRadius); if (distanceToBorder < MinimalDistanceToBorder) { // move to the center immediately with max speed this.NextMovePos = this.Pos.Add(Calc.GetVector(toCheck, center).Scale(MaxJumpDistance)); moved = true; } return moved; }
public bool RunFromEnemy(Frog enemy) { // try to keep distance to enemy as much as possible // move randomly to the left or to the right of the vector between frogs // get enemy direction Position enemyVector = Calc.GetVector(this.Pos, enemy.Pos); // hardcoded decision table with random selector Position[] moves = new Position[12]; moves[0] = Calc.GetVector(this.Pos, new Position(0, 0)); // run to center moves[1] = Calc.RotateVectorClockwise(enemyVector); // run clockwise to the enemy position moves[2] = Calc.RotateVectorCounterClockwise(enemyVector); // run counter-clockwise to the enemy position moves[3] = moves[0]; // run to center moves[4] = moves[0]; // run to center moves[5] = moves[1]; // run counter-clockwise to the enemy position moves[6] = moves[1]; // run counter-clockwise to the enemy position moves[7] = moves[0]; // run to center moves[8] = moves[2]; // run counter-clockwise to the enemy position moves[9] = moves[1]; // run counter-clockwise to the enemy position moves[10] = enemyVector; // run forward to the enemy moves[11] = new Position(0,0); // stay at current position double distanceToEnemy = Calc.GetDistance(this.Pos, enemy.Pos); double scaleFactor = generator.NextDouble() * (Frog.MaxJumpDistance - Frog.MinJumpDistance) + Frog.MinJumpDistance; // check if frogs are in range (in 2 moves bullet can reach the frog, but we can run away in these 2 moves) bool closeToEnemy = (distanceToEnemy < 2 * Bullet.BulletSpeed); // and if yes - exclude last two choices - stay and move forward int chooseMove = generator.Next(closeToEnemy ? moves.Length - 2 : moves.Length); this.NextMovePos = this.Pos.Add(moves[chooseMove].Scale(scaleFactor)); if (closeToEnemy) { ShootAtEnemy(enemy); } return (chooseMove != 3); // if stays then no move has been selected }