OSDN Git Service

ShipInfoとItemInfoから辞書を分離する
authorKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 30 Jul 2018 12:29:32 +0000 (21:29 +0900)
committerKazuhiro Fujieda <fujieda@users.osdn.me>
Mon, 30 Jul 2018 12:29:32 +0000 (21:29 +0900)
KancolleSniffer.Test/BattleTest.cs
KancolleSniffer.Test/QuestInfoTest.cs
KancolleSniffer/KancolleSniffer.csproj
KancolleSniffer/Model/Inventry.cs [new file with mode: 0644]
KancolleSniffer/Model/ItemInfo.cs
KancolleSniffer/Model/ShipInfo.cs
KancolleSniffer/Sniffer.cs

index 62a8bb4..eb63b95 100644 (file)
@@ -36,8 +36,8 @@ namespace KancolleSniffer.Test
         [TestInitialize]\r
         public void Initialize()\r
         {\r
-            _itemInfo = new ItemInfo(new ItemMaster());\r
-            _shipInfo = new ShipInfo(new ShipMaster(), _itemInfo);\r
+            _itemInfo = new ItemInfo(new ItemMaster(), new ItemInventry());\r
+            _shipInfo = new ShipInfo(new ShipMaster(), new ShipInventry(), _itemInfo);\r
             _battleInfo = new BattleInfo(_shipInfo, _itemInfo);\r
         }\r
 \r
index 8d3aac4..f0719b9 100644 (file)
@@ -1087,7 +1087,7 @@ namespace KancolleSniffer.Test
         [TestMethod]\r
         public void DestroyItem_613_638_643_645_663_673_674_675_676_677_678()\r
         {\r
-            var itemInfo = new ItemInfo(new ItemMaster());\r
+            var itemInfo = new ItemInfo(new ItemMaster(), new ItemInventry());\r
             var questInfo = new QuestInfo(itemInfo, null, () => new DateTime(2015, 1, 1)) {AcceptMax = 12};\r
 \r
             itemInfo.InjectItemSpec(new[]\r
index 2dfb094..915081c 100644 (file)
@@ -58,6 +58,7 @@
     <Compile Include="Model\AkashiTimer.cs" />\r
     <Compile Include="Model\AlarmTimer.cs" />\r
     <Compile Include="Model\ItemMaster.cs" />\r
+    <Compile Include="Model\Inventry.cs" />\r
     <Compile Include="Model\ItemSpec.cs" />\r
     <Compile Include="Model\ItemStatus.cs" />\r
     <Compile Include="Model\ShipSpec.cs" />\r
diff --git a/KancolleSniffer/Model/Inventry.cs b/KancolleSniffer/Model/Inventry.cs
new file mode 100644 (file)
index 0000000..85c8e42
--- /dev/null
@@ -0,0 +1,115 @@
+// 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;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+\r
+namespace KancolleSniffer.Model\r
+{\r
+    public class ShipInventry : Inventry<ShipStatus>\r
+    {\r
+        public ShipInventry() : base(new ShipStatus())\r
+        {\r
+        }\r
+\r
+        protected override ShipStatus CreateDummy(int id) => new ShipStatus();\r
+\r
+        protected override int GetId(ShipStatus ship) => ship.Id;\r
+\r
+        public IEnumerable<ShipStatus> AllShips => AllItems;\r
+    }\r
+\r
+    public class ItemInventry : Inventry<ItemStatus>\r
+    {\r
+        public ItemInventry() : base(new ItemStatus())\r
+        {\r
+        }\r
+\r
+        protected override ItemStatus CreateDummy(int id) => new ItemStatus(id);\r
+\r
+        protected override int GetId(ItemStatus item) => item.Id;\r
+    }\r
+\r
+    public abstract class Inventry<T>\r
+    {\r
+        private readonly Dictionary<int, T> _dict = new Dictionary<int, T>();\r
+\r
+        protected abstract T CreateDummy(int id);\r
+\r
+        protected Inventry(T dummy)\r
+        {\r
+            _dict[-1] = dummy;\r
+        }\r
+\r
+        public void Clear()\r
+        {\r
+            _dict.Clear();\r
+            _dict[-1] = CreateDummy(-1);\r
+        }\r
+\r
+        public virtual T this[int id]\r
+        {\r
+            get => _dict.TryGetValue(id, out var item) ? item : CreateDummy(id);\r
+            set => _dict[id] = value;\r
+        }\r
+\r
+        protected abstract int GetId(T item);\r
+\r
+        public void Add(T item)\r
+        {\r
+            _dict[GetId(item)] = item;\r
+        }\r
+\r
+        public void Add(IEnumerable<T> items)\r
+        {\r
+            foreach (var item in items)\r
+                Add(item);\r
+        }\r
+\r
+        public void Remove(int id)\r
+        {\r
+            if (id != -1)\r
+                _dict.Remove(id);\r
+        }\r
+\r
+        public void Remove(IEnumerable<int> ids)\r
+        {\r
+            foreach (var id in ids)\r
+                Remove(id);\r
+        }\r
+\r
+        public void Remove(T item)\r
+        {\r
+            Remove(GetId(item));\r
+        }\r
+\r
+        public void Remove(IEnumerable<T> items)\r
+        {\r
+            foreach (var item in items)\r
+                Remove(item);\r
+        }\r
+\r
+        public bool Contains(int id) => _dict.ContainsKey(id);\r
+\r
+        public bool Contains(T item) => Contains(GetId(item));\r
+\r
+        public IEnumerable<T> AllItems =>\r
+            from kv in _dict where kv.Key != -1 select kv.Value;\r
+\r
+        public int Count => _dict.Count - 1;\r
+\r
+        public int MaxId => Math.Max(_dict.Keys.Max(), 0);\r
+    }\r
+}
\ No newline at end of file
index 5316927..5e05d47 100644 (file)
@@ -22,7 +22,7 @@ namespace KancolleSniffer.Model
     {\r
         private int _nowShips, _nowEquips;\r
         private readonly ItemMaster _itemMaster;\r
-        private readonly Dictionary<int, ItemStatus> _itemInfo = new Dictionary<int, ItemStatus>();\r
+        private readonly ItemInventry _itemInventry;\r
         public int MaxShips { get; private set; }\r
         public int MarginShips { get; set; }\r
         public bool AlarmShips { get; set; }\r
@@ -62,9 +62,10 @@ namespace KancolleSniffer.Model
 \r
         public bool TooManyEquips => MaxEquips != 0 && NowEquips >= MaxEquips - MarginEquips;\r
 \r
-        public ItemInfo(ItemMaster itemMaster)\r
+        public ItemInfo(ItemMaster itemMaster, ItemInventry itemInventry)\r
         {\r
             _itemMaster = itemMaster;\r
+            _itemInventry = itemInventry;\r
             MarginShips = 4;\r
             MarginEquips = 10;\r
         }\r
@@ -88,21 +89,18 @@ namespace KancolleSniffer.Model
             if (!json.IsArray)\r
                 json = new[] {json};\r
             if (full)\r
-            {\r
-                _itemInfo.Clear();\r
-                _itemInfo[-1] = new ItemStatus();\r
-            }\r
+                _itemInventry.Clear();\r
             foreach (var entry in json)\r
             {\r
                 var id = (int)entry.api_id;\r
-                _itemInfo[id] = new ItemStatus(id)\r
+                _itemInventry[id] = new ItemStatus(id)\r
                 {\r
                     Spec = _itemMaster[(int)entry.api_slotitem_id],\r
                     Level = entry.api_level() ? (int)entry.api_level : 0,\r
                     Alv = entry.api_alv() ? (int)entry.api_alv : 0\r
                 };\r
             }\r
-            NowEquips = _itemInfo.Count - 1;\r
+            NowEquips = _itemInventry.Count;\r
         }\r
 \r
         public void InspectCreateItem(dynamic json)\r
@@ -142,11 +140,8 @@ namespace KancolleSniffer.Model
 \r
         private void DeleteItems(IEnumerable<int> ids)\r
         {\r
-            foreach (var id in ids.Where(id => id != -1))\r
-            {\r
-                _itemInfo.Remove(id);\r
-                NowEquips--;\r
-            }\r
+            _itemInventry.Remove(ids);\r
+            NowEquips = _itemInventry.Count;\r
         }\r
 \r
         public ItemSpec GetSpecByItemId(int id) => _itemMaster[id];\r
@@ -155,16 +150,16 @@ namespace KancolleSniffer.Model
 \r
         public ItemStatus GetStatus(int id)\r
         {\r
-            return _itemInfo.TryGetValue(id, out var item) ? item : new ItemStatus(id);\r
+            return _itemInventry[id];\r
         }\r
 \r
         public void ClearHolder()\r
         {\r
-            foreach (var item in _itemInfo.Values)\r
+            foreach (var item in _itemInventry.AllItems)\r
                 item.Holder = new ShipStatus();\r
         }\r
 \r
-        public ItemStatus[] ItemList => (from e in _itemInfo where e.Key != -1 select e.Value).ToArray();\r
+        public ItemStatus[] ItemList => _itemInventry.AllItems.ToArray();\r
 \r
         public string GetUseItemName(int id) => _itemMaster.GetUseItemName(id);\r
 \r
@@ -176,7 +171,7 @@ namespace KancolleSniffer.Model
 \r
         public ItemStatus[] InjectItems(IEnumerable<int> itemIds)\r
         {\r
-            var id = _itemInfo.Keys.Count + 1;\r
+            var id = _itemInventry.MaxId + 1;\r
             return itemIds.Select(itemId =>\r
             {\r
                 var spec = _itemMaster[itemId];\r
@@ -186,7 +181,7 @@ namespace KancolleSniffer.Model
                     _itemMaster[itemId] = spec;\r
                 }\r
                 var item = new ItemStatus {Id = id++, Spec = spec};\r
-                _itemInfo.Add(item.Id, item);\r
+                _itemInventry.Add(item);\r
                 return item;\r
             }).ToArray();\r
         }\r
index d59e69c..37e30b0 100644 (file)
@@ -26,8 +26,8 @@ namespace KancolleSniffer.Model
         public const int MemberCount = 6;\r
 \r
         private readonly Fleet[] _fleets;\r
-        private readonly Dictionary<int, ShipStatus> _shipInfo = new Dictionary<int, ShipStatus>();\r
         private readonly ShipMaster _shipMaster;\r
+        private readonly ShipInventry _shipInventry;\r
         private readonly ItemInfo _itemInfo;\r
         private readonly List<int> _escapedShips = new List<int>();\r
         private ShipStatus[] _battleResult = new ShipStatus[0];\r
@@ -63,25 +63,25 @@ namespace KancolleSniffer.Model
             }\r
         }\r
 \r
-        public ShipInfo(ShipMaster shipMaster, ItemInfo itemInfo)\r
+        public ShipInfo(ShipMaster shipMaster, ShipInventry shipInventry, ItemInfo itemInfo)\r
         {\r
             _shipMaster = shipMaster;\r
+            _shipInventry = shipInventry;\r
             _fleets = Enumerable.Range(0, FleetCount).Select((x, i) => new Fleet(this, i)).ToArray();\r
             _itemInfo = itemInfo;\r
-            ClearShipInfo();\r
         }\r
 \r
         public void InspectMaster(dynamic json)\r
         {\r
             _shipMaster.Inspect(json);\r
-            ClearShipInfo();\r
+            _shipInventry.Clear();\r
         }\r
 \r
         public void InspectShip(dynamic json)\r
         {\r
             if (json.api_deck_port()) // port\r
             {\r
-                ClearShipInfo();\r
+                _shipInventry.Clear();\r
                 for (var i = 0; i < FleetCount; i++)\r
                     _fleets[i].State = FleetState.Port;\r
                 InspectDeck(json.api_deck_port);\r
@@ -140,12 +140,6 @@ namespace KancolleSniffer.Model
                 .SelectMany(fleet => fleet.Deck.Select(id => (ShipStatus)GetStatus(id).Clone())).ToArray();\r
         }\r
 \r
-        private void ClearShipInfo()\r
-        {\r
-            _shipInfo.Clear();\r
-            _shipInfo[-1] = new ShipStatus();\r
-        }\r
-\r
         public void InspectDeck(dynamic json)\r
         {\r
             foreach (var entry in json)\r
@@ -186,10 +180,10 @@ namespace KancolleSniffer.Model
                     Lucky = (int)entry.api_lucky[0],\r
                     Locked = entry.api_locked() && entry.api_locked == 1\r
                 };\r
-                _shipInfo[id] = ship;\r
+                _shipInventry.Add(ship);\r
                 _numEquipsChecker.Check(ship);\r
             }\r
-            _numEquipsChecker.MaxId = _shipInfo.Keys.Max();\r
+            _numEquipsChecker.MaxId = _shipInventry.MaxId;\r
         }\r
 \r
         private void InspectBasic(dynamic json)\r
@@ -201,7 +195,7 @@ namespace KancolleSniffer.Model
         {\r
             foreach (var entry in json.api_ship)\r
             {\r
-                var status = _shipInfo[(int)entry.api_id];\r
+                var status = _shipInventry[(int)entry.api_id];\r
                 status.Bull = (int)entry.api_bull;\r
                 status.Fuel = (int)entry.api_fuel;\r
                 status.OnSlot = (from num in (dynamic[])entry.api_onslot select (int)num).ToArray();\r
@@ -267,12 +261,11 @@ namespace KancolleSniffer.Model
         {\r
             var values = HttpUtility.ParseQueryString(request);\r
             var ships = values["api_id_items"].Split(',').Select(int.Parse).ToArray();\r
-            if (!_shipInfo.ContainsKey(ships[0])) // 二重に実行された場合\r
+            if (!_shipInventry.Contains(ships[0])) // 二重に実行された場合\r
                 return;\r
             _itemInfo.NowShips -= ships.Length;\r
-            _itemInfo.DeleteItems(ships.SelectMany(id => _shipInfo[id].Slot).ToArray());\r
-            foreach (var id in ships)\r
-                _shipInfo.Remove(id);\r
+            _itemInfo.DeleteItems(ships.SelectMany(id => _shipInventry[id].Slot).ToArray());\r
+            _shipInventry.Remove(ships);\r
             InspectDeck(json.api_deck);\r
             InspectShip(json);\r
         }\r
@@ -281,7 +274,7 @@ namespace KancolleSniffer.Model
         {\r
             var values = HttpUtility.ParseQueryString(request);\r
             var ship = int.Parse(values["api_id"]);\r
-            _shipInfo[ship].Slot = ((int[])json.api_slot).Select(id => new ItemStatus(id)).ToArray();\r
+            _shipInventry[ship].Slot = ((int[])json.api_slot).Select(id => new ItemStatus(id)).ToArray();\r
         }\r
 \r
         public void InspectSlotDeprive(dynamic json)\r
@@ -293,15 +286,15 @@ namespace KancolleSniffer.Model
         {\r
             var values = HttpUtility.ParseQueryString(request);\r
             var delitem = int.Parse(values["api_slot_dest_flag"] ?? "0") == 1;\r
-            foreach (var ship in values["api_ship_id"].Split(',').Select(int.Parse))\r
+            foreach (var id in values["api_ship_id"].Split(',').Select(int.Parse))\r
             {\r
                 _itemInfo.NowShips--;\r
                 if (delitem)\r
-                    _itemInfo.DeleteItems(_shipInfo[ship].AllSlot);\r
-                var of = FindFleet(ship, out var oi);\r
+                    _itemInfo.DeleteItems(_shipInventry[id].AllSlot);\r
+                var of = FindFleet(id, out var oi);\r
                 if (of != null)\r
                     WithdrowShip(of, oi);\r
-                _shipInfo.Remove(ship);\r
+                _shipInventry.Remove(id);\r
             }\r
         }\r
 \r
@@ -335,28 +328,30 @@ namespace KancolleSniffer.Model
 \r
         public void RepairShip(int id)\r
         {\r
-            var s = _shipInfo[id];\r
+            var s = _shipInventry[id];\r
             s.NowHp = s.MaxHp;\r
             s.Cond = Max(40, s.Cond);\r
         }\r
 \r
         public Fleet[] Fleets => _fleets;\r
 \r
-        public ShipStatus GetStatus(int id)\r
+        public ShipStatus GetStatus(int id) => FillUp(_shipInventry[id]);\r
+\r
+        private ShipStatus FillUp(ShipStatus ship)\r
         {\r
-            if (!_shipInfo.TryGetValue(id, out var s))\r
-                return new ShipStatus();\r
-            s.Slot = s.Slot.Select(item => _itemInfo.GetStatus(item.Id)).ToArray();\r
-            s.SlotEx = _itemInfo.GetStatus(s.SlotEx.Id);\r
-            s.Escaped = _escapedShips.Contains(id);\r
-            s.Fleet = FindFleet(s.Id, out var idx);\r
-            s.DeckIndex = idx;\r
-            return s;\r
+            if (ship.Empty)\r
+                return ship;\r
+            ship.Slot = ship.Slot.Select(item => _itemInfo.GetStatus(item.Id)).ToArray();\r
+            ship.SlotEx = _itemInfo.GetStatus(ship.SlotEx.Id);\r
+            ship.Escaped = _escapedShips.Contains(ship.Id);\r
+            ship.Fleet = FindFleet(ship.Id, out var idx);\r
+            ship.DeckIndex = idx;\r
+            return ship;\r
         }\r
 \r
         public void SetItemHolder()\r
         {\r
-            foreach (var ship in _shipInfo.Values)\r
+            foreach (var ship in _shipInventry.AllShips)\r
             {\r
                 foreach (var item in ship.Slot)\r
                     _itemInfo.GetStatus(item.Id).Holder = ship;\r
@@ -366,7 +361,7 @@ namespace KancolleSniffer.Model
 \r
         public ShipSpec GetSpec(int id) => _shipMaster.GetSpec(id);\r
 \r
-        public ShipStatus[] ShipList => _shipInfo.Keys.Where(id => id != -1).Select(GetStatus).ToArray();\r
+        public ShipStatus[] ShipList => _shipInventry.AllShips.Select(FillUp).ToArray();\r
 \r
         public ShipStatus[] GetRepairList(DockInfo dockInfo)\r
             => (from s in ShipList\r
@@ -422,12 +417,11 @@ namespace KancolleSniffer.Model
 \r
         private void InjectShips(int deck, int[] nowhps, int[] maxhps, int[][] slots)\r
         {\r
-            var id = _shipInfo.Keys.Count + 1;\r
+            var id = _shipInventry.MaxId + 1;\r
             var ships = nowhps.Zip(maxhps,\r
                 (now, max) => new ShipStatus {Id = id++, NowHp = now, MaxHp = max}).ToArray();\r
             _fleets[deck].Deck = (from ship in ships select ship.Id).ToArray();\r
-            foreach (var ship in ships)\r
-                _shipInfo[ship.Id] = ship;\r
+            _shipInventry.Add(ships);\r
             foreach (var entry in ships.Zip(slots, (ship, slot) => new {ship, slot}))\r
             {\r
                 entry.ship.Slot = _itemInfo.InjectItems(entry.slot.Take(5));\r
index f055b16..02b55cf 100644 (file)
@@ -25,12 +25,14 @@ namespace KancolleSniffer
     {\r
         private bool _start;\r
         private readonly ItemMaster _itemMaster = new ItemMaster();\r
+        private readonly ItemInventry _itemInventry = new ItemInventry();\r
         private readonly ItemInfo _itemInfo;\r
+        private readonly ShipMaster _shipMaster = new ShipMaster();\r
+        private readonly ShipInventry _shipInventry = new ShipInventry();\r
+        private readonly ShipInfo _shipInfo;\r
         private readonly MaterialInfo _materialInfo = new MaterialInfo();\r
         private readonly QuestInfo _questInfo;\r
         private readonly MissionInfo _missionInfo = new MissionInfo();\r
-        private readonly ShipMaster _shipMaster = new ShipMaster();\r
-        private readonly ShipInfo _shipInfo;\r
         private readonly ConditionTimer _conditionTimer;\r
         private readonly DockInfo _dockInfo;\r
         private readonly AkashiTimer _akashiTimer;\r
@@ -77,8 +79,8 @@ namespace KancolleSniffer
         public Sniffer(bool start = false)\r
         {\r
             _start = start;\r
-            _itemInfo = new ItemInfo(_itemMaster);\r
-            _shipInfo = new ShipInfo(_shipMaster, _itemInfo);\r
+            _itemInfo = new ItemInfo(_itemMaster, _itemInventry);\r
+            _shipInfo = new ShipInfo(_shipMaster, _shipInventry, _itemInfo);\r
             _conditionTimer = new ConditionTimer(_shipInfo);\r
             _dockInfo = new DockInfo(_shipInfo, _materialInfo);\r
             _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo, _presetDeck);\r