OSDN Git Service

艦隊に関する責務をShipInfoからFleetクラスに移す
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 18 Jun 2018 13:50:29 +0000 (22:50 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 18 Jun 2018 14:15:58 +0000 (23:15 +0900)
14 files changed:
KancolleSniffer.Test/BattleTest.cs
KancolleSniffer.Test/SnifferTest.cs
KancolleSniffer/AntiAirPanel.cs
KancolleSniffer/BattleInfo.cs
KancolleSniffer/ConditionTimer.cs
KancolleSniffer/Fleet.cs [new file with mode: 0644]
KancolleSniffer/FleetPanel.cs
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/Logger.cs
KancolleSniffer/MainForm.cs
KancolleSniffer/MiscTextInfo.cs
KancolleSniffer/ShipInfo.cs
KancolleSniffer/Sniffer.cs
KancolleSniffer/TextGenerator.cs

index a778fbf..bb49456 100644 (file)
@@ -52,7 +52,7 @@ namespace KancolleSniffer.Test
             _battleInfo.InspectBattle(logs[0], logs[1], battle);\r
             dynamic result = JsonParser.Parse(logs[5]);\r
             _battleInfo.InspectBattleResult(result);\r
-            PAssert.That(() => _shipInfo.GetShipStatuses(2)[4].NowHp == 31);\r
+            PAssert.That(() => _shipInfo.Fleets[2].Ships[4].NowHp == 31);\r
         }\r
 \r
         /// <summary>\r
@@ -66,7 +66,7 @@ namespace KancolleSniffer.Test
             _shipInfo.InjectShips(battle, JsonParser.Parse(logs[0]));\r
             _battleInfo.InspectBattle(logs[1], logs[2], battle);\r
             _battleInfo.InspectBattleResult(JsonParser.Parse(logs[6]));\r
-            PAssert.That(() => _shipInfo.GetShipStatuses(0)[3].NowHp == 12);\r
+            PAssert.That(() => _shipInfo.Fleets[0].Ships[3].NowHp == 12);\r
         }\r
 \r
         private dynamic Data(string json) => ((dynamic)JsonParser.Parse(json)).api_data;\r
index 010259d..6dc2c61 100644 (file)
@@ -83,7 +83,7 @@ namespace KancolleSniffer.Test
         private void AssertEqualBattleResult(Sniffer sniffer, IEnumerable<int> expected, IEnumerable<int> enemy,\r
             string msg = null)\r
         {\r
-            var result = sniffer.GetShipStatuses(0).Select(s => s.NowHp);\r
+            var result = sniffer.Fleets[0].Ships.Select(s => s.NowHp);\r
             PAssert.That(() => expected.SequenceEqual(result), msg);\r
             var enemyResult = sniffer.Battle.Result.Enemy.Main.Select(s => s.NowHp);\r
             PAssert.That(() => enemy.SequenceEqual(enemyResult), msg);\r
@@ -186,8 +186,9 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "escape_001");\r
-            PAssert.That(() => sniffer.GetShipStatuses(0)[5].Escaped &&\r
-                               sniffer.GetShipStatuses(1)[2].Escaped);\r
+            var fleets = sniffer.Fleets;\r
+            PAssert.That(() => fleets[0].Ships[5].Escaped &&\r
+                               fleets[1].Ships[2].Escaped);\r
         }\r
 \r
         /// <summary>\r
@@ -220,7 +221,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "escape_002");\r
-            PAssert.That(() => sniffer.GetShipStatuses(2)[1].Escaped);\r
+            PAssert.That(() => sniffer.Fleets[2].Ships[1].Escaped);\r
             PAssert.That(() => !sniffer.IsBattleResultStatusError);\r
         }\r
 \r
@@ -254,9 +255,10 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "fighterpower_001");\r
-            PAssert.That(() => sniffer.GetFighterPower(0).SequenceEqual(new[] {156, 159}));\r
+            var fleet = sniffer.Fleets[0];\r
+            PAssert.That(() => fleet.FighterPower.SequenceEqual(new[] {156, 159}));\r
             SniffLogFile(sniffer, "fighterpower_002");\r
-            PAssert.That(() => sniffer.GetFighterPower(0).SequenceEqual(new[] {140, 143}), "全滅したスロットがある");\r
+            PAssert.That(() => fleet.FighterPower.SequenceEqual(new[] {140, 143}), "全滅したスロットがある");\r
         }\r
 \r
         /// <summary>\r
@@ -267,7 +269,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "fighterpower_003");\r
-            PAssert.That(() => sniffer.GetFighterPower(0).SequenceEqual(new[] {135, 135}));\r
+            PAssert.That(() => sniffer.Fleets[0].FighterPower.SequenceEqual(new[] {135, 135}));\r
         }\r
 \r
         /// <summary>\r
@@ -335,11 +337,12 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "lineofsight_001");\r
-            PAssert.That(() => Math.Abs(sniffer.GetFleetLineOfSights(0, 1) - 39.45) < 0.01);\r
-            PAssert.That(() => Math.Abs(sniffer.GetFleetLineOfSights(0, 3) - 115.19) < 0.01);\r
-            PAssert.That(() => Math.Abs(sniffer.GetFleetLineOfSights(0, 4) - 153.06) < 0.01);\r
+            var fleet = sniffer.Fleets[0];\r
+            PAssert.That(() => Math.Abs(fleet.GetLineOfSights(1) - 39.45) < 0.01);\r
+            PAssert.That(() => Math.Abs(fleet.GetLineOfSights(3) - 115.19) < 0.01);\r
+            PAssert.That(() => Math.Abs(fleet.GetLineOfSights(4) - 153.06) < 0.01);\r
             SniffLogFile(sniffer, "lineofsight_002");\r
-            PAssert.That(() => Math.Abs(sniffer.GetFleetLineOfSights(0, 1) - -25.10) < 0.01, "艦隊に空きがある");\r
+            PAssert.That(() => Math.Abs(fleet.GetLineOfSights(1) - -25.10) < 0.01, "艦隊に空きがある");\r
         }\r
 \r
         /// <summary>\r
@@ -350,7 +353,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "contact_001");\r
-            PAssert.That(() => Math.Abs(sniffer.GetContactTriggerRate(0) - 1.8182) < 0.0001);\r
+            PAssert.That(() => Math.Abs(sniffer.Fleets[0].ContactTriggerRate - 1.8182) < 0.0001);\r
         }\r
 \r
         /// <summary>\r
@@ -368,7 +371,7 @@ namespace KancolleSniffer.Test
                 var sniffer = new Sniffer();\r
                 SniffLogFile(sniffer, "transportpoint_00" + (i + 1));\r
                 var j = i;\r
-                PAssert.That(() => (int)sniffer.GetShipStatuses(0).Sum(s => s.TransportPoint) == results[j], msgs[j]);\r
+                PAssert.That(() => (int)sniffer.Fleets[0].TransportPoint == results[j], msgs[j]);\r
             }\r
         }\r
 \r
@@ -380,7 +383,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "antiairfire_001");\r
-            var ships = sniffer.GetShipStatuses(0);\r
+            var ships = sniffer.Fleets[0].Ships;\r
             PAssert.That(() => ships.Sum(ship => ship.EffectiveAntiAirForFleet) == 88);\r
             PAssert.That(\r
                 () =>\r
@@ -396,7 +399,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "nightbattlepower_001");\r
-            var ships = sniffer.GetShipStatuses(0);\r
+            var ships = sniffer.Fleets[0].Ships;\r
             PAssert.That(() =>\r
                 ships.Select(ship => (int)(ship.NightBattlePower * 100))\r
                     .SequenceEqual(new[] {11202, 14985, 20092, 17354}));\r
@@ -418,9 +421,10 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "firepower_001");\r
+            var fleet = sniffer.Fleets[0];\r
             // ReSharper disable CompareOfFloatsByEqualityOperator\r
-            PAssert.That(() => sniffer.GetShipStatuses(0)[0].EffectiveFirepower == 93.5);\r
-            PAssert.That(() => sniffer.GetShipStatuses(0)[1].EffectiveFirepower == 82.5);\r
+            PAssert.That(() => fleet.Ships[0].EffectiveFirepower == 93.5);\r
+            PAssert.That(() => fleet.Ships[1].EffectiveFirepower == 82.5);\r
             // ReSharper restore CompareOfFloatsByEqualityOperator\r
         }\r
 \r
@@ -504,7 +508,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "slot_exchange_001");\r
-            var result = sniffer.GetShipStatuses(0)[0].Slot.Select(item => item.Id);\r
+            var result = sniffer.Fleets[0].Ships[0].Slot.Select(item => item.Id);\r
             PAssert.That(() => new[] {26096, 30571, 77694, 61383, -1}.SequenceEqual(result));\r
         }\r
 \r
@@ -516,7 +520,7 @@ namespace KancolleSniffer.Test
         {\r
             var sniffer = new Sniffer();\r
             SniffLogFile(sniffer, "powerup_001");\r
-            PAssert.That(() => Math.Abs(sniffer.GetShipStatuses(0)[0].EffectiveFirepower - 30) < 0.0001);\r
+            PAssert.That(() => Math.Abs(sniffer.Fleets[0].Ships[0].EffectiveFirepower - 30) < 0.0001);\r
         }\r
 \r
         /// <summary>\r
@@ -743,7 +747,7 @@ namespace KancolleSniffer.Test
             var sniffer = new Sniffer(true);\r
             SniffLogFile(sniffer, "twofleets_001");\r
             var expected = Enumerable.Repeat(new ChargeStatus(5, 5), ShipInfo.FleetCount);\r
-            PAssert.That(() => expected.SequenceEqual(sniffer.ChargeStatuses));\r
+            PAssert.That(() => expected.SequenceEqual(sniffer.Fleets.Select(f => f.ChargeStatus)));\r
         }\r
 \r
         /// <summary>\r
index 565ff66..fb70ec0 100644 (file)
@@ -56,7 +56,7 @@ namespace KancolleSniffer
             var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
             for (var f = 0; f < fn.Length; f++)\r
             {\r
-                var ships = sniffer.GetShipStatuses(f);\r
+                var ships = sniffer.Fleets[f].Ships;\r
                 var rawForFleet = ships.Sum(ship => ship.EffectiveAntiAirForFleet);\r
                 var forFleet = new[] {1.0, 1.2, 1.6}.Select(r => (int)(rawForFleet * r) * 2 / 1.3).ToArray();\r
                 _table.Add(new Record {Fleet = fn[f] + " : " + string.Join("/", forFleet.Select(x => x.ToString("f1")))});\r
index 3a32909..710911e 100644 (file)
@@ -128,11 +128,12 @@ namespace KancolleSniffer
                 return;\r
             _shipInfo.SaveBattleStartStatus();\r
             _fleet = DeckId(json);\r
-            var fstats = _shipInfo.GetShipStatuses(_fleet);\r
+            var fleets = _shipInfo.Fleets;\r
+            var fstats = fleets[_fleet].Ships;\r
             FlagshipRecovery(request, fstats[0]);\r
             _friend = Record.Setup(fstats, practice);\r
             _guard = json.api_f_nowhps_combined()\r
-                ? Record.Setup(_shipInfo.GetShipStatuses(1), practice)\r
+                ? Record.Setup(fleets[1].Ships, practice)\r
                 : new Record[0];\r
             _enemy = Record.Setup((int[])json.api_e_nowhps,\r
                 ((int[])json.api_ship_ke).Select(_shipInfo.GetSpec).ToArray(),\r
@@ -220,9 +221,10 @@ namespace KancolleSniffer
 \r
         private int[] CalcFighterPower()\r
         {\r
+            var fleets = _shipInfo.Fleets;\r
             if (_guard.Length > 0 && _enemyGuard.Length > 0)\r
-                return _shipInfo.GetFighterPower(0).Zip(_shipInfo.GetFighterPower(1), (a, b) => a + b).ToArray();\r
-            return _shipInfo.GetFighterPower(_fleet);\r
+                return fleets[0].FighterPower.Zip(fleets[1].FighterPower, (a, b) => a + b).ToArray();\r
+            return fleets[_fleet].FighterPower;\r
         }\r
 \r
         private EnemyFighterPower CalcEnemyFighterPower(dynamic json)\r
@@ -507,9 +509,10 @@ namespace KancolleSniffer
         {\r
             if (_friend == null)\r
                 return;\r
+            var fleets = _shipInfo.Fleets;\r
             var ships = _guard.Length > 0\r
-                ? _shipInfo.GetShipStatuses(0).Concat(_shipInfo.GetShipStatuses(1)).ToArray()\r
-                : _shipInfo.GetShipStatuses(_fleet);\r
+                ? fleets[0].Ships.Concat(fleets[1].Ships)\r
+                : fleets[_fleet].Ships;\r
             foreach (var entry in ships.Zip(_friend.Concat(_guard), (ship, now) => new {ship, now}))\r
                 entry.now.UpdateShipStatus(entry.ship);\r
             if (warnDamagedShip)\r
index 0a94589..8ef0422 100644 (file)
@@ -80,9 +80,10 @@ namespace KancolleSniffer
 \r
         public DateTime GetTimer(int fleet)\r
         {\r
-            if (_shipInfo.Fleets[fleet].State != FleetState.Port)\r
+            var target = _shipInfo.Fleets[fleet];\r
+            if (target.State != FleetState.Port)\r
                 return DateTime.MinValue;\r
-            var cond = _shipInfo.GetShipStatuses(fleet).Select(s => s.Cond).DefaultIfEmpty(49).Min();\r
+            var cond = target.Ships.Select(s => s.Cond).DefaultIfEmpty(49).Min();\r
             if (cond >= 49)\r
                 return DateTime.MinValue;\r
             var nextRegen = NextRegenTime(_lastUpdate);\r
diff --git a/KancolleSniffer/Fleet.cs b/KancolleSniffer/Fleet.cs
new file mode 100644 (file)
index 0000000..0054ac9
--- /dev/null
@@ -0,0 +1,171 @@
+// Copyright (C) 2018 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.Collections.Generic;\r
+using System.Linq;\r
+using static System.Math;\r
+\r
+namespace KancolleSniffer\r
+{\r
+    public struct ChargeStatus\r
+    {\r
+        public int Fuel { get; set; }\r
+        public int Bull { get; set; }\r
+\r
+        public ChargeStatus(ShipStatus status) : this()\r
+        {\r
+            Fuel = CalcChargeState(status.Fuel, status.Spec.FuelMax);\r
+            Bull = CalcChargeState(status.Bull, status.Spec.BullMax);\r
+        }\r
+\r
+        public ChargeStatus(int fuel, int bull) : this()\r
+        {\r
+            Fuel = fuel;\r
+            Bull = bull;\r
+        }\r
+\r
+        private int CalcChargeState(int now, int full)\r
+        {\r
+            if (full == 0 || now == full)\r
+                return 0;\r
+            var ratio = (double)now / full;\r
+            if (ratio >= 7.0 / 9)\r
+                return 1;\r
+            if (ratio >= 3.0 / 9)\r
+                return 2;\r
+            if (ratio > 0)\r
+                return 3;\r
+            return 4;\r
+        }\r
+    }\r
+\r
+    public enum FleetState\r
+    {\r
+        Port,\r
+        Mission,\r
+        Sortie,\r
+        Practice\r
+    }\r
+\r
+    public class Fleet\r
+    {\r
+        private readonly ShipInfo _shipInfo;\r
+        public FleetState State { get; set; }\r
+        public int[] Deck { get; set; } = Enumerable.Repeat(-1, ShipInfo.MemberCount).ToArray();\r
+        public ShipStatus[] Ships => Deck.Where(id => id != -1).Select(_shipInfo.GetStatus).ToArray();\r
+\r
+        public Fleet(ShipInfo shipInfo)\r
+        {\r
+            _shipInfo = shipInfo;\r
+        }\r
+\r
+        public ChargeStatus ChargeStatus\r
+        {\r
+            get\r
+            {\r
+                var fs = new ChargeStatus(_shipInfo.GetStatus(Deck[0]));\r
+                var others = (from id in Deck.Skip(1) select new ChargeStatus(_shipInfo.GetStatus(id))).Aggregate(\r
+                    (result, next) => new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)));\r
+                return new ChargeStatus(fs.Fuel != 0 ? fs.Fuel : others.Fuel + 5, fs.Bull != 0 ? fs.Bull : others.Bull + 5);\r
+            }\r
+        }\r
+\r
+        public int[] FighterPower\r
+            => Ships.Where(ship => !ship.Escaped).SelectMany(ship =>\r
+                    ship.Slot.Zip(ship.OnSlot, (slot, onslot) => slot.CalcFighterPower(onslot)))\r
+                .Aggregate(new[] {0, 0}, (prev, cur) => new[] {prev[0] + cur[0], prev[1] + cur[1]});\r
+\r
+        public double ContactTriggerRate\r
+            => Ships.Where(ship => !ship.Escaped).SelectMany(ship =>\r
+                ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
+                    slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
+\r
+        public double GetLineOfSights(int factor)\r
+        {\r
+            var result = 0.0;\r
+            var emptyBonus = 6;\r
+            foreach (var s in Ships.Where(s => !s.Escaped))\r
+            {\r
+                emptyBonus--;\r
+                var itemLoS = 0;\r
+                foreach (var item in s.Slot)\r
+                {\r
+                    var spec = item.Spec;\r
+                    itemLoS += spec.LoS;\r
+                    result += (spec.LoS + item.LoSLevelBonus) * spec.LoSScaleFactor * factor;\r
+                }\r
+                result += Sqrt(s.LoS - itemLoS);\r
+            }\r
+            return result > 0 ? result - Ceiling(_shipInfo.HqLevel * 0.4) + emptyBonus * 2 : 0.0;\r
+        }\r
+\r
+        public double DaihatsuBonus\r
+        {\r
+            get\r
+            {\r
+                var tokudaiBonus = new[,]\r
+                {\r
+                    {0.00, 0.00, 0.00, 0.00, 0.00},\r
+                    {0.02, 0.02, 0.02, 0.02, 0.02},\r
+                    {0.04, 0.04, 0.04, 0.04, 0.04},\r
+                    {0.05, 0.05, 0.052, 0.054, 0.054},\r
+                    {0.054, 0.056, 0.058, 0.059, 0.06}\r
+                };\r
+                var daihatsu = 0;\r
+                var tokudai = 0;\r
+                var bonus = 0.0;\r
+                var level = 0;\r
+                var sum = 0;\r
+                foreach (var ship in Ships)\r
+                {\r
+                    if (ship.Name == "鬼怒改二")\r
+                        bonus += 0.05;\r
+                    foreach (var item in ship.Slot)\r
+                    {\r
+                        switch (item.Spec.Name)\r
+                        {\r
+                            case "大発動艇":\r
+                                level += item.Level;\r
+                                sum++;\r
+                                daihatsu++;\r
+                                bonus += 0.05;\r
+                                break;\r
+                            case "特大発動艇":\r
+                                level += item.Level;\r
+                                sum++;\r
+                                tokudai++;\r
+                                bonus += 0.05;\r
+                                break;\r
+                            case "大発動艇(八九式中戦車&陸戦隊)":\r
+                                level += item.Level;\r
+                                sum++;\r
+                                bonus += 0.02;\r
+                                break;\r
+                            case "特二式内火艇":\r
+                                level += item.Level;\r
+                                sum++;\r
+                                bonus += 0.01;\r
+                                break;\r
+                        }\r
+                    }\r
+                }\r
+                var levelAverage = sum == 0 ? 0.0 : (double)level / sum;\r
+                bonus = Min(bonus, 0.2);\r
+                return bonus + 0.01 * bonus * levelAverage + tokudaiBonus[Min(tokudai, 4), Min(daihatsu, 4)];\r
+            }\r
+        }\r
+\r
+        public double TransportPoint => Ships.Where(ship => !ship.Escaped).Sum(ship => ship.TransportPoint);\r
+    }\r
+}
\ No newline at end of file
index 4558ad2..76d692b 100644 (file)
@@ -89,12 +89,14 @@ namespace KancolleSniffer
         private void CreateTable(Sniffer sniffer)\r
         {\r
             var list = new List<Record>();\r
+            var fleets = sniffer.Fleets;\r
             var fn = new[] {"第一", "第二", "第三", "第四"};\r
             for (var f = 0; f < fn.Length; f++)\r
             {\r
                 var total = new Total();\r
                 var ships = new List<Record>();\r
-                foreach (var s in sniffer.GetShipStatuses(f))\r
+                var fleet = fleets[f];\r
+                foreach (var s in fleet.Ships)\r
                 {\r
                     var equips = new List<Record>();\r
                     for (var i = 0; i < s.Slot.Length; i++)\r
@@ -150,10 +152,10 @@ namespace KancolleSniffer
                     ships.Add(ship);\r
                     ships.AddRange(equips);\r
                 }\r
-                var daihatsu = sniffer.GetDaihatsuBonus(f);\r
-                var tp = sniffer.GetTransportPoint(f);\r
+                var daihatsu = fleet.DaihatsuBonus;\r
+                var tp = fleet.TransportPoint;\r
                 if (sniffer.CombinedFleetType != 0 && f == 0)\r
-                    tp += sniffer.GetTransportPoint(1);\r
+                    tp += fleets[1].TransportPoint;\r
                 list.Add(new Record\r
                 {\r
                     Fleet = fn[f] + HideIfZero(" Lv", total.Level) +\r
index 4583c24..5e091d1 100644 (file)
@@ -83,6 +83,7 @@
     </Compile>\r
     <Compile Include="CUDColor.cs" />\r
     <Compile Include="DockInfo.cs" />\r
+    <Compile Include="Fleet.cs" />\r
     <Compile Include="FleetPanel.cs">\r
       <SubType>Component</SubType>\r
     </Compile>\r
index 8998b22..5b39fe0 100644 (file)
@@ -214,7 +214,7 @@ namespace KancolleSniffer
                 else\r
                     dropName += "+" + itemName;\r
             }\r
-            var fp = _shipInfo.GetFighterPower(BattleInfo.DeckId(_battle));\r
+            var fp = _shipInfo.Fleets[BattleInfo.DeckId(_battle)].FighterPower;\r
             var fpower = fp[0] == fp[1] ? fp[0].ToString() : fp[0] + "~" + fp[1];\r
             _writer("海戦・ドロップ報告書", string.Join(",", FormatDateTime(_nowFunc()),\r
                     result.api_quest_name,\r
@@ -495,7 +495,7 @@ namespace KancolleSniffer
 \r
         private string Secretary()\r
         {\r
-            var ship = _shipInfo.GetShipStatuses(0)[0];\r
+            var ship = _shipInfo.Fleets[0].Ships[0];\r
             return ship.Name + "(" + ship.Level + ")";\r
         }\r
 \r
@@ -550,7 +550,7 @@ namespace KancolleSniffer
                 diff[i] = _currentMaterial[i] - after[i];\r
             var ship1 = Secretary();\r
             var ship2 = "";\r
-            var ships = _shipInfo.GetShipStatuses(0);\r
+            var ships = _shipInfo.Fleets[0].Ships;\r
             if (ships.Length >= 2)\r
                 ship2 = ships[1].Name + "(" + ships[1].Level + ")";\r
             _writer("改修報告書",\r
index 8190aa9..d2525e7 100644 (file)
@@ -519,10 +519,10 @@ namespace KancolleSniffer
             if (!_listForm.Visible)\r
                 return;\r
             var idx = (int)((Control)sender).Tag;\r
-            var statuses = _sniffer.GetShipStatuses(_currentFleet);\r
-            if (statuses.Length <= idx)\r
+            var ships = _sniffer.Fleets[_currentFleet].Ships;\r
+            if (ships.Length <= idx)\r
                 return;\r
-            _listForm.ShowShip(statuses[idx].Id);\r
+            _listForm.ShowShip(ships[idx].Id);\r
         }\r
 \r
         private void UpdateItemInfo()\r
@@ -636,15 +636,16 @@ namespace KancolleSniffer
 \r
         private void UpdatePanelShipInfo()\r
         {\r
-            var statuses = _sniffer.GetShipStatuses(_currentFleet);\r
-            panel7Ships.Visible = statuses.Length == 7;\r
-            _mainLabels.SetShipLabels(statuses);\r
+            var fleets = _sniffer.Fleets;\r
+            var ships = fleets[_currentFleet].Ships;\r
+            panel7Ships.Visible = ships.Length == 7;\r
+            _mainLabels.SetShipLabels(ships);\r
             if (_sniffer.CombinedFleetType == 0)\r
                 _combinedFleet = false;\r
             labelFleet1.Text = _combinedFleet ? "連合" : "第一";\r
             panelCombinedFleet.Visible = _combinedFleet;\r
             if (_combinedFleet)\r
-                _mainLabels.SetCombinedShipLabels(_sniffer.GetShipStatuses(0), _sniffer.GetShipStatuses(1));\r
+                _mainLabels.SetCombinedShipLabels(fleets[0].Ships, fleets[1].Ships);\r
             for (var i = 0; i < _labelCheckFleets.Length; i++)\r
                 _labelCheckFleets[i].Visible = _currentFleet == i;\r
             UpdateAkashiTimer();\r
@@ -664,13 +665,14 @@ namespace KancolleSniffer
 \r
         public void UpdateFighterPower(bool combined)\r
         {\r
+            var fleets = _sniffer.Fleets;\r
             var fp = combined\r
-                ? _sniffer.GetFighterPower(0).Zip(_sniffer.GetFighterPower(1), (a, b) => a + b).ToArray()\r
-                : _sniffer.GetFighterPower(_currentFleet);\r
+                ? fleets[0].FighterPower.Zip(fleets[1].FighterPower, (a, b) => a + b).ToArray()\r
+                : fleets[_currentFleet].FighterPower;\r
             labelFighterPower.Text = fp[0].ToString("D");\r
             var cr = combined\r
-                ? _sniffer.GetContactTriggerRate(0) + _sniffer.GetContactTriggerRate(1)\r
-                : _sniffer.GetContactTriggerRate(_currentFleet);\r
+                ? fleets[0].ContactTriggerRate + fleets[1].ContactTriggerRate\r
+                : fleets[_currentFleet].ContactTriggerRate;\r
             var text = "制空: " + (fp[0] == fp[1] ? $"{fp[0]}" : $"{fp[0]}~{fp[1]}") +\r
                        $" 触接: {cr * 100:f1}";\r
             _toolTip.SetToolTip(labelFighterPower, text);\r
@@ -679,9 +681,10 @@ namespace KancolleSniffer
 \r
         private void UpdateLoS()\r
         {\r
-            labelLoS.Text = RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 1)).ToString("F1");\r
-            var text = $"係数3: {RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 3)):F1}\r\n" +\r
-                       $"係数4: {RoundDown(_sniffer.GetFleetLineOfSights(_currentFleet, 4)):F1}";\r
+            var fleet = _sniffer.Fleets[_currentFleet];\r
+            labelLoS.Text = RoundDown(fleet.GetLineOfSights(1)).ToString("F1");\r
+            var text = $"係数3: {RoundDown(fleet.GetLineOfSights(3)):F1}\r\n" +\r
+                       $"係数4: {RoundDown(fleet.GetLineOfSights(4)):F1}";\r
             _toolTip.SetToolTip(labelLoS, text);\r
             _toolTip.SetToolTip(labelLoSCaption, text);\r
         }\r
@@ -751,7 +754,7 @@ namespace KancolleSniffer
 \r
             for (var i = 0; i < fuelSq.Length; i++)\r
             {\r
-                var stat = _sniffer.ChargeStatuses[i];\r
+                var stat = _sniffer.Fleets[i].ChargeStatus;\r
                 fuelSq[i].ImageIndex = stat.Fuel;\r
                 bullSq[i].ImageIndex = stat.Bull;\r
             }\r
@@ -908,8 +911,7 @@ namespace KancolleSniffer
         {\r
             if (_config.UsePresetAkashi)\r
                 UpdatePresetAkashiTimer();\r
-            var statuses = _sniffer.GetShipStatuses(_currentFleet);\r
-            _mainLabels.SetAkashiTimer(statuses,\r
+            _mainLabels.SetAkashiTimer(_sniffer.Fleets[_currentFleet].Ships,\r
                 _sniffer.AkashiTimer.GetTimers(_currentFleet));\r
         }\r
 \r
index eac9ecc..ecc541b 100644 (file)
@@ -113,7 +113,7 @@ namespace KancolleSniffer
             var raw = _expTable[Min(s1, _expTable.Length) - 1] / 100.0 +\r
                       _expTable[Min(s2, _expTable.Length) - 1] / 300.0;\r
             var exp = raw >= 500 ? 500 + (int)Sqrt(raw - 500) : (int)raw;\r
-            var bonus = 1 + TrainingCruiserBonus(_shipInfo.GetShipStatuses(0));\r
+            var bonus = 1 + TrainingCruiserBonus(_shipInfo.Fleets[0].Ships);\r
             Text += $"獲得経験値 : {(int)(exp * bonus)}\r\nS勝利 : {(int)((int)(exp * 1.2) * bonus)}";\r
         }\r
 \r
index 83b3626..ebace6e 100644 (file)
@@ -19,65 +19,20 @@ using static System.Math;
 \r
 namespace KancolleSniffer\r
 {\r
-    public struct ChargeStatus\r
-    {\r
-        public int Fuel { get; set; }\r
-        public int Bull { get; set; }\r
-\r
-        public ChargeStatus(ShipStatus status) : this()\r
-        {\r
-            Fuel = CalcChargeState(status.Fuel, status.Spec.FuelMax);\r
-            Bull = CalcChargeState(status.Bull, status.Spec.BullMax);\r
-        }\r
-\r
-        public ChargeStatus(int fuel, int bull) : this()\r
-        {\r
-            Fuel = fuel;\r
-            Bull = bull;\r
-        }\r
-\r
-        private int CalcChargeState(int now, int full)\r
-        {\r
-            if (full == 0 || now == full)\r
-                return 0;\r
-            var ratio = (double)now / full;\r
-            if (ratio >= 7.0 / 9)\r
-                return 1;\r
-            if (ratio >= 3.0 / 9)\r
-                return 2;\r
-            if (ratio > 0)\r
-                return 3;\r
-            return 4;\r
-        }\r
-    }\r
-\r
-    public enum FleetState\r
-    {\r
-        Port,\r
-        Mission,\r
-        Sortie,\r
-        Practice\r
-    }\r
-\r
-    public class Fleet\r
-    {\r
-        public FleetState State { get; set; }\r
-        public int[] Deck { get; set; } = Enumerable.Repeat(-1, ShipInfo.MemberCount).ToArray();\r
-    }\r
 \r
     public class ShipInfo\r
     {\r
         public const int FleetCount = 4;\r
         public const int MemberCount = 6;\r
 \r
-        private readonly Fleet[] _fleets = Enumerable.Range(0, FleetCount).Select(x => new Fleet()).ToArray();\r
+        private readonly Fleet[] _fleets;\r
         private readonly Dictionary<int, ShipStatus> _shipInfo = new Dictionary<int, ShipStatus>();\r
         private readonly ShipMaster _shipMaster = new ShipMaster();\r
         private readonly ItemInfo _itemInfo;\r
-        private int _hqLevel;\r
         private readonly List<int> _escapedShips = new List<int>();\r
         private int _combinedFleetType;\r
         private ShipStatus[] _battleResult = new ShipStatus[0];\r
+        public int HqLevel { get; private set; }\r
         public ShipStatusPair[] BattleResultDiff { get; private set; } = new ShipStatusPair[0];\r
         public bool IsBattleResultError => BattleResultDiff.Length > 0;\r
         public ShipStatus[] BattleStartStatus { get; private set; } = new ShipStatus[0];\r
@@ -96,6 +51,7 @@ namespace KancolleSniffer
 \r
         public ShipInfo(ItemInfo itemInfo)\r
         {\r
+            _fleets = Enumerable.Range(0, FleetCount).Select(x => new Fleet(this)).ToArray();\r
             _itemInfo = itemInfo;\r
             ClearShipInfo();\r
         }\r
@@ -211,7 +167,7 @@ namespace KancolleSniffer
 \r
         private void InspectBasic(dynamic json)\r
         {\r
-            _hqLevel = (int)json.api_level;\r
+            HqLevel = (int)json.api_level;\r
         }\r
 \r
         public void InspectCharge(dynamic json)\r
@@ -356,11 +312,6 @@ namespace KancolleSniffer
             s.Cond = Max(40, s.Cond);\r
         }\r
 \r
-        public ShipStatus[] GetShipStatuses(int fleet)\r
-        {\r
-            return _fleets[fleet].Deck.Where(id => id != -1).Select(GetStatus).ToArray();\r
-        }\r
-\r
         public Fleet[] Fleets => _fleets;\r
 \r
         public ShipStatus GetStatus(int id)\r
@@ -392,109 +343,11 @@ namespace KancolleSniffer
 \r
         public ShipStatus[] ShipList => _shipInfo.Keys.Where(id => id != -1).Select(GetStatus).ToArray();\r
 \r
-        public ChargeStatus[] ChargeStatuses\r
-            => (from fleet in _fleets\r
-                let flag = new ChargeStatus(_shipInfo[fleet.Deck[0]])\r
-                let others = (from id in fleet.Deck.Skip(1)\r
-                        select new ChargeStatus(_shipInfo[id]))\r
-                    .Aggregate(\r
-                        (result, next) =>\r
-                            new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)))\r
-                select new ChargeStatus(flag.Fuel != 0 ? flag.Fuel : others.Fuel + 5,\r
-                    flag.Bull != 0 ? flag.Bull : others.Bull + 5)).ToArray();\r
-\r
-        public int[] GetFighterPower(int fleet)\r
-            => GetShipStatuses(fleet).Where(ship => !ship.Escaped).SelectMany(ship =>\r
-                    ship.Slot.Zip(ship.OnSlot, (slot, onslot) => slot.CalcFighterPower(onslot)))\r
-                .Aggregate(new[] {0, 0}, (prev, cur) => new[] {prev[0] + cur[0], prev[1] + cur[1]});\r
-\r
-        public double GetContactTriggerRate(int fleet)\r
-            => GetShipStatuses(fleet).Where(ship => !ship.Escaped).SelectMany(ship =>\r
-                ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
-                    slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
-\r
         public ShipStatus[] GetRepairList(DockInfo dockInfo)\r
             => (from s in ShipList\r
                 where s.NowHp < s.MaxHp && !dockInfo.InNDock(s.Id)\r
                 select s).OrderByDescending(s => s.RepairTime).ToArray();\r
 \r
-        public double GetLineOfSights(int fleet, int factor)\r
-        {\r
-            var result = 0.0;\r
-            var emptyBonus = 6;\r
-            foreach (var s in GetShipStatuses(fleet).Where(s => !s.Escaped))\r
-            {\r
-                emptyBonus--;\r
-                var itemLoS = 0;\r
-                foreach (var item in s.Slot)\r
-                {\r
-                    var spec = item.Spec;\r
-                    itemLoS += spec.LoS;\r
-                    result += (spec.LoS + item.LoSLevelBonus) * spec.LoSScaleFactor * factor;\r
-                }\r
-                result += Sqrt(s.LoS - itemLoS);\r
-            }\r
-            return result > 0 ? result - Ceiling(_hqLevel * 0.4) + emptyBonus * 2 : 0.0;\r
-        }\r
-\r
-        public double GetDaihatsuBonus(int fleet)\r
-        {\r
-            var tokudaiBonus = new[,]\r
-            {\r
-                {0.00, 0.00, 0.00, 0.00, 0.00},\r
-                {0.02, 0.02, 0.02, 0.02, 0.02},\r
-                {0.04, 0.04, 0.04, 0.04, 0.04},\r
-                {0.05, 0.05, 0.052, 0.054, 0.054},\r
-                {0.054, 0.056, 0.058, 0.059, 0.06}\r
-            };\r
-            var daihatsu = 0;\r
-            var tokudai = 0;\r
-            var bonus = 0.0;\r
-            var level = 0;\r
-            var sum = 0;\r
-            foreach (var ship in GetShipStatuses(fleet))\r
-            {\r
-                if (ship.Name == "鬼怒改二")\r
-                    bonus += 0.05;\r
-                foreach (var item in ship.Slot)\r
-                {\r
-                    switch (item.Spec.Name)\r
-                    {\r
-                        case "大発動艇":\r
-                            level += item.Level;\r
-                            sum++;\r
-                            daihatsu++;\r
-                            bonus += 0.05;\r
-                            break;\r
-                        case "特大発動艇":\r
-                            level += item.Level;\r
-                            sum++;\r
-                            tokudai++;\r
-                            bonus += 0.05;\r
-                            break;\r
-                        case "大発動艇(八九式中戦車&陸戦隊)":\r
-                            level += item.Level;\r
-                            sum++;\r
-                            bonus += 0.02;\r
-                            break;\r
-                        case "特二式内火艇":\r
-                            level += item.Level;\r
-                            sum++;\r
-                            bonus += 0.01;\r
-                            break;\r
-                    }\r
-                }\r
-            }\r
-            var levelAverage = sum == 0 ? 0.0 : (double)level / sum;\r
-            bonus = Min(bonus, 0.2);\r
-            return bonus + 0.01 * bonus * levelAverage + tokudaiBonus[Min(tokudai, 4), Min(daihatsu, 4)];\r
-        }\r
-\r
-        public double GetTransportPoint(int fleet)\r
-        {\r
-            return GetShipStatuses(fleet).Where(ship => !ship.Escaped).Sum(ship => ship.TransportPoint);\r
-        }\r
-\r
         public string[] BadlyDamagedShips { get; private set; } = new string[0];\r
 \r
         public void SetBadlyDamagedShips()\r
index cc56698..b800118 100644 (file)
@@ -554,8 +554,6 @@ namespace KancolleSniffer
 \r
         public int[] GetConditionNotice(DateTime prev, DateTime now) => _conditionTimer.GetNotice(prev, now);\r
 \r
-        public ShipStatus[] GetShipStatuses(int fleet) => _shipInfo.GetShipStatuses(fleet);\r
-\r
         public Fleet[] Fleets => _shipInfo.Fleets;\r
 \r
         public ShipInfo.ShipStatusPair[] BattleResultStatusDiff => _shipInfo.BattleResultDiff;\r
@@ -566,24 +564,12 @@ namespace KancolleSniffer
 \r
         public int CombinedFleetType => _shipInfo.CombinedFleetType;\r
 \r
-        public ChargeStatus[] ChargeStatuses => _shipInfo.ChargeStatuses;\r
-\r
-        public int[] GetFighterPower(int fleet) => _shipInfo.GetFighterPower(fleet);\r
-\r
-        public double GetContactTriggerRate(int fleet) => _shipInfo.GetContactTriggerRate(fleet);\r
-\r
-        public double GetFleetLineOfSights(int fleet, int factor) => _shipInfo.GetLineOfSights(fleet, factor);\r
-\r
         public ShipStatus[] RepairList => _shipInfo.GetRepairList(_dockInfo);\r
 \r
         public ShipStatus[] ShipList => _shipInfo.ShipList;\r
 \r
         public string[] BadlyDamagedShips => _shipInfo.BadlyDamagedShips;\r
 \r
-        public double GetDaihatsuBonus(int fleet) => _shipInfo.GetDaihatsuBonus(fleet);\r
-\r
-        public double GetTransportPoint(int fleet) => _shipInfo.GetTransportPoint(fleet);\r
-\r
         public ItemStatus[] ItemList\r
         {\r
             get\r
index 01f2701..94fce21 100644 (file)
@@ -72,18 +72,19 @@ namespace KancolleSniffer
 \r
         private static StringBuilder GenerateFleetData(Sniffer sniffer, int fleet, ItemName dict)\r
         {\r
+            var target = sniffer.Fleets[fleet];\r
             var sb = new StringBuilder();\r
             var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
             sb.Append(fn[fleet] + "\r\n");\r
-            sb.Append(string.Concat(from s in sniffer.GetShipStatuses(fleet)\r
+            sb.Append(string.Concat(from s in target.Ships\r
                 select ($"{s.Name} Lv{s.Level} " +\r
                         string.Join(",",\r
                             from item in s.AllSlot\r
                             where item.Id != -1\r
                             select dict[item.Spec.Name] + ItemStatusString(item))).TrimEnd(' ') + "\r\n"));\r
-            var fp = sniffer.GetFighterPower(fleet);\r
+            var fp = target.FighterPower;\r
             sb.Append($"制空: {(fp[0] == fp[1] ? fp[0].ToString() : fp[0] + "~" + fp[1])} " +\r
-                      $"索敵: {sniffer.GetFleetLineOfSights(fleet, 1):F1}\r\n");\r
+                      $"索敵: {target.GetLineOfSights(1):F1}\r\n");\r
             return sb;\r
         }\r
 \r
@@ -144,7 +145,7 @@ namespace KancolleSniffer
                 if (f != 0)\r
                     sb.Append(",");\r
                 sb.Append($"\"f{f + 1}\":{{");\r
-                var ships = sniffer.GetShipStatuses(f);\r
+                var ships = sniffer.Fleets[f].Ships;\r
                 for (var s = 0; s < ships.Length; s++)\r
                 {\r
                     if (s != 0)\r