/// <summary>
        /// Moves a unit on the game board and redraws to show updated
        /// positions.
        /// </summary>
        /// <param name="character">ID of the piece, so we know how to redraw.</param>
        /// <param name="newX">new x-coordinate position of the piece</param>
        /// <param name="newY">new y-coordinate position of the piece</param>
        /// <returns>true if the update happened, false otherwise</returns>
        public static Boolean update(Character character, Int16 newX, Int16 newY)
        {
            if (isValidMove(newX, newY))
            {
                Logger.log(@"Valid move detected, attempting to reassign position.", "debug");
                overlay[character.yPos, character.xPos] = board[character.yPos, character.xPos];
                overlay[newY, newX] = character.id;
                character.xPos = newX;
                character.yPos = newY;
                Logger.log(@"Reassignment successful, map should redraw.", "debug");

                redraw();
                return true;
            }
            else
            {
                Logger.log(String.Format(@"Invalid move detected. Tried to place at {0}, {1}", newX, newY), "warning");
                return false;
            }
        }
Esempio n. 2
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;
 }
Esempio n. 3
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; }
        }
Esempio n. 4
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; }
 }
Esempio n. 5
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; }
        }
Esempio n. 6
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; }
        }
Esempio n. 7
0
 private int canAttackOpponent(Character unit, List<Character> enemyUnits)
 {
     List<Character> attackable = GameBoard.getAttackableUnits(unit.xPos, unit.yPos, enemyUnits);
     if (attackable.Any()) { return HEURISTIC_ATTACK_OPPONENT_UNIT; }
     return 0;
 }
Esempio n. 8
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;
 }