void ProcessCombatUnit(CombatUnit t_combatUnit)
    {
        bool combatActionFound = false;

        for (int i = 0; i < m_combatActions.Count && !combatActionFound; i++)
        {
            if (m_combatActions[i].m_unit == t_combatUnit)
            {
                combatActionFound = true;
            }
        }

        if (!combatActionFound)
        {
            CombatUnitAction combatUnitAction = new CombatUnitAction();
            combatUnitAction.Initilaize(this, t_combatUnit);
            m_combatActions.Add(combatUnitAction);
        }
    }
        public Action GetAction(PlayerView playerView, DebugInterface debugInterface)
        {
            if (Params.IsDebug)
            {
                debugInterface.Send(new DebugCommand.SetAutoFlush(true));
            }

            if (playerView.CurrentTick == 10 && playerView.Players.Length == 2)
            {
                Params.RangedBaseBuildingLimit = 35;
                Params.MaxBuilderUnitsCount   += 30;
                Params.MaxRangedUnitsCount    += 20;
                Params.MaxHouseCount          += 10;
            }

            var entityActions = new Dictionary <int, EntityAction>();

            ScoreMap.InitMap(playerView);
            DrawScoreMap(debugInterface);
            IsDanger = DangerCheck();

            // repairing
            Entity? builder     = null;
            Vec2Int?moveTarget  = null;
            int     minDistance = int.MaxValue;

            foreach (Entity entity in playerView.Entities)
            {
                if (entity.PlayerId != ScoreMap.MyId || entity.EntityType != EntityType.BuilderUnit)
                {
                    continue;
                }

                BuilderUnitActions.SetRepair(playerView, entity, entityActions);
                if (!ScoreMap.AnyRepairScoreMoreThanOne || entityActions.ContainsKey(entity.Id))
                {
                    continue;
                }

                var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions);

                var bestTarget = ASearchMove(entity, approxTarget, out var cameFrom, out var costSoFar);
                var cell       = ScoreMap.Get(bestTarget);
                if (cell.RepairScore > 1 && costSoFar[bestTarget] < minDistance)
                {
                    builder     = entity;
                    moveTarget  = GetMoveTarget(builder.Value.Position, bestTarget, cameFrom, Blue, debugInterface);
                    minDistance = costSoFar[bestTarget];
                }
            }

            if (builder != null && moveTarget != null)
            {
                ScoreMap.Set(builder.Value.Position, null);
                ScoreMap.Set(moveTarget.Value, builder.Value);

                var moveAction = new MoveAction(moveTarget.Value, false, false);
                entityActions.Add(builder.Value.Id, new EntityAction(moveAction, null, null, null));
            }

            // building turret
            if ((playerView.Players.Length > 2 || playerView.CurrentTick >= 300) &&
                ScoreMap.MyActiveRangedBases.Count > 0 &&
                (ScoreMap.Limit >= Params.TurretBuildingLimit || playerView.CurrentTick >= 300) &&
                ScoreMap.MyResource >= ScoreMap.TurretProperties.InitialCost &&
                ScoreMap.MyNotActiveTurrets.Count <= 1)
            {
                BuilderUnitActions.SetBuild(EntityType.Turret, ScoreMap.TurretProperties.Size, entityActions, debugInterface);
                ScoreMap.MyResource -= ScoreMap.TurretProperties.InitialCost;
            }

            // building ranged base
            if (ScoreMap.MyActiveRangedBases.Count == 0 &&
                ScoreMap.MyResource >= ScoreMap.RangedBaseProperties.InitialCost &&
                ScoreMap.MyNotActiveRangedBases.Count == 0)
            {
                BuilderUnitActions.SetBuild(EntityType.RangedBase, ScoreMap.RangedBaseProperties.Size, entityActions, debugInterface);
                ScoreMap.MyResource -= ScoreMap.RangedBaseProperties.InitialCost;
            }

            // building house
            if (((ScoreMap.MyActiveRangedBases.Count == 0 &&
                  ScoreMap.Limit >= Params.RangedBaseBuildingLimit &&
                  ScoreMap.MyResource >=
                  ScoreMap.RangedBaseProperties.InitialCost + ScoreMap.HouseProperties.InitialCost) ||

                 ((ScoreMap.MyActiveRangedBases.Count > 0 ||
                   ScoreMap.MyNotActiveRangedBases.Count > 0 ||
                   ScoreMap.Limit < Params.RangedBaseBuildingLimit) &&
                  ScoreMap.MyResource >= ScoreMap.HouseProperties.InitialCost)
                 ) &&
                ScoreMap.Limit + 10 >= ScoreMap.AvailableLimit &&
                ScoreMap.MyNotActiveHouses.Count <= 1 &&
                ScoreMap.MyNotActiveHouses.Count + ScoreMap.MyActiveHouses.Count < Params.MaxHouseCount)
            {
                BuilderUnitActions.SetBuild(EntityType.House, ScoreMap.HouseProperties.Size, entityActions, debugInterface);
                ScoreMap.MyResource -= ScoreMap.HouseProperties.InitialCost;
            }

            foreach (Entity entity in playerView.Entities)
            {
                if (entity.PlayerId != ScoreMap.MyId)
                {
                    continue;
                }

                switch (entity.EntityType)
                {
                case EntityType.BuilderUnit:
                {
                    BuilderUnitActions.SetAttack(entity, entityActions);
                    var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions);
                    SetMoveAction(entity, approxTarget, entityActions, debugInterface);
                    continue;
                }

                case EntityType.MeleeUnit:
                {
                    CombatUnitAction.SetAttack(entity, 1, 1, entityActions);
                    var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions);
                    SetMoveAction(entity, approxTarget, entityActions, debugInterface);
                    continue;
                }

                case EntityType.RangedUnit:
                {
                    CombatUnitAction.SetAttack(entity, 5, 1, entityActions);
                    var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions);
                    SetMoveAction(entity, approxTarget, entityActions, debugInterface);
                    continue;
                }

                case EntityType.Turret:
                {
                    if (!entity.Active)
                    {
                        continue;
                    }

                    CombatUnitAction.SetAttack(entity, 5, 2, entityActions);
                    continue;
                }

                case EntityType.BuilderBase:
                {
                    int unitCost = ScoreMap.BuilderUnitProperties.InitialCost + ScoreMap.MyBuilderUnits.Count;

                    if ((IsDanger && ScoreMap.MyResource >= unitCost * 2 ||
                         !IsDanger && ScoreMap.MyResource >= unitCost) &&
                        ScoreMap.MyBuilderUnits.Count < ScoreMap.BuilderUnitTargets.Count &&
                        ScoreMap.MyBuilderUnits.Count < Params.MaxBuilderUnitsCount)
                    {
                        var approxTarget = BuilderUnitActions.GetApproxTarget(entity, entityActions);
                        SetBuildUnitAction(entity, approxTarget, EntityType.BuilderUnit, unitCost, entityActions);
                    }

                    if (!entityActions.ContainsKey(entity.Id))
                    {
                        entityActions.Add(entity.Id, new EntityAction(null, null, null, null));
                    }

                    continue;
                }

                case EntityType.MeleeBase:
                {
                    int unitCost = ScoreMap.MeleeUnitProperties.InitialCost + ScoreMap.MyMeleeUnits.Count;

                    if ((IsDanger && ScoreMap.MyResource >= unitCost ||
                         !IsDanger && ScoreMap.MyResource >= unitCost * 2) &&
                        ScoreMap.MyRangedUnits.Count * 2 >= Params.MaxRangedUnitsCount &&
                        ScoreMap.MyMeleeUnits.Count < Params.MaxMeleeUnitsCount)
                    {
                        var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions);
                        SetBuildUnitAction(entity, approxTarget, EntityType.MeleeUnit, unitCost, entityActions);
                    }

                    if (!entityActions.ContainsKey(entity.Id))
                    {
                        entityActions.Add(entity.Id, new EntityAction(null, null, null, null));
                    }

                    continue;
                }

                case EntityType.RangedBase:
                {
                    if (!entity.Active)
                    {
                        continue;
                    }

                    int unitCost = ScoreMap.RangedUnitProperties.InitialCost + ScoreMap.MyRangedUnits.Count;

                    if ((IsDanger && ScoreMap.MyResource >= unitCost ||
                         !IsDanger && ScoreMap.MyResource >= unitCost * 3) &&
                        ScoreMap.MyRangedUnits.Count < Params.MaxRangedUnitsCount)
                    {
                        var approxTarget = CombatUnitAction.GetAttackTarget(entity, entityActions);
                        SetBuildUnitAction(entity, approxTarget, EntityType.RangedUnit, unitCost, entityActions);
                    }

                    if (!entityActions.ContainsKey(entity.Id))
                    {
                        entityActions.Add(entity.Id, new EntityAction(null, null, null, null));
                    }

                    continue;
                }
                }
            }

            return(new Action(entityActions));
        }