[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
[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
<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
--- /dev/null
+// 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
{\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
\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
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
\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
\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
\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
_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
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
}\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
.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
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
{\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
{\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
{\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
{\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
\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
\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
\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
{\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
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