Пример #1
0
        public static bool IsNumerable(this SlotItemType type)
        {
            switch (type)
            {
            case SlotItemType.艦上偵察機:
            case SlotItemType.艦上偵察機_II:
            case SlotItemType.艦上戦闘機:
            case SlotItemType.艦上攻撃機:
            case SlotItemType.艦上爆撃機:
            case SlotItemType.水上偵察機:
            case SlotItemType.水上爆撃機:
            case SlotItemType.水上戦闘機:
            case SlotItemType.オートジャイロ:
            case SlotItemType.対潜哨戒機:
            case SlotItemType.大型飛行艇:
            case SlotItemType.陸上攻撃機:
            case SlotItemType.局地戦闘機:
            case SlotItemType.噴式戦闘機:
            case SlotItemType.噴式戦闘爆撃機:
            case SlotItemType.噴式攻撃機:
            case SlotItemType.噴式偵察機:
                return(true);

            default:
                return(false);
            }
        }
Пример #2
0
        private static double GetScore(SlotItemType type, int score)
        {
            switch (type)
            {
            case SlotItemType.艦上爆撃機:
                return(score * 0.62);

            case SlotItemType.艦上攻撃機:
                return(score * 0.81);

            case SlotItemType.艦上偵察機:
                return(score * 0.99);

            case SlotItemType.水上偵察機:
                return(score * 1.19);

            case SlotItemType.水上爆撃機:
                return(score * 1.06);

            case SlotItemType.小型電探:
                return(score * 0.6);

            case SlotItemType.大型電探:
                return(score * 0.59);

            case SlotItemType.探照灯:
                return(score * 0.54);
            }

            return(.0);
        }
Пример #3
0
        private static double GetScore(SlotItemType type, int score)
        {
            switch (type)
            {
            case SlotItemType.艦上爆撃機:
                return(score * 1.04);

            case SlotItemType.艦上攻撃機:
                return(score * 1.37);

            case SlotItemType.艦上偵察機:
                return(score * 1.66);

            case SlotItemType.水上偵察機:
                return(score * 2.00);

            case SlotItemType.水上爆撃機:
                return(score * 1.78);

            case SlotItemType.小型電探:
                return(score * 1.00);

            case SlotItemType.大型電探:
                return(score * .99);

            case SlotItemType.探照灯:
                return(score * 0.91);
            }

            return(.0);
        }
Пример #4
0
        /// <summary>
        /// Unserializes a BinaryStream into the Attributes of this Instance
        /// </summary>
        /// <param name="reader">The Stream that contains the FileData</param>
        internal void Unserialize(System.IO.BinaryReader reader)
        {
            type = (SlotItemType)reader.ReadUInt16();

            unknownf1 = reader.ReadSingle();
            unknownf2 = reader.ReadSingle();
            unknownf3 = reader.ReadSingle();

            unknowni1 = reader.ReadInt32();
            unknowni2 = reader.ReadInt32();
            unknowni3 = reader.ReadInt32();
            unknowni4 = reader.ReadInt32();
            unknowni5 = reader.ReadInt32();

            if (parent.Version >= 5)
            {
                unknownf4 = reader.ReadSingle();
                unknownf5 = reader.ReadSingle();
                unknownf6 = reader.ReadSingle();

                unknowni6 = reader.ReadInt32();
            }

            if (parent.Version >= 6)
            {
                unknowns1 = reader.ReadInt16();
                unknowns2 = reader.ReadInt16();
            }

            if (parent.Version >= 7)
            {
                unknownf7 = reader.ReadSingle();
            }
            if (parent.Version >= 8)
            {
                unknowni7 = reader.ReadInt32();
            }
            if (parent.Version >= 9)
            {
                unknowni8 = reader.ReadInt32();
            }
            if (parent.Version >= 0x10)
            {
                unknownf8 = reader.ReadSingle();
            }

            if (parent.Version >= 0x40)
            {
                unknowni9  = reader.ReadInt32();
                unknowni10 = reader.ReadInt32();
            }
        }
Пример #5
0
        private static double GetLevelCoefficient(SlotItemType type, int Level)
        {
            switch (type)
            {
            case SlotItemType.水上偵察機:
                return(Math.Sqrt(Level) * 1.2);

            case SlotItemType.小型電探:
            case SlotItemType.大型電探:
            case SlotItemType.大型電探_II:
                return(Math.Sqrt(Level) * 1.25);

            default:
                return(0);
            }
        }
Пример #6
0
        /// <summary>
        /// 合計対潜値のチェック
        /// </summary>
        /// <param name="index">The index.</param>
        /// <returns></returns>
        private bool SumASWCheck(Fleet fleet)
        {
            if (null == SumASW)
            {
                return(true);
            }

            var not_types = new SlotItemType[] { SlotItemType.水上偵察機, SlotItemType.水上爆撃機, SlotItemType.大型飛行艇 };

            //水偵・水爆・飛行艇の対潜値の合計を取得
            var not_sum_asw = fleet.Ships.Select(
                ship => ship.EquippedItems.Where(item => not_types.Any(t => t == item.Item.Info.Type) //水偵・水爆・飛行艇の絞込み
                                                 ).Sum(s => s.Item.Info.ASW)).Sum();                  //対潜値の合計

            //すべての装備込み対潜値の合計を取得
            var sum_asw = fleet.Ships.Select(s => s.ASW).Sum();

            //水偵・水爆・飛行艇の対潜値を無効にする
            return(sum_asw - not_sum_asw >= SumASW);
        }
Пример #7
0
        private static double GetTypeCoefficient(SlotItemType type)
        {
            switch (type)
            {
            case SlotItemType.艦上戦闘機:
            case SlotItemType.艦上爆撃機:
            case SlotItemType.小型電探:
            case SlotItemType.大型電探:
            case SlotItemType.対潜哨戒機:
            case SlotItemType.探照灯:
            case SlotItemType.司令部施設:
            case SlotItemType.航空要員:
            case SlotItemType.水上艦要員:
            case SlotItemType.大型ソナー:
            case SlotItemType.大型飛行艇:
            case SlotItemType.大型探照灯:
            case SlotItemType.水上戦闘機:
            case SlotItemType.噴式戦闘機:                     // 未実装なのでテキトー
            case SlotItemType.噴式戦闘爆撃機:
                return(0.6);

            case SlotItemType.艦上攻撃機:
            case SlotItemType.噴式攻撃機:                     // 未実装なのでテキトー
                return(0.8);

            case SlotItemType.艦上偵察機:
            case SlotItemType.艦上偵察機_II:
                return(1.0);

            case SlotItemType.水上爆撃機:
                return(1.1);

            case SlotItemType.水上偵察機:
            case SlotItemType.噴式偵察機:                     // 未実装なのでテキトー
                return(1.2);

            default:
                return(.0);
            }
        }
Пример #8
0
        private static AirSuperiorityCalculator GetCalculator(this SlotItemType type)
        {
            switch (type)
            {
            case SlotItemType.艦上戦闘機:
            case SlotItemType.水上戦闘機:
            case SlotItemType.噴式戦闘機:
                return(new FighterCalculator());

            case SlotItemType.艦上攻撃機:
            case SlotItemType.艦上爆撃機:
            case SlotItemType.噴式攻撃機:
            case SlotItemType.噴式戦闘爆撃機:
                // case SlotItemType.噴式偵察機: ??
                return(new AttackerCalculator());

            case SlotItemType.水上爆撃機:
                return(new SeaplaneBomberCalculator());

            default:
                return(EmptyCalculator.Instance);
            }
        }
Пример #9
0
		private static double GetScore(SlotItemType type, int score)
		{
			switch (type)
			{
				case SlotItemType.艦上爆撃機:
					return score * 1.04;
				case SlotItemType.艦上攻撃機:
					return score * 1.37;
				case SlotItemType.艦上偵察機:
					return score * 1.66;

				case SlotItemType.水上偵察機:
					return score * 2.00;
				case SlotItemType.水上爆撃機:
					return score * 1.78;

				case SlotItemType.小型電探:
					return score * 1.00;
				case SlotItemType.大型電探:
					return score * .99;

				case SlotItemType.探照灯:
					return score * 0.91;
			}

			return .0;
		}
Пример #10
0
        public static string GetName(this SlotItemType type)
        {
            switch (type)
            {
            case SlotItemType.None:
                return("없음");

            case SlotItemType.小口径主砲:
                return("소구경주포");

            case SlotItemType.中口径主砲:
                return("중구경주포");

            case SlotItemType.大口径主砲:
                return("대구경주포");

            case SlotItemType.副砲:
                return("부포");

            case SlotItemType.魚雷:
                return("어뢰");

            case SlotItemType.艦上戦闘機:
                return("함상전투기");

            case SlotItemType.艦上爆撃機:
                return("함상폭격기");

            case SlotItemType.艦上攻撃機:
                return("함상공격기");

            case SlotItemType.艦上偵察機:
                return("함상정찰기");

            case SlotItemType.水上偵察機:
                return("수상정찰기");

            case SlotItemType.水上爆撃機:
                return("수상폭격기");

            case SlotItemType.小型電探:
                return("소형전탐");

            case SlotItemType.大型電探:
                return("대형전탐");

            case SlotItemType.ソナー:
                return("소나");

            case SlotItemType.爆雷:
                return("폭뢰");

            case SlotItemType.追加装甲:
                return("추가장갑");

            case SlotItemType.機関部強化:
                return("기관부강화");

            case SlotItemType.対空強化弾:
                return("대공강화탄");

            case SlotItemType.対艦強化弾:
                return("대함강화탄");

            case SlotItemType.VT信管:
                return("VT신관");

            case SlotItemType.対空機銃:
                return("대공기관총");

            case SlotItemType.特殊潜航艇:
                return("특수잠항정");

            case SlotItemType.応急修理要員:
                return("응급수리요원");

            case SlotItemType.陸用舟艇:
                return("상륙용주정");

            case SlotItemType.オートジャイロ:
                return("오토자이로");

            case SlotItemType.対潜哨戒機:
                return("대잠초계기");

            case SlotItemType.追加装甲_中型:
                return("추가장갑 (중형)");

            case SlotItemType.追加装甲_大型:
                return("추가장갑 (대형)");

            case SlotItemType.探照灯:
                return("탐조등");

            case SlotItemType.簡易輸送部材:
                return("간이운송자재");

            case SlotItemType.艦艇修理施設:
                return("함정수리시설");

            case SlotItemType.潜水艦魚雷:
                return("잠수함어뢰");

            case SlotItemType.照明弾:
                return("조명탄");

            case SlotItemType.司令部施設:
                return("사령부시설");

            case SlotItemType.航空要員:
                return("항공요원");

            case SlotItemType.高射装置:
                return("고사장치");

            case SlotItemType.対地装備:
                return("대지상장비");

            case SlotItemType.大口径主砲_II:
                return("대구경주포 2");

            case SlotItemType.水上艦要員:
                return("숙련견시원");

            case SlotItemType.大型ソナー:
                return("대형소나");

            case SlotItemType.大型飛行艇:
                return("대형비행정");

            case SlotItemType.大型探照灯:
                return("대형탐조등");

            case SlotItemType.戦闘糧食:
                return("전투식량");

            case SlotItemType.補給物資:
                return("보급물자");

            case SlotItemType.水上戦闘機:
                return("수상전투기");

            case SlotItemType.特型内火艇:
                return("특형내화정");

            case SlotItemType.陸上攻撃機:
                return("육상공격기");

            case SlotItemType.局地戦闘機:
                return("국지전투기");

            case SlotItemType.輸送機材:
                return("운송자재");

            case SlotItemType.潜水艦装備:
                return("잠수함장비");

            case SlotItemType.噴式戦闘機:
                return("분식 전투기");

            case SlotItemType.噴式戦闘爆撃機:
                return("분식 전투폭격기");

            case SlotItemType.噴式攻撃機:
                return("분식 공격기");

            case SlotItemType.噴式偵察機:
                return("분식 정찰기");

            case SlotItemType.大型電探_II:
                return("대형전탐 2");

            case SlotItemType.艦上偵察機_II:
                return("함상정찰기 2");

            default:
                return(type.ToString());
            }
        }
Пример #11
0
        private static double GetTypeCoefficient(SlotItemType type)
        {
            switch (type)
            {
                case SlotItemType.艦上戦闘機:
                case SlotItemType.艦上爆撃機:
                case SlotItemType.小型電探:
                case SlotItemType.大型電探:
                case SlotItemType.対潜哨戒機:
                case SlotItemType.探照灯:
                case SlotItemType.司令部施設:
                case SlotItemType.航空要員:
                case SlotItemType.水上艦要員:
                case SlotItemType.大型ソナー:
                case SlotItemType.大型飛行艇:
                case SlotItemType.大型探照灯:
                case SlotItemType.水上戦闘機:
                    return 0.6;

                case SlotItemType.艦上攻撃機:
                    return 0.8;

                case SlotItemType.艦上偵察機:
                case SlotItemType.艦上偵察機_II:
                    return 1.0;

                case SlotItemType.水上爆撃機:
                    return 1.1;

                case SlotItemType.水上偵察機:
                    return 1.2;

                default:
                    return .0;
            }
        }
Пример #12
0
        private void CalculateLandBased()
        {
            Dictionary <int, int[]> distanceBonus = new Dictionary <int, int[]>()
            {
                { 138, new int[] { 3, 3, 3, 3, 3, 3, 3, 3 } },                 // 이식대정
                { 178, new int[] { 3, 3, 2, 2, 2, 2, 1, 1 } },                 // 카탈리나
                { 151, new int[] { 2, 2, 2, 2, 1, 1, 0, 0 } },                 // 시제케이운
                { 54, new int[] { 2, 2, 2, 2, 1, 1, 0, 0 } },                  // 사이운
                { 25, new int[] { 2, 2, 2, 1, 1, 0, 0, 0 } },                  // 영식수상정찰기
                { 59, new int[] { 2, 2, 2, 1, 1, 0, 0, 0 } },                  // 영식수상관측기
                { 61, new int[] { 2, 1, 1, 0, 0, 0, 0, 0 } },                  // 2식함상정찰기
            };
            Dictionary <int, Proficiency> proficiencies = new Dictionary <int, Proficiency>()
            {
                { 0, new Proficiency(0, 9, 0, 0) },
                { 1, new Proficiency(10, 24, 0, 1) },
                { 2, new Proficiency(25, 39, 2, 2) },
                { 3, new Proficiency(40, 54, 5, 3) },
                { 4, new Proficiency(55, 69, 9, 4) },
                { 5, new Proficiency(70, 84, 14, 5) },
                { 6, new Proficiency(85, 99, 14, 7) },
                { 7, new Proficiency(100, 120, 22, 9) },
            };
            var def = AirSuperiorityCalculationOptions.Default;

            var items = this.Planes
                        .Where(x => (x?.MaximumCount ?? 0) > 0)
                        .Select(x => x.Source);

            AttackPower             = 0;
            AirSuperiorityPotential = 0;
            if (items.Count() == 0)
            {
                return;
            }

            #region Attack Power calculating
            var attackers = new SlotItemType[]
            {
                SlotItemType.艦上攻撃機,
                SlotItemType.艦上爆撃機,
                SlotItemType.噴式攻撃機,
                SlotItemType.噴式戦闘爆撃機,
                SlotItemType.陸上攻撃機,
                SlotItemType.水上爆撃機
            };
            var power_sum = items
                            .Where(x => attackers.Contains(x.Info.Type))
                            .Sum(item =>
            {
                var proficiency = proficiencies[item.Proficiency];
                double damage   = 0;

                if (item.Info.Type == SlotItemType.陸上攻撃機)
                {
                    damage  = (item.Info.Torpedo + item.Info.Bomb) / 2;        // P
                    damage *= Math.Sqrt(1.8 * 18);                             // root 1.8N
                    damage += 25;
                    damage  = Math.Floor(damage * 0.8);
                    // Critical modifier skip
                    // Contact multiplier skip
                }
                else
                {
                    damage  = (item.Info.Torpedo + item.Info.Bomb) / 2;        // P
                    damage *= Math.Sqrt(1.8 * 18);                             // root 1.8N
                    damage += 25;
                    damage  = Math.Floor(damage * 0.8);
                    // Critical modifier skip
                    // Contact multiplier skip
                    damage *= 1.8;
                }
                return(damage);
            });
            #endregion

            #region Bonus rate calculate when Air Defence Mode
            var bonusRate = 1.0;
            if (this.ActionKind == AirBaseAction.방공)
            {
                if (items.Any(x => x.Info.Type == SlotItemType.艦上偵察機))
                {
                    var viewrange = items
                                    .Where(x => x.Info.Type == SlotItemType.艦上偵察機)
                                    .Max(x => x.Info.ViewRange);

                    if (viewrange <= 7)
                    {
                        bonusRate = 1.2;
                    }
                    else if (viewrange == 8)
                    {
                        bonusRate = 1.25;                         // Maybe?
                    }
                    else
                    {
                        bonusRate = 1.3;
                    }
                }
                else if (items.Any(x => x.Info.Type == SlotItemType.水上偵察機))
                {
                    var viewrange = items
                                    .Where(x => x.Info.Type == SlotItemType.水上偵察機)
                                    .Max(x => x.Info.ViewRange);

                    if (viewrange <= 7)
                    {
                        bonusRate = 1.1;
                    }
                    else if (viewrange == 8)
                    {
                        bonusRate = 1.13;
                    }
                    else
                    {
                        bonusRate = 1.16;
                    }
                }
            }
            #endregion
            #region AA calculating
            var air_sum = items.Sum(item =>
            {
                var proficiency = proficiencies[item.Proficiency];
                double aa       = item.Info.AA;
                double bonus    = 0;

                switch (item.Info.Type)
                {
                // 전투기
                case SlotItemType.艦上戦闘機:
                case SlotItemType.水上戦闘機:
                case SlotItemType.噴式戦闘機:
                case SlotItemType.局地戦闘機:
                    aa   += item.Level * 0.2;
                    bonus = Math.Sqrt(proficiency.GetInternalValue(def) / 10.0)
                            + proficiency.FighterBonus;
                    break;

                // 공격기 (뇌격기, 폭격기)
                case SlotItemType.艦上攻撃機:
                case SlotItemType.艦上爆撃機:
                case SlotItemType.噴式攻撃機:
                case SlotItemType.噴式戦闘爆撃機:
                case SlotItemType.陸上攻撃機:
                    bonus = Math.Sqrt(proficiency.GetInternalValue(def) / 10.0)
                            + 0;
                    break;

                // 수상폭격기
                case SlotItemType.水上爆撃機:
                    bonus = Math.Sqrt(proficiency.GetInternalValue(def) / 10.0)
                            + proficiency.SeaplaneBomberBonus;
                    break;

                // 정찰기, 수상정찰기, (분식정찰기?)
                // 본래는 제공치에 포함되지 않으나 기항대에는 포함되는 듯
                // 다만 기지항공대 공격을 방공할 때에만 출격하는 듯함. 일단은 주석처리
                default:
                    /*
                     * bonus = Math.Sqrt(proficiency.GetInternalValue(def) / 10.0)
                     + 0;
                     */
                    break;
                }
                bonus = Math.Min(22, bonus) + Math.Sqrt(12);

                switch (this.ActionKind)
                {
                case AirBaseAction.방공:
                    if (item.Info.Type == SlotItemType.局地戦闘機)
                    {
                        aa += item.Info.Hit * 2 + item.Info.Evade;
                    }
                    break;

                default:                         // 출격 등
                    if (item.Info.Type == SlotItemType.局地戦闘機)
                    {
                        aa += (int)(item.Info.Evade * 1.5);
                    }
                    break;
                }
                return(Math.Floor(Math.Sqrt(18) * aa) * bonusRate + Math.Floor(bonus));
            });
            #endregion

            this.AttackPower             = power_sum;
            this.AirSuperiorityPotential = air_sum;
        }
Пример #13
0
        public static string GetASWTooltip(Ship ship)
        {
            //  4식 소나 대잠 12
            //  0식 소나 대잠 11
            //  3식 소나 대잠 10
            //  3식 폭뢰 대잠  8
            //  2식 폭뢰 대잠  7
            // 93식 소나 대잠  6
            // 94식 폭뢰 대잠  5
            // 95식 폭뢰 대잠  4

            // 선제 대잠에는 소나 장착이 필수

            List <string> output = new List <string>();
            var           master = KanColleClient.Current.Master;

            // 선제 대잠에 필요한 대잠 수치
            var goal_asw = ship.Info.ShipType.Id == 1 ? 60
                                : ship.Info.ShipType.Id == 7 && ship.Speed == ShipSpeed.Slow ? 65
                                : 100;

            // 필요한 장비 대잠 수치
            var require_asw = Math.Max(0, goal_asw - ship.ASW.Current);

            IEnumerable <SlotItemInfo> available_equips;
            List <SlotItemType>        available_equip_types = new List <SlotItemType>();

            SlotItemType[] require_type = new SlotItemType[0];

            #region 장착 가능 & 대잠 공격 필수 장비 체크
            switch (ship.Info.ShipType.Id)
            {
            case 1:                                          // 해방함
            case 2:                                          // 구축함
            case 3:                                          // 경순양함
            case 4:                                          // 중뢰장순양함
            case 21:                                         // 연습순양함
                available_equip_types.Add(SlotItemType.ソナー); // 소나
                available_equip_types.Add(SlotItemType.爆雷);  // 폭뢰

                require_type = new SlotItemType[] { SlotItemType.ソナー };
                break;

            case 6:                                              // 항공순양함
            case 10:                                             // 항공전함
                available_equip_types.Add(SlotItemType.水上爆撃機);   // 수상폭격기
                available_equip_types.Add(SlotItemType.大型ソナー);   // 대형소나
                available_equip_types.Add(SlotItemType.オートジャイロ); // 오토자이로

                require_type = new SlotItemType[] { SlotItemType.水上爆撃機 };
                break;

            case 16:                                           // 수상기모함
                available_equip_types.Add(SlotItemType.水上爆撃機); // 수상폭격기
                available_equip_types.Add(SlotItemType.大型ソナー); // 대형소나

                if (ship.Info.Id == 450 ||                      // 까모改
                    ship.Info.Id == 491 ||                             // 코망단
                    ship.Info.Id == 372)                                // 코망단改
                {
                    available_equip_types.Add(SlotItemType.ソナー);        // 소나
                }
                if (ship.Info.Id != 491 &&                      // 코망단
                    ship.Info.Id != 372)                                // 코망단改
                {
                    available_equip_types.Add(SlotItemType.爆雷);         // 폭뢰
                }
                if (ship.Info.Id == 491 ||                      // 코망단
                    ship.Info.Id == 372)                                // 코망단改
                {
                    available_equip_types.Add(SlotItemType.オートジャイロ);    // 오토자이로
                }
                require_type = new SlotItemType[] { SlotItemType.水上爆撃機, SlotItemType.オートジャイロ };
                break;

            case 7:                                                  // 경공모
                available_equip_types.Add(SlotItemType.艦上爆撃機);       // 함상폭격기

                if (ship.Info.Id != 521)                             // 카스가마루
                {
                    available_equip_types.Add(SlotItemType.艦上攻撃機);   // 함상공격기

                    available_equip_types.Add(SlotItemType.オートジャイロ); // 오토자이로
                    available_equip_types.Add(SlotItemType.対潜哨戒機);   // 대잠초계기
                }

                available_equip_types.Add(SlotItemType.大型ソナー);          // 대형소나
                if (ship.Info.Id == 380 ||                      // 타이요改
                    ship.Info.Id == 529)                                // 타이요改2
                {
                    available_equip_types.Add(SlotItemType.ソナー);        // 소나
                    available_equip_types.Add(SlotItemType.爆雷);         // 폭뢰
                }

                require_type = new SlotItemType[] { SlotItemType.艦上爆撃機, SlotItemType.艦上攻撃機 };
                break;

            case 22:                                               // 보급함
                if (ship.Info.Id == 352)                           // 하야스이改
                {
                    available_equip_types.Add(SlotItemType.艦上攻撃機); // 함상공격기
                    available_equip_types.Add(SlotItemType.ソナー);   // 소나
                }
                available_equip_types.Add(SlotItemType.オートジャイロ);   // 오토자이로

                require_type = new SlotItemType[] { SlotItemType.艦上攻撃機, SlotItemType.オートジャイロ };
                break;

            case 17:                                             // 양륙함
                available_equip_types.Add(SlotItemType.大型ソナー);   // 대형소나
                available_equip_types.Add(SlotItemType.オートジャイロ); // 오토자이로
                available_equip_types.Add(SlotItemType.対潜哨戒機);   // 대잠초계기

                require_type = new SlotItemType[] { SlotItemType.オートジャイロ, SlotItemType.対潜哨戒機 };
                break;
            }
            #endregion

            // 산출된 목록에서 실제 장비를 가져옴
            available_equips = master.SlotItems
                               .Where(x => x.Value.Id <= 500)  // 501 부터는 심해서함 장비
                               .Where(x => available_equip_types.Contains(x.Value.Type))
                               .Select(x => x.Value)
                               .ToArray();
            require_type = require_type
                           .Where(x => available_equip_types.Contains(x))
                           .ToArray();

            // 장착 가능 장비가 없는 경우 혹은 필수 장비가 항공기인데 탑재량이 없는 경우
            if (available_equips.Count() == 0 || require_type.Count() == 0 ||
                (require_type.All(x => x.IsNumerable()) && ship.Info.Slots.All(x => x == 0)))
            {
                output.Add("선제 대잠 불가능");
                output.Add("- 대잠 공격 불가능");
            }
            else if (ship.Info.Id == 141)             // 이스즈
            {
                output.Add("선제 대잠 가능");
                output.Add("- 대잠 공격 필수 장비:");
                for (var i = 0; i < require_type.Length; i++)
                {
                    output.Add($"  * {require_type[i].GetName()}");
                }

                goal_asw = require_asw = 0;
            }
            else
            {
                // 대잠 낮은 장비순으로 (높은 순서지만 Stack 에서 Pop 되므로 거꾸로 해야한다)
                var sorted_items = available_equips
                                   .OrderByDescending(x => x.ASW)
                                   .ToArray();

                // 장착 가능한 슬롯 수 만큼
                Stack <SlotItemInfo>[] available_items = new Stack <SlotItemInfo> [ship.Info.SlotCount];
                for (var i = 1; i < ship.Info.SlotCount; i++)
                {
                    available_items[i] = new Stack <SlotItemInfo>(sorted_items);
                }

                // 1슬롯은 필수 장비를
                available_items[0] = new Stack <SlotItemInfo>(
                    available_equips
                    .Where(x => require_type.Contains(x.Type))
                    .OrderByDescending(x => x.ASW)
                    );

                // 가능한 최소 장비 세트를 찾기
                var last_asw = 0;
                while (available_items[0].Count > 0)
                {
                    var cur_asw = available_items.Sum(x => x.Peek().ASW);
                    last_asw = cur_asw;

                    if (cur_asw >= require_asw)
                    {
                        output.Add("선제 대잠 가능");
                        output.Add("- 대잠 공격 필수 장비:");
                        for (var i = 0; i < require_type.Length; i++)
                        {
                            output.Add($"  * {require_type[i].GetName()}");
                        }

                        output.Add("- 최소 장비:");
                        for (var i = 0; i < available_items.Length; i++)
                        {
                            output.Add($"  * {available_items[i].Peek().Name}");
                        }

                        break;
                    }
                    else
                    {
                        for (var i = available_items.Length - 1; i >= 0; i--)
                        {
                            available_items[i].Pop();

                            if (available_items[i].Count == 0 && i != 0)
                            {
                                available_items[i] = new Stack <SlotItemInfo>(sorted_items);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }

                // 찾지 못한 경우
                if (available_items[0].Count == 0)
                {
                    output.Add("선제 대잠 불가능");
                    output.Add("- 대잠 공격 필수 장비:");
                    for (var i = 0; i < require_type.Length; i++)
                    {
                        output.Add($"  * {require_type[i].GetName()}");
                    }
                    output.Add("- 대잠 수치 부족");
                    output.Add($"- 함선 대잠 수치 {require_asw - last_asw} 증가 필요");
                }
            }

            output.Add("");
            output.Add("선제 대잠에 필요한 대잠 수치");
            output.Add(" - 필요 대잠 수치");
            output.Add($"  * {goal_asw}");
            output.Add(" - 필요 장비 대잠 수치 합계");
            output.Add($"  * {require_asw}");

            return(string.Join(Environment.NewLine, output.ToArray()));
        }
Пример #14
0
        private static double GetScore(SlotItemType type, int score)
        {
            switch (type)
            {
                case SlotItemType.艦上爆撃機:
                    return score * 0.62;
                case SlotItemType.艦上攻撃機:
                    return score * 0.81;
                case SlotItemType.艦上偵察機:
                    return score * 0.99;

                case SlotItemType.水上偵察機:
                    return score * 1.19;
                case SlotItemType.水上爆撃機:
                    return score * 1.06;

                case SlotItemType.小型電探:
                    return score * 0.6;
                case SlotItemType.大型電探:
                    return score * 0.59;

                case SlotItemType.探照灯:
                    return score * 0.54;
            }

            return .0;
        }