예제 #1
0
 public bool HasMana(
     int amount,
     ManaUsage usage = ManaUsage.Any,
     ConvokeAndDelveOptions convokeAndDelveOptions = null)
 {
     return(HasMana(amount.Colorless(), usage, convokeAndDelveOptions));
 }
예제 #2
0
        public bool Has(
            ManaAmount amount,
            ManaUsage usage,
            ConvokeAndDelveOptions convokeAndDelveOptions)
        {
            var allocated = TryToAllocateAmount(
                amount,
                usage,
                convokeAndDelveOptions);

            return(allocated != null && allocated.Lifeloss < _controller.Life);
        }
예제 #3
0
        private List <ManaUnit> GetAdditionalManaSources(
            ConvokeAndDelveOptions convokeAndDelve)
        {
            var additional = new List <ManaUnit>();

            convokeAndDelve = convokeAndDelve ?? ConvokeAndDelveOptions.NoConvokeAndDelve;

            if (convokeAndDelve.CanUseConvoke)
            {
                additional.AddRange(GetConvokeSources(convokeAndDelve.UiConvokeSources));
            }

            if (convokeAndDelve.CanUseDelve)
            {
                additional.AddRange(GetDelveSources(convokeAndDelve.UiDelveSources));
            }

            return(additional);
        }
예제 #4
0
        public void Consume(
            ManaAmount amount,
            ManaUsage usage,
            ConvokeAndDelveOptions convokeAndDelveOptions)
        {
            var allocated = TryToAllocateAmount(amount, usage, convokeAndDelveOptions);

            Asrt.True(allocated != null, "Not enough mana available.");

            var sources = GetSourcesToActivate(allocated.Units);

            foreach (var source in sources)
            {
                lock (_manaPoolCountLock)
                {
                    foreach (var unit in source.GetUnits())
                    {
                        _manaPool.Add(unit);
                    }
                }

                source.PayActivationCost();
            }

            lock (_manaPoolCountLock)
            {
                foreach (var unit in allocated.Units)
                {
                    _manaPool.Remove(unit);
                }
            }

            foreach (var unit in allocated.Units.Where(x => !x.HasSource))
            {
                RemovePermanently(unit);
            }

            _controller.Life -= allocated.Lifeloss;
        }
예제 #5
0
        public List <ManaColor> GetAvailableMana(ManaUsage usage, ConvokeAndDelveOptions convokeAndDelve)
        {
            var restricted = new HashSet <ManaUnit>();
            var allocated  = new List <ManaUnit>();

            var units = _units
                        .Concat(GetAdditionalManaSources(convokeAndDelve))
                        .ToList();

            foreach (var manaUnit in units)
            {
                if (IsAvailable(manaUnit, restricted, usage))
                {
                    restricted.Add(manaUnit);
                    allocated.Add(manaUnit);

                    RestrictUsingDifferentSourcesFromSameCard(manaUnit, restricted, units);
                }
            }

            return(allocated.Select(x => x.Color).ToList());
        }
예제 #6
0
        private AllocatedAmount TryToAllocateAmount(
            ManaAmount amount,
            ManaUsage usage,
            ConvokeAndDelveOptions convokeAndDelveOptions)
        {
            var restricted = new HashSet <ManaUnit>();
            var allocated  = new AllocatedAmount();

            var additional        = GetAdditionalManaSources(convokeAndDelveOptions);
            var additionalGrouped = GroupAdditionalSources(additional);
            var units             = _units.Concat(additional).ToList();

            var checkAmount = amount
                              .Select(x => new
            {
                Color       = GetColorIndex(x),
                Count       = x.Count,
                IsPhyrexian = x.Color.IsPhyrexian
            })
                              // first check for mana which has only few mana sources
                              .OrderBy(x => _groups[x.Color].Count)
                              .ToArray();

            var allocatedPhyrexian = new List <ManaUnit>();

            foreach (var manaOfSingleColor in checkAmount)
            {
                var ordered = _groups[manaOfSingleColor.Color]
                              .Concat(additionalGrouped[manaOfSingleColor.Color])
                              .OrderBy(GetManaUnitAllocationOrder)
                              .ToList();

                for (var i = 0; i < manaOfSingleColor.Count; i++)
                {
                    var allocatedUnit = ordered.FirstOrDefault(unit => IsAvailable(unit, restricted, usage));

                    // allocation failed
                    if (allocatedUnit == null)
                    {
                        if (manaOfSingleColor.IsPhyrexian)
                        {
                            allocated.Lifeloss += 2;
                            continue;
                        }

                        // if pyrexian is holding the slot, release it and pay life
                        if (allocatedPhyrexian.Count > 0)
                        {
                            var restrictedWithoutPhyrexian = restricted.Where(x => !allocatedPhyrexian.Contains(x)).ToHashSet();
                            allocatedUnit = ordered.FirstOrDefault(unit => IsAvailable(unit, restrictedWithoutPhyrexian, usage));

                            if (allocatedUnit != null)
                            {
                                allocated.Lifeloss += 2;
                                allocatedPhyrexian.Remove(allocatedUnit);
                                continue;
                            }
                        }

                        return(null);
                    }

                    if (manaOfSingleColor.IsPhyrexian)
                    {
                        allocatedPhyrexian.Add(allocatedUnit);
                    }

                    restricted.Add(allocatedUnit);
                    allocated.Units.Add(allocatedUnit);

                    RestrictUsingDifferentSourcesFromSameCard(allocatedUnit, restricted, units);
                }
            }

            return(allocated);
        }
예제 #7
0
 public bool HasMana(ManaAmount amount, ManaUsage usage            = ManaUsage.Any,
                     ConvokeAndDelveOptions convokeAndDelveOptions = null)
 {
     return(ManaCache.Has(amount, usage, convokeAndDelveOptions));
 }
예제 #8
0
 public void Consume(ManaAmount amount, ManaUsage usage, ConvokeAndDelveOptions convokeAndDelveOptions = null)
 {
     ManaCache.Consume(amount, usage, convokeAndDelveOptions);
 }
예제 #9
0
 public List <ManaColor> GetAvailableMana(
     ConvokeAndDelveOptions convokeAndDelveOptions = null,
     ManaUsage usage = ManaUsage.Any)
 {
     return(ManaCache.GetAvailableMana(usage, convokeAndDelveOptions));
 }
예제 #10
0
 public int GetAvailableManaCount(
     ConvokeAndDelveOptions convokeAndDelveOptions = null,
     ManaUsage usage = ManaUsage.Any)
 {
     return(GetAvailableMana(convokeAndDelveOptions, usage).Count);
 }