示例#1
0
        public void SpellOptimizerTest()
        {
            var allSpells = GetAllSpells().ToList();

            var baseSpell = ImmutableStack <Spell> .Instance
                            .Push(allSpells[0])
                            .Push(allSpells[1])
                            .Push(allSpells[2])
                            .Push(allSpells[3]);

            var spellsForLearn = new List <Spell>()
            {
                allSpells[15],
                allSpells[27],
                allSpells[31],
                allSpells[9],
                allSpells[7],
                allSpells[11],
            };

            var tomeSpells = spellsForLearn.Select((x, i) => new Learn(x.Id, 0, x.Tiers, i))
                             .ToList();

            var orders = new List <Order>
            {
                OrderReceipts[2],
                OrderReceipts[7],
                OrderReceipts[22],
                OrderReceipts[31],
                OrderReceipts[13],
            };

            var sw             = Stopwatch.StartNew();
            var spellOptimizer = new SpellOptimizer();
            var mapForLearn    = spellOptimizer.GetSpellMapForLearn(orders, tomeSpells, baseSpell, sw);

            foreach (var item in mapForLearn)
            {
                var sb = new StringBuilder();
                sb.Append($"points: {item.TotalRupies}, length: {item.TotalLength}, maxDeep: {item.MaxDeep}  | ");
                foreach (var i in item.LearnOrder)
                {
                    sb.Append($" -> {i}");
                }

                Console.WriteLine(sb);
            }

            Console.WriteLine("Optimal path for second set.");
            var t = mapForLearn[1];

            for (var i = 0; i < orders.Count; i++)
            {
                Console.WriteLine($"Recipes for order {i}");
                foreach (var recipes in t.OptimalRecipes[i])
                {
                    Console.WriteLine($"\t{recipes}");
                }
            }
        }
示例#2
0
        public void BugTest()
        {
            var allSpells = GetAllSpells().ToList();

            var baseSpell = ImmutableStack <Spell> .Instance
                            .Push(allSpells[0])
                            .Push(allSpells[1])
                            .Push(allSpells[2])
                            .Push(allSpells[3]);

            var tomeSpells = new List <Learn>
            {
                new Learn(244, 0, (-2, 0, -1, 2), 0),
                new Learn(245, 0, (-3, 0, 0, 1), 1),
                new Learn(246, 0, (-4, 0, 2, 0), 2),
                new Learn(247, 0, (3, -2, 1, 0), 3),
                new Learn(248, 0, (0, -3, 3, 0), 4),
                new Learn(249, 0, (0, 0, -3, 3), 5),
            };


            var orders = new List <Order>
            {
                OrderReceipts[22],
                OrderReceipts[29],
                OrderReceipts[10],
                OrderReceipts[15],
                OrderReceipts[3],
            };

            var spellOptimizer = new SpellOptimizer();
            var sw             = Stopwatch.StartNew();
            var learnMap       = spellOptimizer.GetSpellMapForLearn(orders, tomeSpells, baseSpell, sw);


            var spells = baseSpell;

            var learnRes = Player.TryGetLearnAction(learnMap, tomeSpells, spells, 3, new HashSet <int>());

            spells     = spells.Push(new Spell(147, ((Learn)learnRes.action).Spell, true, 1));
            tomeSpells = tomeSpells.Where(x => x.Id != ((Learn)learnRes.action).Id).ToList();
            var learnRes2 = Player.TryGetLearnAction(learnMap, tomeSpells, spells, 3, new HashSet <int>());

            spells     = spells.Push(new Spell(741, ((Learn)learnRes2.action).Spell, true, 1));
            tomeSpells = tomeSpells.Where(x => x.Id != ((Learn)learnRes2.action).Id).ToList();
            var learnRes3 = Player.TryGetLearnAction(learnMap, tomeSpells, spells, 3, new HashSet <int>());
        }
示例#3
0
    static void Main(string[] args)
    {
        GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;

        //LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

        string[]        inputs;
        var             turnNumber   = -1;
        List <SpellMap> learnMap     = null;
        SpellMap        bestSpellMap = null;

        var            useGreedy         = true;
        GreedyResolver greedyResolver    = null;
        Path           previousActions   = Path.Instance;
        int?           greadyOrderTurn   = null;
        int            finishedOrdersCnt = 0;
        var            usedOrders        = new HashSet <int>();

        var sw = new Stopwatch();

        // game loop
        while (true)
        {
            turnNumber++;
            int actionCount = int.Parse(Console.ReadLine()); // the number of spells and recipes in play
            sw.Restart();

            var orders     = new List <Order>();
            var spells     = ImmutableStack <Spell> .Instance;
            var learns     = new List <Learn>();
            var usedSpells = new HashSet <int>();
            for (int i = 0; i < actionCount; i++)
            {
                inputs = Console.ReadLine().Split(' ');
                int    actionId   = int.Parse(inputs[0]);  // the unique ID of this spell or recipe
                string actionType = inputs[1];             // in the first league: BREW; later: CAST, OPPONENT_CAST, LEARN, BREW
                int    delta0     = int.Parse(inputs[2]);  // tier-0 ingredient change
                int    delta1     = int.Parse(inputs[3]);  // tier-1 ingredient change
                int    delta2     = int.Parse(inputs[4]);  // tier-2 ingredient change
                int    delta3     = int.Parse(inputs[5]);  // tier-3 ingredient change
                byte   price      = byte.Parse(inputs[6]); // the price in rupees if this is a potion
                int    tomeIndex  = int.Parse(inputs[7]);  // in the first two leagues: always 0; later: the index in the tome if this is a tome spell, equal to the read-ahead tax
                int    taxCount   = int.Parse(inputs[8]);  // in the first two leagues: always 0; later: the amount of taxed tier-0 ingredients you gain from learning this spell
                bool   castable   = inputs[9] != "0";      // in the first league: always 0; later: 1 if this is a castable player spell
                bool   repeatable = inputs[10] != "0";     // for the first two leagues: always 0; later: 1 if this is a repeatable player spell

                if (actionType == "BREW")
                {
                    orders.Add(new Order(actionId, (delta0, delta1, delta2, delta3), price));
                }

                if (actionType == "CAST")
                {
                    spells = spells.Push(new Spell(actionId, (delta0, delta1, delta2, delta3), repeatable, 1));
                    if (!castable)
                    {
                        usedSpells.Add(actionId);
                    }
                }

                if (actionType == "LEARN")
                {
                    learns.Add(new Learn(actionId, taxCount, (delta0, delta1, delta2, delta3), tomeIndex));
                }
            }

            //Console.Error.WriteLine($"Orders cnt: {orders.Count}");

            var needRest = usedSpells.Any();

            StateRes res = null;
            for (int i = 0; i < 2; i++)
            {
                inputs = Console.ReadLine().Split(' ');
                int  inv0  = int.Parse(inputs[0]); // tier-0 ingredients in inventory
                int  inv1  = int.Parse(inputs[1]);
                int  inv2  = int.Parse(inputs[2]);
                int  inv3  = int.Parse(inputs[3]);
                byte score = byte.Parse(inputs[4]); // amount of rupees

                if (i == 0)
                {
                    res = new StateRes((inv0, inv1, inv2, inv3), score);
                }
            }

            var currentState = new GameState
                               (
                res,
                spells,
                orders,
                learns,
                usedOrders,
                usedSpells,
                new HashSet <int>(),
                Path.Instance,
                needRest
                               );

            // Write an action using Console.WriteLine()
            // To debug: Console.Error.WriteLine("Debug messages...");
            if (turnNumber == 0)
            {
                var learnTime = new Stopwatch();
                learnTime.Restart();
                var spellOptimizer = new SpellOptimizer();
                learnMap = spellOptimizer.GetSpellMapForLearn(orders, learns, spells, sw);
                Console.Error.WriteLine($"Learn time: {learnTime.ElapsedMilliseconds:F1}");
            }

            if (bestSpellMap == null)
            {
                var learnRes = TryGetLearnAction(learnMap, learns, spells, currentState.StateRes.Inventary[0], currentState.UsedSpells);
                bestSpellMap = learnRes.spellMap;
                if (learnRes.action != null)
                {
                    var q = new StringBuilder();
                    q.Append(learnRes.action.Print());
                    if (bestSpellMap != null)
                    {
                        greedyResolver = new GreedyResolver(bestSpellMap);
                        q.Append($" I AM READY! D{bestSpellMap.MaxDeep}");
                        var dbg = new StringBuilder();
                        foreach (var idx in bestSpellMap.LearnOrder)
                        {
                            dbg.Append($" {idx}");
                        }
                        Console.Error.WriteLine(dbg);
                    }
                    else
                    {
                        q.Append(" I SHOULD BE SMARTER!");
                    }

                    Console.WriteLine(q.ToString());
                    continue;
                }
            }

            if (useGreedy && greedyResolver != null)
            {
                var decision = greedyResolver.Resolve(currentState, previousActions, finishedOrdersCnt);
                finishedOrdersCnt = decision.finishedOrders;
                previousActions   = decision.previousActions;
                var greedyAction = decision.nextAction;
                if (greedyAction != null)
                {
                    if (greedyAction is Order)
                    {
                        usedOrders.Add(((Order)greedyAction).Id);
                        greadyOrderTurn = turnNumber;
                    }
                    Console.WriteLine($"{greedyAction.Print()} I AM GREEDY!");
                    continue;
                }

                if (greadyOrderTurn == turnNumber - 1)
                {
                    Console.WriteLine($"{new Rest().Print()} I AM GREEDY!");
                    continue;
                }
            }

            var action = new Resolver(debug, 35).Resolve(currentState, sw);
            if (action.StartsWith("BREW"))
            {
                var num = int.Parse(action.Split(' ')[1]);
                usedOrders.Add(num);
            }
            Console.WriteLine(action);
            // in the first league: BREW <id> | WAIT; later: BREW <id> | CAST <id> [<times>] | LEARN <id> | REST | WAIT
        }
    }