OSDN Git Service

【節分任務】令和三年節分作戦のカウンターを実装する
[kancollesniffer/KancolleSniffer.git] / KancolleSniffer / Log / BattleLogProcessor.cs
1 // Copyright (C) 2018 Kazuhiro Fujieda <fujieda@users.osdn.me>\r
2 //\r
3 // Licensed under the Apache License, Version 2.0 (the "License");\r
4 // you may not use this file except in compliance with the License.\r
5 // You may obtain a copy of the License at\r
6 //\r
7 //    http://www.apache.org/licenses/LICENSE-2.0\r
8 //\r
9 // Unless required by applicable law or agreed to in writing, software\r
10 // distributed under the License is distributed on an "AS IS" BASIS,\r
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
12 // See the License for the specific language governing permissions and\r
13 // limitations under the License.\r
14 \r
15 using System;\r
16 using System.Collections.Generic;\r
17 using System.Linq;\r
18 using System.Text.RegularExpressions;\r
19 using KancolleSniffer.Model;\r
20 \r
21 namespace KancolleSniffer.Log\r
22 {\r
23     public class BattleLogProcessor : LogProcessor.Processor\r
24     {\r
25         private readonly Dictionary<string, string> _mapDictionary;\r
26 \r
27         public BattleLogProcessor(Dictionary<string, string> mapDictionary = null)\r
28         {\r
29             _mapDictionary = mapDictionary ?? new Dictionary<string, string>();\r
30         }\r
31 \r
32         public override string[] Process(string[] data)\r
33         {\r
34             string map;\r
35             switch (data.Length)\r
36             {\r
37                 case 35:\r
38                     data = data.Concat(Enumerable.Repeat("", 3)).ToArray();\r
39                     goto case 38;\r
40                 case 38:\r
41                     map = _mapDictionary.TryGetValue(data[1], out var num) ? num : "";\r
42                     break;\r
43                 case 39:\r
44                     map = data[38];\r
45                     break;\r
46                 case 40:\r
47                     if (data[8] == "深海5" && data[9] == "500t級軽巡洋艦")\r
48                     {\r
49                         data[8] = "深海5,500t級軽巡洋艦";\r
50                         Array.Copy(data, 10, data, 9, 30);\r
51                         goto case 39;\r
52                     }\r
53                     // 七隻分のログが出力されている\r
54                     data[21] = data[21] + "・" + data[23];\r
55                     data[22] = data[22] + "・" + data[24];\r
56                     Array.Copy(data, 24, data, 23, 15);\r
57                     goto case 38;\r
58                 default:\r
59                     Skip = true;\r
60                     return null;\r
61             }\r
62             Skip = false;\r
63             if (data[5] == "T字戦(有利)")\r
64                 data[5] = "T字有利";\r
65             if (data[5] == "T字戦(不利)")\r
66                 data[5] = "T字不利";\r
67             if (data[6].EndsWith("航行序列"))\r
68                 data[6] = data[6].Substring(0, 4);\r
69             if (data[7].EndsWith("航行序列"))\r
70                 data[7] = data[7].Substring(0, 4);\r
71             data[37] = ShortenAirBattleResult(data[37]);\r
72             var result = new string[41];\r
73             var damage = GenerateDamagedShip(data);\r
74             result[38] = damage[0];\r
75             result[39] =  damage[1];\r
76             result[40] = map;\r
77             Array.Copy(data, result, 38);\r
78             return result;\r
79         }\r
80 \r
81         private static string ShortenAirBattleResult(string result)\r
82         {\r
83             switch (result)\r
84             {\r
85                 case "制空均衡":\r
86                     return "均衡";\r
87                 case "制空権確保":\r
88                     return "確保";\r
89                 case "航空優勢":\r
90                     return "優勢";\r
91                 case "航空劣勢":\r
92                     return "劣勢";\r
93                 case "制空権喪失":\r
94                     return "喪失";\r
95                 default:\r
96                     return "";\r
97             }\r
98         }\r
99 \r
100         private static string[] GenerateDamagedShip(string[] data)\r
101         {\r
102             var badly = new List<string>();\r
103             var half = new List<string>();\r
104             for (var i = 11; i < 11 + 12; i += 2)\r
105             {\r
106                 if (data[i] == "")\r
107                     continue;\r
108                 var ship = data[i] = StripKana(data[i]);\r
109                 var hp = data[i + 1];\r
110                 try\r
111                 {\r
112                     foreach (var entry in from entry in ship.Split('・').Zip(hp.Split('・'), (s, h) => new {s, h})\r
113                         where entry.h.Contains("/")\r
114                         let nm = entry.h.Split('/').Select(int.Parse).ToArray()\r
115                         let level = ShipStatus.CalcDamage(nm[0], nm[1])\r
116                         select new {level, name = entry.s})\r
117                     {\r
118                         if (entry.level == ShipStatus.Damage.Half)\r
119                             half.Add(entry.name);\r
120                         else if (entry.level == ShipStatus.Damage.Badly)\r
121                             badly.Add(entry.name);\r
122                     }\r
123                 }\r
124                 catch (FormatException)\r
125                 {\r
126                     return new[] {"", ""};\r
127                 }\r
128             }\r
129             return new []{string.Join("・", badly), string.Join("・", half)};\r
130         }\r
131 \r
132         private static readonly Regex Kana = new Regex(@"\([^)]+\)\(", RegexOptions.Compiled);\r
133 \r
134         private static string StripKana(string name)\r
135         {\r
136             return Kana.Replace(name, "(");\r
137         }\r
138     }\r
139 }