static bool ai_evaluate_hex(ref AI_Eval eval)
 {
     int result;
     int i, nx, ny, ox, oy, odist, j, nx2, ny2;
     bool covered;
     eval.target = null;
     eval.mov_score = eval.atk_score = 0;
     /* terrain modifications which only apply for ground units */
     if ((eval.unit.sel_prop.flags & UnitFlags.FLYING) != UnitFlags.FLYING)
     {
         /* entrenchment bonus. infantry receives more than others. */
         eval.mov_score += (((eval.unit.sel_prop.flags & UnitFlags.INFANTRY) == UnitFlags.INFANTRY) ? 2 : 1) *
                            (Engine.map.map[eval.x, eval.y].terrain.min_entr * 2 +
                              Engine.map.map[eval.x, eval.y].terrain.max_entr);
         /* if the unit looses initiative on this terrain we give a malus */
         if (Engine.map.map[eval.x, eval.y].terrain.max_ini < eval.unit.sel_prop.ini)
             eval.mov_score -= 5 * (eval.unit.sel_prop.ini -
                                       Engine.map.map[eval.x, eval.y].terrain.max_ini);
         /* rivers should be avoided */
         if ((Engine.map.map[eval.x, eval.y].terrain.flags[Scenario.cur_weather] & Terrain_flags.RIVER) == Terrain_flags.RIVER)
             eval.mov_score -= 50;
         if ((Engine.map.map[eval.x, eval.y].terrain.flags[Scenario.cur_weather] & Terrain_flags.SWAMP) == Terrain_flags.SWAMP)
             eval.mov_score -= 30;
         /* inf_close_def will benefit an infantry while disadvantaging
            other units */
         if ((Engine.map.map[eval.x, eval.y].terrain.flags[Scenario.cur_weather] & Terrain_flags.INF_CLOSE_DEF) == Terrain_flags.INF_CLOSE_DEF)
         {
             if ((eval.unit.sel_prop.flags & UnitFlags.INFANTRY) == UnitFlags.INFANTRY)
                 eval.mov_score += 30;
             else
                 eval.mov_score -= 20;
         }
         /* if this is a mount position and an enemy or fog is less than
            6 tiles away we give a big malus */
         if (Engine.map.mask[eval.x, eval.y].mount != 0)
             if (ai_unsafe__mount(eval.unit, eval.x, eval.y))
                 eval.mov_score -= 1000;
         /* conquering a flag gives a bonus */
         if (Engine.map.map[eval.x, eval.y].player != null)
             if (!Player.player_is_ally(eval.unit.player, Engine.map.map[eval.x, eval.y].player))
                 if (Engine.map.map[eval.x, eval.y].g_unit == null)
                 {
                     eval.mov_score += 600;
                     if (Engine.map.map[eval.x, eval.y].obj)
                         eval.mov_score += 600;
                 }
         /* if this position allows debarking or is just one hex away
            this tile receives a big bonus. */
         if (eval.unit.embark == UnitEmbarkTypes.EMBARK_SEA)
         {
             if (Engine.map.map_check_unit_debark(eval.unit, eval.x, eval.y, UnitEmbarkTypes.EMBARK_SEA, false))
                 eval.mov_score += 1000;
             else
                 for (i = 0; i < 6; i++)
                     if (Misc.get_close_hex_pos(eval.x, eval.y, i, out nx, out ny))
                         if (Engine.map.map_check_unit_debark(eval.unit, nx, ny, UnitEmbarkTypes.EMBARK_SEA, false))
                         {
                             eval.mov_score += 500;
                             break;
                         }
         }
     }
     /* modifications on flying units */
     if ((eval.unit.sel_prop.flags & UnitFlags.FLYING) == UnitFlags.FLYING)
     {
         /* if interceptor covers an uncovered bomber on this tile give bonus */
         if ((eval.unit.sel_prop.flags & UnitFlags.INTERCEPTOR) == UnitFlags.INTERCEPTOR)
         {
             for (i = 0; i < 6; i++)
                 if (Misc.get_close_hex_pos(eval.x, eval.y, i, out nx, out ny))
                     if (Engine.map.map[nx, ny].a_unit != null)
                         if (Player.player_is_ally(Engine.cur_player, Engine.map.map[nx, ny].a_unit.player))
                             if ((Engine.map.map[nx, ny].a_unit.sel_prop.flags & UnitFlags.BOMBER) == UnitFlags.BOMBER)
                             {
                                 covered = false;
                                 for (j = 0; j < 6; j++)
                                     if (Misc.get_close_hex_pos(nx, ny, j, out nx2, out ny2))
                                         if (Engine.map.map[nx2, ny2].a_unit != null)
                                             if (Player.player_is_ally(Engine.cur_player, Engine.map.map[nx2, ny2].a_unit.player))
                                                 if ((Engine.map.map[nx2, ny2].a_unit.sel_prop.flags & UnitFlags.INTERCEPTOR) == UnitFlags.INTERCEPTOR)
                                                     if (Engine.map.map[nx2, ny2].a_unit != eval.unit)
                                                     {
                                                         covered = true;
                                                         break;
                                                     }
                                 if (!covered)
                                     eval.mov_score += 2000; /* 100 equals one tile of getting
                                             to center of interest which must
                                             be overcome */
                             }
         }
     }
     /* each group has a 'center of interest'. getting closer
        to this center is honored. */
     if (eval.group.x == -1)
     {
         /* proceed to the nearest flag */
         if ((eval.unit.sel_prop.flags & UnitFlags.FLYING) != UnitFlags.FLYING)
         {
             if (eval.group.order > 0)
             {
                 if (AI.ai_get_dist(eval.unit, eval.x, eval.y, AI_FIND.AI_FIND_ENEMY_OBJ, out ox, out oy, out odist))
                     eval.mov_score -= odist * 100;
             }
             else
                 if (eval.group.order < 0)
                 {
                     if (AI.ai_get_dist(eval.unit, eval.x, eval.y, AI_FIND.AI_FIND_OWN_OBJ, out ox, out oy, out odist))
                         eval.mov_score -= odist * 100;
                 }
         }
     }
     else
         eval.mov_score -= 100 * Misc.get_dist(eval.x, eval.y, eval.group.x, eval.group.y);
     /* defensive support */
     ai_count_df_units(eval.unit, eval.x, eval.y, out result);
     if (result > 2) result = 2; /* senseful limit */
     eval.mov_score += result * 10;
     /* check for the best target and save the result to atk_score */
     eval.atk_score = eval.mov_score;
     if (Engine.map.mask[eval.x, eval.y].mount == 0)
         if (((eval.unit.sel_prop.flags & UnitFlags.ATTACK_FIRST) != UnitFlags.ATTACK_FIRST) ||
               eval.unit.x == eval.x && eval.unit.y == eval.y)
             if (ai_get_best_target(eval.unit, eval.x, eval.y, eval.group, out eval.target, out result))
                 eval.atk_score += result;
     return true;
 }
 static AI_Eval ai_create_eval(Unit unit, AI_Group group, int x, int y)
 {
     AI_Eval eval = new AI_Eval();
     eval.unit = unit; eval.group = group;
     eval.x = x; eval.y = y;
     return eval;
 }