Beispiel #1
0
    public IMove GetCopy()
    {
        var result = new MultiMove();

        foreach (var move in moves)
        {
            result.AddMove(move.GetCopy());
        }
        return(result);
    }
Beispiel #2
0
 void FixedUpdate()
 {
     lockZ();
     multiMoves           = MultiMove.executeMultiMoves(multiMoves);
     this.currentVelocity = this.currentVelocity / 1.5f;
     if (Mathf.Abs(this.currentVelocity.x) < 0.05f && Mathf.Abs(this.currentVelocity.y) < 0.05f)
     {
         this.currentVelocity = new Vector3(0, 0);
     }
     transform.position = transform.position + this.getCurrentVelocity() * Time.deltaTime;
 }
    private IMove EvaluateMove()
    {
//        throw new NotImplementedException();
        var multiMove = new MultiMove();

        multiMove.AddMove(new Message($"Fight for {FactoryState.FactoryId}"));
        var moveTroops = new MoveTroops();

        multiMove.AddMove(moveTroops);
        for (int i = 0; i < StepsToPredict; i++)
        {
            //взять  мои фабрики на этом расстоянии
            var myFactoriesForAttack = graph.Factories[FactoryState.FactoryId].GetLinks()
                                       .Where(x => x.Distance <= i && graph.Factories[x.DestinationId].Side == Side.MyOwn)
                                       .Select(x => graph.Factories[x.DestinationId])
                                       .ToList();
            //если могут захватить - ура
            if (myFactoriesForAttack.Any() && myFactoriesForAttack.Sum(x => x.TroopsCanBeUsed) > FactoryState.Enemies[i])
            {
                int troopsUsed, needed;
                needed = troopsUsed = FactoryState.Enemies[i] ?? int.MaxValue;
                foreach (var myFactory in myFactoriesForAttack)
                {
//TODO: sort factories by distance or smth else
                    var sendedTroops = Math.Min(needed + 1, myFactory.TroopsCanBeUsed); // TODO: захват нейтралов совместный. +1 не совсем точно. нужно только для захвата но не деф.
                    myFactory.TroopsCanBeUsed =
                        graph.Factories[myFactory.Id].TroopsCanBeUsed = myFactory.TroopsCanBeUsed - sendedTroops;

                    var shortestPath = GraphLinks.Links[myFactory.Id, FactoryState.FactoryId];
                    moveTroops.AddTroop(new Troop {
                        Dst          = FactoryState.FactoryId,
                        DstInCommand = shortestPath.FirstFactoryId,
                        Side         = Side.MyOwn,
                        Remaining    = shortestPath.Distance + 1,
                        Src          = myFactory.Id,
                        Size         = sendedTroops
                    });

                    needed -= sendedTroops;
                    if (needed <= 0)
                    {
                        break;
                    }
                }

                priorityValue = CostFunction.GetJobEstimatePriority(
                    graph.Factories[FactoryState.FactoryId].Income * (graph.Factories[FactoryState.FactoryId].Side == Side.Neutral ? 1 : 2),
                    troopsUsed, i);

                break;
            }
        }
        return(multiMove);
    }
Beispiel #4
0
 public static void AddMovesForJobs(this Graph graph, List <IJob> jobs, MultiMove resultMove)
 {
 }
Beispiel #5
0
    public static IEnumerable <IMove> ProposeMoves(this Graph graph)
    {
        var stepsToPredict = Math.Max(graph.GetMaxCountSteps(), GraphLinks.MaxDistance);

        bool canSendBomb            = graph.BombsAvailable_MyOwn > 0;
        var  bombFactoriesCandidate = new List <Factory>();

        var factories = new List <FactoryStates>();
        var multiMove = new MultiMove();

        yield return(multiMove);

        { //Get List available for attack/defense
            var holdState = Graph.GetCopy(graph);
            graph.UpdateAvailableTroops(holdState, true);
            for (int i = 0; i < stepsToPredict; i++)
            {
                holdState.DoNextMove();
                graph.UpdateAvailableTroops(holdState);
            }
//            multiMove.AddMove(new Message("CBU:"+graph.Factories.Sum(x=>x.TroopsCanBeUsed)));
            if (canSendBomb)
            {
                var sendedBombTo = graph.Bombs.Any(x => x.Side == Side.MyOwn) ? graph.Bombs.Select(x => x.Dst).First() : -1;
                bombFactoriesCandidate = holdState.Factories.Where(x => x.Side == Side.Enemy && x.Income > 1 && x.Id != sendedBombTo).ToList();
            }
            // если не моя по истечению ходов то стоит ее проверить.
            foreach (var factoryTarget in holdState.Factories.Where(x => x.Side != Side.MyOwn && x.Income > 0))
            {
                var testGraph = Graph.GetCopy(graph);
                var move      = new MoveTroops();
                // шлем со всех туда.
                foreach (var myFactory in testGraph.Factories.Where(x => x.Side == Side.MyOwn && x.Id != factoryTarget.Id))
                {
                    var availableTroops = graph.Factories[myFactory.Id].TroopsCanBeUsed;
                    if (availableTroops <= 0)
                    {
                        continue;
                    }

                    //TODO: слать с переправами
                    var linkTo = myFactory.GetLinks().FirstOrDefault(link => link.DestinationId == factoryTarget.Id);
                    if (linkTo.Distance > 0)
                    {
                        // if any
                        move.AddTroop(new Troop {
                            Dst       = factoryTarget.Id,
                            Side      = myFactory.Side,
                            Src       = myFactory.Id,
                            Remaining = linkTo.Distance + 1,
                            Size      = availableTroops
                        });
                    }
                }
                move.ChangeGraph(testGraph);
                testGraph.DoSteps(testGraph.GetMaxCountSteps());
                // Если изменился статус фабрики - запоминаем
                if (testGraph.Factories[factoryTarget.Id].Side == Side.MyOwn)
                {
                    factories.Add(new FactoryStates(factoryTarget.Id, stepsToPredict));
                }
            }
        }
        //Select & send the bomb
        if (canSendBomb)
        {
            var bombTo = bombFactoriesCandidate
                         .OrderByDescending(x => x.Income)
                         .ThenByDescending(f => f.GetLinks().Where(x => graph.Factories[x.DestinationId].Side == Side.MyOwn).Min(x => x.Distance)) // Самая удаленная от нас
                         .FirstOrDefault();
            if (bombTo != null)
            {
                var bombLinkSources = bombTo.GetLinks().Where(x => graph.Factories[x.DestinationId].Side == Side.MyOwn).OrderBy(x => x.Distance);
                if (bombLinkSources.Any())
                {
                    var bombLinkSettings = bombLinkSources.FirstOrDefault();
                    multiMove.AddMove(
                        new SendBomb(new Bomb
                    {
                        Src       = bombLinkSettings.DestinationId,
                        Dst       = bombTo.Id,
                        Side      = Side.MyOwn,
                        Remaining = bombLinkSettings.Distance + 1,
                    }));
                }
            }
        }

        {
            var jobs = new List <IJob>();

            // Get moves to minimum attack
            if (factories.Any())
            {
                multiMove.AddMove(new Message("Init Atack/Defense"));

                var holdState = Graph.GetCopy(graph);
                for (int i = 0; i < stepsToPredict; i++)
                {
                    holdState.DoNextMove();
                    foreach (var factoryState in factories)
                    {
                        var factory = holdState.Factories[factoryState.FactoryId];
                        if (factory.Side == Side.MyOwn)
                        {
                            factoryState.Enemies[i] = null;
                        }
                        else
                        {
                            factoryState.Enemies[i] = factory.TroopsCount;
                        }
                    }
                }
                // fill nulls be next first value
                foreach (var factoryState in factories)
                {
                    for (int i = stepsToPredict - 2; i >= 0; i--)
                    {
                        if (!factoryState.Enemies[i].HasValue)
                        {
                            factoryState.Enemies[i] = factoryState.Enemies[i + 1];
                        }
                    }
                }
                //multiMove.AddMove(new Message($"FS #{factories.Count}: "  + string.Join(", ", factories.Select(x => $"({x.FactoryId})" + string.Join(".", x.Enemies.Select(t=> t ?? -1))))));

                factories.ForEach(x => { jobs.Add(new AtackFactory(x, stepsToPredict)); });
            }

            jobs.AddRange(
                graph.Factories
                .Where(x => x.Side == Side.MyOwn && x.Income < 3)     //TODO: condition can be changed, income check when bomb
                .Select(x => {
                if (x.TroopsCount >= 10 && x.TroopsCanBeUsed >= 9)
                {
                    return((IJob) new UpgradeFactoryJob(x.Id));
                }
                else
                {
                    return((IJob) new WaitToUpgradeFactoryJob(x.Id));
                }
            })
                );

            //Evaluate jobs
            var jobGraph = Graph.GetCopy(graph);
            while (true)
            {
                jobs.ForEach(x => { x.EvaluateInnerState(jobGraph); });
                var first = jobs.OrderByDescending(x => x.GetPriorityValue()).FirstOrDefault();
                if (first == null || first.GetPriorityValue() == int.MinValue)
                {
                    break;
                }
                var jobMove = first.GetMove();
                Logger.ErrorLog("Best job Cost: " + first.GetPriorityValue() + " ACT: " + jobMove.GetConsoleCommand(), LogReportLevel.BestJobCost);

                jobMove.ChangeGraph(jobGraph);
                multiMove.AddMove(jobMove);
                jobs.Remove(first);
                yield return(multiMove);
            }

            multiMove.AddMove(new Message("Init basic moves"));
            // Just move troops
            {
                // TODO: независимо для каждой фабрики выбирать
                foreach (var factory in graph.Factories.Where(x => x.Side == Side.MyOwn && x.TroopsCanBeUsed > 0))
                {
                    foreach (var factoryLink in factory.GetLinks())
                    {
                        var checkedMove = new MoveTroops(new Troop {
                            Dst          = factoryLink.DestinationId,
                            DstInCommand = factoryLink.FirstFactoryId,
                            Side         = Side.MyOwn,
                            Remaining    = factoryLink.Distance + 1,
                            Src          = factory.Id,
                            Size         = factory.TroopsCanBeUsed
                        });
                        multiMove.AddMove(checkedMove);
                        yield return(multiMove);

                        multiMove.RemoveMove(checkedMove);
                    }
                }
//                var l = graph.Factories.Where(x => x.Side == Side.MyOwn && x.TroopsCanBeUsed > 0)
//                    .OrderByDescending(x => {
//                        var links = x.GetLinks().Where(t => graph.Factories[t.DestinationId].Side == Side.Enemy);
//                        if (!links.Any()) return 0;
//
//                        return links.Min(t => t.Distance);
//                    });
            }

            yield return(multiMove);
        }
    }
Beispiel #6
0
 public UpgradeFactoryJob(int factoryId)
 {
     FactoryId = factoryId;
     move      = new MultiMove();
     move.AddMove(new UpgradeFactory(FactoryId));
 }
Beispiel #7
0
    void Update()
    {
        // Check if the player has pressed the fire button and if enough time has elapsed since they last fired
        if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
        {
            // Update the time when our player can fire next
            nextFire = Time.time + fireRate;

            // Start our ShotEffect coroutine to turn our laser line on and off
            StartCoroutine(ShotEffect());

            // Create a vector at the center of our camera's viewport
            Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));

            // Declare a raycast hit to store information about what our raycast has hit
            RaycastHit hit;


            // Set the start position for our visual effect for our laser to the position of gunEnd
            laserLine.SetPosition(0, gunEnd.position);

            // Check if our raycast has hit anything
            if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
            {
                // if (Physics.SphereCast(rayOrigin, 100,fpsCam.transform.forward, out hit, weaponRange))

                // Set the end position for our laser line
                laserLine.SetPosition(1, hit.point);

                // Get a reference to a health script attached to the collider we hit
                ShootableBox     health = hit.collider.GetComponent <ShootableBox>();
                MovePlatform     mp     = hit.collider.GetComponent <MovePlatform>();
                MoveablePlatform mc     = hit.collider.GetComponent <MoveablePlatform>();
                MultiMove        mm     = hit.collider.GetComponent <MultiMove>();

                if (health != null)
                {
                    health.Damage(gunDamage);
                }

                if (mp != null)
                {
                    //use if MoveablePlatform is mine not prefab
                    mp.Frozen();
                }

                if (mm != null)
                {
                    //use if MoveablePlatform is mine not prefab
                    mm.Frize();
                }
                if (mc != null)
                {
                    //use if MoveablePlatform is mine not prefab
                    mc.Froze();
                }

                // Check if the object we hit has a rigidbody attached
                if (hit.rigidbody != null)
                {
                }
            }
            else
            {
                // If we did not hit anything, set the end of the line to a position directly in front of the camera at the distance of weaponRange
                laserLine.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
            }
        }
    }