OSDN Git Service

基地航空隊の制空値の出撃と防空を同時に計算する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Sat, 19 Jan 2019 06:55:24 +0000 (15:55 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Sat, 19 Jan 2019 07:36:21 +0000 (16:36 +0900)
KancolleSniffer.Test/SnifferTest.cs
KancolleSniffer.Test/logs
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/Model/AirBaseParams.cs [new file with mode: 0644]
KancolleSniffer/Model/BaseAirCoprs.cs
KancolleSniffer/Model/ItemSpec.cs
KancolleSniffer/Model/ItemStatus.cs
KancolleSniffer/View/FleetPanel.cs

index fa10960..78fad62 100644 (file)
@@ -113,9 +113,9 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "baseaircorps_001");\r
-            PAssert.That(() => sniffer.BaseAirCorps[0].AirCorps[0].FighterPower.AirCombat[1] == 301);\r
+            PAssert.That(() => (int)sniffer.BaseAirCorps[0].AirCorps[0].CalcFighterPower()[1].AirCombat == 301);\r
             sniffer.BaseAirCorps[0].AirCorps[0].Action = 2; // 防空\r
-            PAssert.That(() => sniffer.BaseAirCorps[0].AirCorps[0].FighterPower.Interception[1] == 320);\r
+            PAssert.That(() => (int)sniffer.BaseAirCorps[0].AirCorps[0].CalcFighterPower()[1].Interception == 320);\r
         }\r
 \r
         /// <summary>\r
@@ -126,7 +126,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "baseaircorps_002");\r
-            PAssert.That(() => sniffer.BaseAirCorps[0].AirCorps[2].FighterPower.Interception[0] == 353);\r
+            PAssert.That(() => (int)sniffer.BaseAirCorps[0].AirCorps[2].CalcFighterPower()[0].Interception == 353);\r
         }\r
 \r
         /// <summary>\r
@@ -137,7 +137,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "baseaircorps_003");\r
-            PAssert.That(() => sniffer.BaseAirCorps[1].AirCorps[0].FighterPower.AirCombat[0] == 121);\r
+            PAssert.That(() => (int)sniffer.BaseAirCorps[1].AirCorps[0].CalcFighterPower()[0].AirCombat == 121);\r
         }\r
 \r
         /// <summary>\r
@@ -159,7 +159,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "baseaircorps_004");\r
-            PAssert.That(() => sniffer.BaseAirCorps[1].AirCorps[0].FighterPower.AirCombat[0] == 328);\r
+            PAssert.That(() => (int)sniffer.BaseAirCorps[1].AirCorps[0].CalcFighterPower()[0].AirCombat == 328);\r
         }\r
 \r
         /// <summary>\r
index aa434af..661a3e8 160000 (submodule)
@@ -1 +1 @@
-Subproject commit aa434af1e9da0eca2ae43ad6820fe7e72930be5f
+Subproject commit 661a3e809ab78022829a3541285c86e3f1b0de6a
index f0d9b86..30fedb7 100644 (file)
@@ -54,6 +54,7 @@
     <Reference Include="System.Xml" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <Compile Include="Model\AirBaseParams.cs" />\r
     <Compile Include="Model\QuestCountList.cs" />\r
     <Compile Include="Privacy.cs" />\r
     <Compile Include="Log\LogProcessor.cs" />\r
diff --git a/KancolleSniffer/Model/AirBaseParams.cs b/KancolleSniffer/Model/AirBaseParams.cs
new file mode 100644 (file)
index 0000000..2b8d3a7
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright (C) 2019 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//    http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+using System;\r
+\r
+namespace KancolleSniffer.Model\r
+{\r
+    public struct AirBaseParams\r
+    {\r
+        public double AirCombat { get; }\r
+        public double Interception { get; }\r
+\r
+        public AirBaseParams(double airCombat, double interception)\r
+        {\r
+            AirCombat = airCombat;\r
+            Interception = interception;\r
+        }\r
+\r
+        public static AirBaseParams Max(AirBaseParams value1, AirBaseParams value2)\r
+        {\r
+            return new AirBaseParams(Math.Max(value1.AirCombat, value2.AirCombat),\r
+                Math.Max(value1.Interception, value2.Interception));\r
+        }\r
+\r
+        public static AirBaseParams operator +(AirBaseParams lhs, AirBaseParams rhs)\r
+        {\r
+            return new AirBaseParams(lhs.AirCombat + rhs.AirCombat, lhs.Interception + rhs.Interception);\r
+        }\r
+\r
+        public static AirBaseParams operator +(AirBaseParams lhs, double rhs)\r
+        {\r
+            return new AirBaseParams(lhs.AirCombat + rhs, lhs.Interception + rhs);\r
+        }\r
+\r
+        public static AirBaseParams operator *(AirBaseParams lhs, AirBaseParams rhs)\r
+        {\r
+            return new AirBaseParams(lhs.AirCombat * rhs.AirCombat, lhs.Interception * rhs.Interception);\r
+        }\r
+\r
+        public static AirBaseParams operator *(AirBaseParams lhs, double rhs)\r
+        {\r
+            return new AirBaseParams(lhs.AirCombat * rhs, lhs.Interception * rhs);\r
+        }\r
+\r
+        public AirBaseParams Floor()\r
+        {\r
+            return new AirBaseParams((int)AirCombat, (int)Interception);\r
+        }\r
+    }\r
+}
\ No newline at end of file
index c612dac..05e441f 100644 (file)
@@ -39,13 +39,6 @@ namespace KancolleSniffer.Model
             public AirCorpsInfo[] AirCorps { get; set; }\r
         }\r
 \r
-        public class FighterPower\r
-        {\r
-            public int[] AirCombat { get; set; }\r
-            public int[] Interception { get; set; }\r
-            public bool IsInterceptor => AirCombat[0] != Interception[0];\r
-        }\r
-\r
         public class Distance\r
         {\r
             public int Base { get; set; }\r
@@ -82,21 +75,24 @@ namespace KancolleSniffer.Model
                 }\r
             }\r
 \r
-            public FighterPower FighterPower =>\r
-                new FighterPower {AirCombat = CalcFighterPower(false), Interception = CalcFighterPower(true)};\r
-\r
-            private int[] CalcFighterPower(bool interception)\r
+            public AirBaseParams[] CalcFighterPower()\r
             {\r
-                var reconPlaneBonus = interception\r
-                    ? Planes.Max(plane => plane.Slot.Spec.ReconPlaneInterceptionBonus)\r
-                    : 1.0;\r
-                return Planes.Aggregate(new[] {0, 0}, (prev, plane) =>\r
+                var reconPlaneBonus = Planes.Aggregate(new AirBaseParams(), (max, plane) =>\r
+                {\r
+                    var bonus = plane.Slot.Spec.ReconPlaneAirBaseBonus;\r
+                    return AirBaseParams.Max(max, bonus);\r
+                });\r
+                return Planes.Aggregate(new[] {new AirBaseParams(), new AirBaseParams()}, (previous, plane) =>\r
                 {\r
                     if (plane.State != 1)\r
-                        return prev;\r
-                    var cur = plane.Slot.CalcFighterPowerInBase(plane.Count, interception);\r
-                    return new[] {prev[0] + cur[0], prev[1] + cur[1]};\r
-                }).Select(fp => (int)(fp * reconPlaneBonus)).ToArray();\r
+                        return previous;\r
+                    var current = plane.Slot.CalcFighterPowerInBase(plane.Count);\r
+                    return new[]\r
+                    {\r
+                        previous[0] + current[0],\r
+                        previous[1] + current[1]\r
+                    };\r
+                }).Select(param => (param * reconPlaneBonus).Floor()).ToArray();\r
             }\r
 \r
             public int[] CostForSortie => Planes.Aggregate(new[] {0, 0}, (prev, plane) =>\r
@@ -143,29 +139,26 @@ namespace KancolleSniffer.Model
                 }\r
             }\r
 \r
-            public FighterPower FighterPower\r
-                => new FighterPower{AirCombat = CalcFighterPower(false), Interception = CalcFighterPower(true)};\r
-\r
-            private int[] CalcFighterPower(bool interception) => Slot.CalcFighterPowerInBase(Count, interception);\r
+            public AirBaseParams[] FighterPower => Slot.CalcFighterPowerInBase(Count);\r
         }\r
 \r
         public void Inspect(dynamic json)\r
         {\r
             AllAirCorps = (from entry in (dynamic[])json\r
                 group\r
-                new AirCorpsInfo\r
-                {\r
-                    Distance = CreateDistance(entry.api_distance),\r
-                    Action = (int)entry.api_action_kind,\r
-                    Planes = (from plane in (dynamic[])entry.api_plane_info\r
-                        select new PlaneInfo\r
-                        {\r
-                            Slot = _itemInfo.GetStatus((int)plane.api_slotid),\r
-                            State = (int)plane.api_state,\r
-                            Count = plane.api_count() ? (int)plane.api_count : 0,\r
-                            MaxCount = plane.api_max_count() ? (int)plane.api_max_count : 0,\r
-                        }).ToArray()\r
-                } by entry.api_area_id() ? (int)entry.api_area_id : 0\r
+                    new AirCorpsInfo\r
+                    {\r
+                        Distance = CreateDistance(entry.api_distance),\r
+                        Action = (int)entry.api_action_kind,\r
+                        Planes = (from plane in (dynamic[])entry.api_plane_info\r
+                            select new PlaneInfo\r
+                            {\r
+                                Slot = _itemInfo.GetStatus((int)plane.api_slotid),\r
+                                State = (int)plane.api_state,\r
+                                Count = plane.api_count() ? (int)plane.api_count : 0,\r
+                                MaxCount = plane.api_max_count() ? (int)plane.api_max_count : 0\r
+                            }).ToArray()\r
+                    } by entry.api_area_id() ? (int)entry.api_area_id : 0\r
                 into grp\r
                 select new BaseInfo {AreaId = grp.Key, AirCorps = grp.ToArray()}).ToArray();\r
         }\r
@@ -227,9 +220,8 @@ namespace KancolleSniffer.Model
             baseInfo.AirCorps = airCorps;\r
             airCorps[airCorps.Length - 1] = new AirCorpsInfo\r
             {\r
-                Planes =\r
-                    ((dynamic[])json[0].api_plane_info).\r
-                        Select(plane => new PlaneInfo {Slot = new ItemStatus()}).ToArray()\r
+                Planes = ((dynamic[])json[0].api_plane_info).Select(plane =>\r
+                    new PlaneInfo {Slot = new ItemStatus()}).ToArray()\r
             };\r
         }\r
 \r
index e071b7a..834625d 100644 (file)
@@ -134,7 +134,7 @@ namespace KancolleSniffer.Model
         public bool IsSonar => Type == 14 || // ソナー\r
                                Type == 40; // 大型ソナー\r
 \r
-        public bool IsDCT =>  // Depth Charge Thrower\r
+        public bool IsDCT => // Depth Charge Thrower\r
             Id == 44 || // 九四式爆雷投射機\r
             Id == 45; // 三式爆雷投射機\r
 \r
@@ -200,20 +200,20 @@ namespace KancolleSniffer.Model
             }\r
         }\r
 \r
-        public double ReconPlaneInterceptionBonus\r
+        public AirBaseParams ReconPlaneAirBaseBonus\r
         {\r
             get\r
             {\r
                 switch (Type)\r
                 {\r
                     case 9:\r
-                        return LoS <= 7 ? 1.2 : 1.3;\r
+                        return new AirBaseParams(1.0, LoS <= 7 ? 1.2 : 1.3);\r
                     case 10:\r
                     case 41:\r
-                        return LoS <= 7 ? 1.1 :\r
-                            LoS <= 8 ? 1.13 : 1.16;\r
+                        return new AirBaseParams(1.0, LoS <= 7 ? 1.1 :\r
+                            LoS <= 8 ? 1.13 : 1.16);\r
                 }\r
-                return 1;\r
+                return new AirBaseParams(1.0, 1.0);\r
             }\r
         }\r
 \r
index d8ce035..fbd15f5 100644 (file)
@@ -45,13 +45,13 @@ namespace KancolleSniffer.Model
             return AlvBonus.Select(bonus => (int)(unskilled + bonus)).ToArray();\r
         }\r
 \r
-        public int[] CalcFighterPowerInBase(int slot, bool airDefense)\r
+        public AirBaseParams[] CalcFighterPowerInBase(int slot)\r
         {\r
             if (!Spec.IsAircraft || slot == 0)\r
-                return new[] {0, 0};\r
-            var airDefenseBonus = airDefense ? Spec.AntiBomber * 2 + Spec.Interception : Spec.Interception * 1.5;\r
-            var unskilled = (Spec.AntiAir + airDefenseBonus + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
-            return AlvBonusInBase.Select(bonus => (int)(unskilled + bonus)).ToArray();\r
+                return new[] {new AirBaseParams(), new AirBaseParams()};\r
+            var baseFighterPower = (new AirBaseParams(Spec.Interception * 1.5, Spec.AntiBomber * 2 + Spec.Interception) +\r
+                                   Spec.AntiAir  + FighterPowerLevelBonus) * Math.Sqrt(slot);\r
+            return AlvBonusInBase.Select(bonus => (baseFighterPower + bonus).Floor()).ToArray();\r
         }\r
 \r
         private readonly double[] _alvBonusMin =\r
index 8ffa2e8..054799e 100644 (file)
@@ -193,18 +193,21 @@ namespace KancolleSniffer.View
                     {\r
                         if (i >= name.Length)\r
                             break;\r
-                        var corpsFp = airCorps.FighterPower;\r
+                        var corpsFp = airCorps.CalcFighterPower();\r
+                        var airCombat = new[] { (int)corpsFp[0].AirCombat, (int)corpsFp[1].AirCombat };\r
+                        var interception = new[] { (int)corpsFp[0].Interception, (int)corpsFp[1].Interception };\r
+                        var different = interception[0] != airCombat[0];\r
                         string spec;\r
                         string spec2;\r
                         if (airCorps.Action == 2)\r
                         {\r
-                            spec = "制空:" + RangeString(corpsFp.Interception);\r
-                            spec2 = corpsFp.IsInterceptor ? "制空(出撃):" + RangeString(corpsFp.AirCombat) : "";\r
+                            spec = "制空:" + RangeString(interception);\r
+                            spec2 = different ? "制空(出撃):" + RangeString(airCombat) : "";\r
                         }\r
                         else\r
                         {\r
-                            spec = "制空:" + RangeString(corpsFp.AirCombat);\r
-                            spec2 = corpsFp.IsInterceptor ? "制空(防空):" + RangeString(corpsFp.Interception) : "";\r
+                            spec = "制空:" + RangeString(airCombat);\r
+                            spec2 = different ? "制空(防空):" + RangeString(interception) : "";\r
                         }\r
                         var cost = airCorps.CostForSortie;\r
                         list.Add(new Record\r
@@ -217,13 +220,16 @@ namespace KancolleSniffer.View
                         list.AddRange(airCorps.Planes.Select(plane =>\r
                         {\r
                             var planeFp = plane.FighterPower;\r
+                            airCombat = new[] {(int)planeFp[0].AirCombat, (int)planeFp[1].AirCombat};\r
+                            interception = new[] {(int) planeFp[0].Interception, (int)planeFp[1].Interception };\r
+                            different = interception[0] != airCombat[0];\r
                             return new Record\r
                             {\r
                                 Equip = plane.State != 1 ? plane.StateName : GenEquipString(plane.Slot),\r
                                 Spec = plane.State != 1 ? "" : $"+{plane.Slot.Alv} {plane.Count}/{plane.MaxCount}",\r
                                 AircraftSpec =\r
-                                    $"距離:{plane.Slot.Spec.Distance} 制空:{RangeString(planeFp.AirCombat)}" +\r
-                                    (planeFp.IsInterceptor ? $" 防空:{RangeString(planeFp.Interception)}" : ""),\r
+                                    $"距離:{plane.Slot.Spec.Distance} 制空:{RangeString(airCombat)}" +\r
+                                    (different ? $" 防空:{RangeString(interception)}" : ""),\r
                                 Color = plane.Slot.Spec.Color\r
                             };\r
                         }));\r