예제 #1
0
        private int isTravellingToBase(Character unit, int prev_x, int prev_y, Tuple <int, int> basePos, Boolean isEnemyBase = true)
        {
            // if the base is not defined, the unit can't be traveling to it
            if (basePos.Item1 < 0)
            {
                return(0);
            }

            if (GameBoard.distance(unit.xPos, unit.yPos, basePos.Item1, basePos.Item2) < GameBoard.distance(prev_x, prev_y, basePos.Item1, basePos.Item2))
            {
                if (isEnemyBase)
                {
                    return(HEURISTIC_TRAVEL_TO_ENEMY_BASE);
                }
                else
                {
                    int numGuarding = 0;
                    foreach (EnemyCharacter friendly in cpuUnits)
                    {
                        if (GameBoard.distance(friendly.xPos, friendly.yPos, cpuBasePos.Item1, cpuBasePos.Item2) < 3)
                        {
                            numGuarding++;
                        }
                    }
                    return(HEURISTIC_TRAVEL_TO_HOME_BASE - numGuarding);
                }
            }
            else
            {
                return(0);
            }
        }
예제 #2
0
 private int canAttackBaseAttacker(Character unit, List <Character> enemy_units, Tuple <int, int> base_pos)
 {
     // if there is no base, obviously this will never be true
     if (base_pos.Item1 < 0)
     {
         return(0);
     }
     foreach (Character enemy_unit in enemy_units)
     {
         if (GameBoard.distance(enemy_unit.xPos, enemy_unit.yPos, base_pos.Item1, base_pos.Item2) < 2)
         {
             if (GameBoard.distance(enemy_unit.xPos, enemy_unit.yPos, unit.xPos, unit.yPos) < 2)
             {
                 return(HEURISTIC_ATTACK_BASE_ATTACKER);
             }
             else
             {
                 return(0);
             }
         }
         else
         {
             return(0);
         }
     }
     return(0);
 }
예제 #3
0
 private int isGuardingBase(Character unit, Tuple <int, int> basePos)
 {
     if (GameBoard.distance(unit.xPos, unit.yPos, basePos.Item1, basePos.Item2) < 2)
     {
         return(HEURISTIC_GUARD_BASE);
     }
     else
     {
         return(0);
     }
 }
예제 #4
0
 private int isMovingToInterceptOpponent(Character unit, List <Character> enemy_units, int prev_x, int prev_y)
 {
     // as long as the cpu unit is moving toward another player unit, return true
     foreach (Character e_unit in enemy_units)
     {
         if (GameBoard.distance(unit.xPos, unit.yPos, e_unit.xPos, e_unit.yPos) < GameBoard.distance(prev_x, prev_y, e_unit.xPos, e_unit.yPos))
         {
             return(HEURISTIC_INTERCEPT_OPPONENT);
         }
     }
     return(0);
 }
예제 #5
0
        private int canDamageOpponentBase(Character unit, Tuple <int, int> basePos)
        {
            if (basePos.Item1 < 0)
            {
                return(0);
            }

            if (GameBoard.distance(unit.xPos, unit.yPos, basePos.Item1, basePos.Item2) < 2)
            {
                return(HEURISTIC_DAMAGE_OPPONENT_BASE);
            }
            else
            {
                return(0);
            }
        }
예제 #6
0
        private int isFleeingFromOverwhelmingForce(Character unit, List <Character> enemy_units, List <Character> friendly_units, int prev_x, int prev_y)
        {
            List <Character> unitsToConsider = new List <Character>();
            int enemy_count = 0;
            int unit_count  = 0;

            // get all units within 3 spaces of the current unit
            foreach (Character enemy in enemy_units)
            {
                if (GameBoard.distance(enemy.xPos, enemy.yPos, unit.xPos, unit.yPos) <= 3)
                {
                    unitsToConsider.Add(enemy);
                    enemy_count++;
                }
            }
            foreach (Character friendly_unit in friendly_units)
            {
                // don't include the given unit
                if (friendly_unit == unit)
                {
                    continue;
                }
                if (GameBoard.distance(friendly_unit.xPos, friendly_unit.yPos, unit.xPos, unit.yPos) <= 3)
                {
                    unit_count++;
                }
            }

            // if the player force is at least the overwhelming percentage, fleeing is an option
            if (enemy_count / (unit_count + 1) > OVERWHELMING_FORCE_PERCENT)
            {
                // now we need to get which direction they are all mainly coming from
                // get the average x and y vector they are coming from
                float      avg_x   = 0.0f;
                float      avg_y   = 0.0f;
                List <int> vectors = new List <int>();
                foreach (Character enemy in unitsToConsider)
                {
                    avg_x += (enemy.xPos - unit.xPos);
                    avg_y += (enemy.yPos - unit.yPos);
                }
                // if the resultant additions so far are very small, we're surrounded, so there's nowhere to run to
                if ((avg_x < 1 && avg_x > -1) && (avg_y < 1 && avg_y > -1))
                {
                    return(0);
                }

                // get the unit vector of current motion
                float motion_x = unit.xPos - prev_x;
                float motion_y = unit.yPos - prev_y;
                motion_x = motion_x / ((float)Math.Sqrt(motion_x * motion_x + motion_y * motion_y));
                motion_y = motion_x / ((float)Math.Sqrt(motion_x * motion_x + motion_y * motion_y));

                // make the averages unit vectors
                avg_x = avg_x / ((float)Math.Sqrt(avg_x * avg_x + avg_y * avg_y));
                avg_y = avg_y / ((float)Math.Sqrt(avg_x * avg_x + avg_y * avg_y));

                // now just get the angle between the vectors
                float theta = (float)Math.Acos(motion_x * avg_x + motion_y * avg_y);

                // if current motion is greater than 90 degrees away from the enemy positions, unit is fleeing
                if (theta > Math.PI / 2)
                {
                    return(HEURISTIC_FLEE_FROM_OVER_FORCE);
                }
                else
                {
                    return(0);
                }
            }
            else
            {
                return(0);
            }
        }