OSDN Git Service

Merge branch 'hotfix/singleton_with_db_accessor_generator_problem'
[amulettoolsmh4/main.git] / model / db_accessor.py
1 # -*- coding: utf-8 -*-
2
3 # database のアクセス用スクリプト
4 # 2013/12/04 written by kei9 
5
6 import sqlite3
7 import sys
8
9 import db_supports
10 import mh4constnumbers
11 from skilltable import SkillTableAccessor
12 from amulettable import AmuletTableAccessor
13 from skillminmaxtable import SkillMinMaxTableAccessor
14 from seed2skill2table import Seed2Skill2TableAccessor
15 from seed2tablenumbertable import Seed2TableNumberTableAccessor
16 from seed2thresholdtable import Seed2ThresholdTableAccessor
17 from seed2inishietable import Seed2InishieTableAccessor
18 from sufficienttable import SufficientTableAccessor
19 from seed1tenuntable import Seed1TenunTableAccessor
20 from alchemysimulator import AlchemySimulator
21 from amuletsearcher import AmuletSearcher
22
23 class DataBaseAccessor(object):
24     u""" this is access class to database """
25     def __init__(self, db_name):
26         u""" db_name is database name to access """
27         self._db_name = db_name
28         self._connect = sqlite3.connect(self._db_name)
29         #self._connect.text_factory = unicode
30         #self._connect.text_factory = str
31         self._cursor = self._connect.cursor()
32
33         self._acc_skill = SkillTableAccessor(self._cursor)
34         self._acc_amulet = AmuletTableAccessor(self._cursor)
35         self._acc_minmax = SkillMinMaxTableAccessor(self._cursor)
36         self._acc_seed2skill2 = Seed2Skill2TableAccessor(self._cursor)
37         self._acc_seed2no = Seed2TableNumberTableAccessor(self._cursor)
38         self._acc_seed2threshold = Seed2ThresholdTableAccessor(self._cursor)
39         self._acc_seed2inishie = Seed2InishieTableAccessor(self._cursor)
40         self._acc_sufficient = SufficientTableAccessor(self._cursor)
41         self._acc_seed1tenun = Seed1TenunTableAccessor(self._cursor)
42         self._simulator = AlchemySimulator(self._cursor)
43         self._amulet_searcher = AmuletSearcher(self._cursor)
44
45         self._minmax_dict_by_name = self._acc_minmax.get_minmax_by_name()
46
47     def select_seed2s(self, amu_name2skill_names):
48         u""" お守り名とスキル名のリストの辞書からSeed2を特定する 
49         skill_names: (skill_name1, skill_name2, ...., skill_name7)
50         不明であればNoneあるいはNO_DATAを入れておくものとする。
51         """
52         return self._acc_seed2skill2.select_seed2s_by_name(amu_name2skill_names)
53
54     def select_seed1s(self, amu_skill_name_list, alchemy_type):
55         u""" お守り名とスキル名のリスト、および錬金の種類からseed1を返す
56         amu_skill_name_list: [(amu_name, skill_name), ....]"""
57         return self._acc_seed1tenun.select_seed1s_from_names(amu_skill_name_list, alchemy_type)
58
59     def get_minmax_dict(self, copied=False):
60         u""" お守り名と第1.第2スキル名ごとのの最大値を関連付けた辞書を返す
61         return {amulet_name:({skill1_name:(min1,max1)}, {skill2_name:(min2,max2)})}"""
62         if copied is True:
63             return self._minmax_dict_by_name.copy()
64         else:
65             return self._minmax_dict_by_name
66
67     def get_id_sorted_amulet_names(self, is_desc=False):
68         u""" お守りId順でソートされたお守り名を返す(is_desc=Trueで降順) """
69         return self._acc_amulet.get_id_sorted_names(is_desc)
70
71     def get_id_sorted_skill_names(self, is_desc=False):
72         u""" スキルId順でソートされたスキル名を返す(is_desc=Trueで降順) """
73         return self._acc_skill.get_id_sorted_names(is_desc)
74
75     def select_threshold_from_sufficient(self, amulet_name, sufficient_val):
76         u""" お守り名と充足値から、スロットごとの判定値を得る
77             return (slot1_th, slot2_th, slot3_th)
78         """
79         return self._acc_sufficient.select_thresholds_by_name(amulet_name, sufficient_val)
80
81     def select_names_from_seed2(self, seed2):
82         u""" 指定されたSeed2に対応するテーブルNo, 通しNo,
83         お守り名ごとの第2スキル名(1-7枠)、
84         判定値1(1-7枠)、判定値2(1-7枠)を返す
85         return: table_no, no, {amu_name:(skill2_names)}, threshold1s, threshold2s
86         """
87         #table no, no
88         table_no, no = self._acc_seed2no.get_table_no_from_seed2(seed2)
89         # skill2 dict
90         skill_dict = self._acc_seed2skill2.select_skill_names_by_seed2(seed2)
91         # threshold1s
92         th1s = self._acc_seed2threshold.select_thresholds_from_seed2(seed2, 1)
93         # threshold2s
94         th2s = self._acc_seed2threshold.select_thresholds_from_seed2(seed2, 2)
95
96         return table_no, no, skill_dict, th1s, th2s
97
98     def select_inishie_skill2_from_seed2(self, seed2):
99         u""" get inishie's (skill2_name, threshold1, threshold2) from seed2 value """
100         return self._acc_seed2inishie.select_names_from_seed2(seed2)
101
102     def select_names_from_seed1(self, seed1, key_alchemy):
103         u""" seed1に対応する(no, table_no, result_num, 
104         (amulet_name1, ..., amulet_name7), (skill1_name1, ..., skill1_name7))
105         の辞書を得る。存在しない場所は空文字列で置き換えてある。
106         """
107         return self._acc_seed1tenun.select_names_from_seed1(seed1, key_alchemy)
108
109     def select_table_nos_from_seed1(self, seed1, key_alchemy):
110         u""" Seed1と錬金の種類から通しNo,テーブルNo,お守り個数を返す。
111         return (no, table_no, result_num)"""
112         return self._acc_seed1tenun.select_table_nos_from_seed1(seed1, key_alchemy)
113
114     def select_near_seed1s_from_table_no(self, no, table_no, smaller_num, larger_num, alchemy_type):
115         u""" 通し番号とテーブル番および錬金の種類からその周囲のseed1の通し番号、テーブルNo.、
116         お守り個数, お守り名(1-7)、スキル名(1-7)を辞書として返す。
117         ただし辞書のキーは通し番号とする。
118         値が存在しない場所は空文字列で埋める。
119         return {no: (seed1, result_num, (amulet_names), (skill_names))}"""
120         return self._acc_seed1tenun.select_near_names_from_seed1(no, table_no, smaller_num, larger_num, alchemy_type)
121
122     def get_sufficient_value(self, amulet_name, skill1_name, skill2_name, skill1_val, skill2_val):
123         u""" 充足値を計算する。
124         指定したスキルが見つからない場合や、充足値を計算できない場合はNoneを返す 
125         skill2_nameが存在しないスキルであればskill1のみから計算する
126         return sufficient_val
127         """
128         if amulet_name in self._minmax_dict_by_name:
129             skill1_minmax, skill2_minmax = self._minmax_dict_by_name[amulet_name]
130             if skill1_name in skill1_minmax:
131                 min1, max1 = skill1_minmax[skill1_name]
132                 skill1_val = 0 if skill1_val < 0 else skill1_val
133             else:
134                 # cannot find skill1
135                 return None
136
137             if skill2_name in skill2_minmax:
138                 min2, max2 = skill2_minmax[skill2_name]
139                 skill2_val = 0 if skill2_val < 0 else skill2_val
140             else:
141                 max2 = 1
142                 skill2_val = 0
143
144             if skill1_val > max1 or skill2_val > max2:
145                 # over value
146                 return None
147
148             suff_val = (10 * skill1_val) // max1 + (10 * skill2_val) // max2
149             return suff_val
150         else:
151             return None
152
153     u""" お守り検索 """
154     def simple_select_seed2s_from_names(self, 
155             amulet_name, skill1_name, skill1_val, skill2_name, skill2_val, slot_num):
156         u""" 指定されたスキルId,スキル値、スロット数を元にして、
157         Seed1との組み合わせを無視したSeed2候補の簡易検索を行う
158         return (suff_val, threshold, th1_seed2s, th2_seed2s)"""
159         return self._amulet_searcher.simple_select_seed2s_from_names(
160                 amulet_name, skill1_name, skill1_val, skill2_name, skill2_val, slot_num)
161
162     def select_seed1s_from_fixed_seed2(self,
163             seed2, amulet_name, skill1_name, skill1_val, skill2_name, skill2_val, slot_num):
164         u""" 指定されたSeed2, スキルId、スキル値、スロット数において、
165         条件を満たすお守りが発生するSeed1を検索する
166         return (seed1s_555, seed1s_888)"""
167         return self._amulet_searcher.select_seed1s_from_fixed_seed2_names(
168                 seed2, amulet_name, skill1_name, skill1_val, skill2_name, skill2_val, slot_num)
169
170     def select_seed1s_from_names(self, 
171             amulet_name, skill1_name, skill1_val, skill2_name, skill2_val, slot_num):
172         u""" 指定されたお守り名、スキル名、スキル値、スロット数において、
173         条件を満たすお守りが発生するSeed2とSeed1のペアを検索する。
174         return {seed2:( seed1s_555, seed1s_888)} """
175         u"""
176         return self._amulet_searcher.select_seed1s_from_names(amulet_name, 
177                 skill1_name, skill1_val, skill2_name, skill2_val, slot_num)
178         """
179         raise NotImplementedError(u"Too heavy and long to calculate!")
180
181     u""" 錬金シミュレーター """
182     def simulate_nazo(self, seed1, seed2):
183         u""" なぞの錬金
184         return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
185         """
186         return self._simulator.alchemy_nazo_name(seed1, seed2)
187
188     def simulate_komyou(self, seed1, seed2):
189         u""" 光明の錬金
190         return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
191         """
192         return self._simulator.alchemy_komyou_name(seed1, seed2)
193
194     def simulate_inishie(self, seed1, seed2):
195         u""" いにしえの錬金
196         return (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
197         """
198         return self._simulator.alchemy_inishie_name(seed1, seed2)
199
200     def simulate_tenun(self, seed1, seed2, alchemy_key):
201         u""" 天運の錬金
202         return list of (skill1_name, skill1_val, skill2_name, skill2_val, slot_num, type_name)
203         """
204         return self._simulator.alchemy_tenun_name(seed1, seed2, alchemy_key)
205
206     def close(self):
207         u""" close database accessor """
208         self._cursor.close()
209         self._connect.close()
210
211 if __name__ == "__main__":
212     db = DataBaseAccessor("test.sqlite3")
213     #db._print_dicts()
214     hikari = [None, 57, None, None, None, None, None]
215     huru = [54, None, None, None, None, None, None]
216     #yuga = [None, None, 98, 75, None, None, None]
217     yuga = [None, None, 98, None, None, None, None]
218     dic = {2:hikari, 3:huru, 4:yuga}
219     #seeds = db.select_seeds(dic)
220     seeds = set([58241, 176])
221     skill_dic, slot_dic = db.select_skills_from_seeds(seeds)
222
223     print "seeds: ", seeds
224     print "amu_id to seed2skill dict: ", skill_dic
225     print "seed2slot dict", slot_dic
226     db.close()