FangAnLogic.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. import Common
  2. import GaoNengLogic
  3. import SiZhuLogic
  4. from DataCenter import DataCenter
  5. from LocalModel import BaZi, GaoNeng, SiZhu, SiZhuWeiZhi, PingJia, Score
  6. def calc_fangan(bazi: BaZi, dc: DataCenter):
  7. for tg in Common.tiangan_ary:
  8. gns1 = GaoNengLogic.fix_gaoneng_by_text(tg, bazi.sizhu_tiangans(), bazi, -1, dc)
  9. sz = __build_fangan_info(tg, gns1, bazi, dc)
  10. for item in gns1:
  11. __calc_gaoneng_extra_power(item, sz)
  12. GaoNengLogic.__calc_fangxiang(item, -1)
  13. __update_fangan_gaoneng_powers(sz, bazi)
  14. __calc_pingjia(sz, bazi)
  15. for dz in Common.dizhi_ary:
  16. gns2 = GaoNengLogic.fix_gaoneng_by_text(dz, bazi.sizhu_dizhis(), bazi, -1, dc)
  17. sz = __build_fangan_info(dz, gns2, bazi, dc)
  18. for item in gns2:
  19. __calc_gaoneng_extra_power(item, sz)
  20. GaoNengLogic.__calc_fangxiang(item, -1)
  21. __update_fangan_gaoneng_powers(sz, bazi)
  22. __calc_pingjia(sz, bazi)
  23. def __build_fangan_info(key: str, gns: [GaoNeng], bazi: BaZi, dc: DataCenter):
  24. isTianGan = Common.is_tiangan(key)
  25. sz = SiZhu(bazi.qiankun, isTianGan, key, SiZhuWeiZhi.extra)
  26. if isTianGan:
  27. SiZhuLogic.__fill_sizhu_of_tiangan(sz)
  28. SiZhuLogic.__fill_shishen(bazi.riGan, sz)
  29. else:
  30. SiZhuLogic.__fill_sizhu_of_dizhi(sz)
  31. tg = Common.get_tiangan_by_dizhi(sz.text)
  32. SiZhuLogic.__fill_sizhu_of_zhangsheng(sz, tg, bazi.riGan.text)
  33. SiZhuLogic.__fill_cang_gan(sz, bazi.riGan)
  34. SiZhuLogic.__fill_shishen(bazi.riGan, sz)
  35. sz.gaonengs = gns
  36. if not sz.isTianGan:
  37. SiZhuLogic.__check_muku(sz, bazi, dc, sz.gaonengs)
  38. sz.power = dc.get_shishen_power(sz.shiShen)
  39. if sz.power == 0:
  40. sz.power = dc.get_power_step(sz.wuXing)
  41. per = dc.get_cangan_power_percentage_by_zhu(sz)
  42. sz.update_canggan_powers(per)
  43. sz.selfPower = sz.get_canggan_power_by_wuxing(sz.wuXing)
  44. sz.check_lushen(bazi.riGan.text)
  45. bazi.fangans.append(sz)
  46. return sz
  47. def __update_fangan_gaoneng_powers(sz: SiZhu, bazi: BaZi):
  48. # 记录新增的高能关系对其他柱的影响
  49. sz.extraGaoNengMap = {}
  50. for i in range(1, 9):
  51. sz.extraGaoNengMap[i] = []
  52. for gn in sz.gaonengs:
  53. if gn.zhu1 != -1:
  54. gn1 = gn.copySelf()
  55. GaoNengLogic.__calc_fangxiang(gn1, gn1.zhu1)
  56. sz.extraGaoNengMap[gn.zhu1].append(gn1)
  57. if gn.zhu2 != -1:
  58. gn2 = gn.copySelf()
  59. GaoNengLogic.__calc_fangxiang(gn2, gn2.zhu2)
  60. sz.extraGaoNengMap[gn.zhu2].append(gn2)
  61. if gn.zhu3 is not None and gn.zhu3 != -1:
  62. gn3 = gn.copySelf()
  63. GaoNengLogic.__calc_fangxiang(gn3, gn3.zhu3)
  64. sz.extraGaoNengMap[gn.zhu3].append(gn3)
  65. def __calc_gaoneng_extra_power(gn: GaoNeng, sz: SiZhu):
  66. # 由于是新增的四柱导致的高能关系变化,所以有可能新增的在原局并不存在
  67. # 这会导致原先计算的gn.power 等于0
  68. # 而既然新增了,那么对应的力量也应该是增加的
  69. # 这会导致冲穿的结果可能不同
  70. wuxing = gn.wuxing1
  71. index = 1
  72. if gn.zhu2 == -1:
  73. wuxing = gn.wuxing2
  74. index = 2
  75. elif gn.zhu3 == -1:
  76. wuxing = gn.wuxing3
  77. index = 3
  78. power = sz.get_canggan_power_by_wuxing(wuxing)
  79. if index == 1:
  80. gn.extraPower1 = power
  81. elif index == 2:
  82. gn.extraPower2 = power
  83. elif index == 3:
  84. gn.extraPower3 = power
  85. def __calc_pingjia(sz: SiZhu, bazi: BaZi):
  86. sz.pingjia = PingJia()
  87. sz.pingjia.mubiao.append(__calc_guansha_score("官", sz))
  88. sz.pingjia.mubiao.append(__calc_guansha_score("杀", sz))
  89. sz.pingjia.mubiao.append(__calc_caixing_score("财", sz))
  90. sz.pingjia.mubiao.append(__calc_caixing_score("才", sz))
  91. sz.pingjia.genji.append(__calc_yinxiao_score("印", sz))
  92. sz.pingjia.genji.append(__calc_yinxiao_score("枭", sz))
  93. sz.pingjia.zhuli.append(__calc_bijie_score("比", sz))
  94. sz.pingjia.zhuli.append(__calc_bijie_score("劫", sz))
  95. __calc_shouhu_score(sz, bazi)
  96. __calc_lushen_score(sz, bazi)
  97. sz.pingjia.calc_scores()
  98. def __calc_guansha_score(key: str, sz: SiZhu):
  99. sc = Score(key)
  100. gnsHe = __find_gaoneng_in_zhu(key, "合", sz)
  101. # 没有合得1分,有合看合什么依次评分
  102. if len(gnsHe) == 0:
  103. sc.he = 1
  104. for gn in gnsHe:
  105. other = gn.shishen1
  106. if gn.shishen1 == key:
  107. other = gn.shishen2
  108. he = 0
  109. if other == "印":
  110. he = 10
  111. elif other == "食":
  112. he = 9
  113. elif other == "财":
  114. he = 8
  115. elif other == "枭":
  116. he = 7
  117. elif other == "才":
  118. he = 6
  119. elif other == "比":
  120. he = 5
  121. elif other == "伤":
  122. he = 4
  123. elif other == "劫":
  124. he = 3
  125. # sz.pingjia.mubiaoDetail.append(key + "合" + other + "+" + str(he))
  126. sc.he += he
  127. # 暗合与合一样的记分方式
  128. gnsAnHe = __find_gaoneng_in_zhu(key, "暗合", sz)
  129. if len(gnsAnHe) == 0:
  130. sc.anHe = 1
  131. for gn in gnsAnHe:
  132. other = gn.shishen1
  133. if gn.shishen1 == key:
  134. other = gn.shishen2
  135. anHe = 0
  136. if other == "印":
  137. anHe = 10
  138. elif other == "食":
  139. anHe = 9
  140. elif other == "财":
  141. anHe = 8
  142. elif other == "枭":
  143. anHe = 7
  144. elif other == "才":
  145. anHe = 6
  146. elif other == "比":
  147. anHe = 5
  148. elif other == "伤":
  149. anHe = 4
  150. elif other == "劫":
  151. anHe = 3
  152. sc.anHe += anHe
  153. # sz.pingjia.mubiaoDetail.append(key + "暗合" + other + "+" + str(anHe))
  154. gnsChong = __find_gaoneng_in_zhu(key, "冲", sz)
  155. # 没有冲给5分,有冲冲赢了给分,没赢不得分
  156. if len(gnsChong) == 0:
  157. sc.chong = 5
  158. for gn in gnsChong:
  159. other = gn.shishen1
  160. powerOther = gn.power1 + gn.extraPower1
  161. powerSelf = gn.power2 + gn.extraPower2
  162. if gn.shishen1 == key:
  163. other = gn.shishen2
  164. powerSelf = gn.power1 + gn.extraPower1
  165. powerOther = gn.power2 + gn.extraPower2
  166. chong = 0
  167. if powerSelf < powerOther:
  168. if other in ["食", "伤"]:
  169. chong = 10
  170. if other in ["比", "劫"]:
  171. chong = 9
  172. sc.chong += chong
  173. # sz.pingjia.mubiaoDetail.append(key + "冲" + other + "+" + str(chong))
  174. gnsChuan = __find_gaoneng_in_zhu(key, "穿", sz)
  175. # 没有穿满分,一个穿扣一分
  176. sc.chuan = 10 - len(gnsChuan)
  177. # sz.pingjia.mubiaoDetail.append(key + "穿" + str(len(gnsChuan)) + "次+" + str(sc.chuan))
  178. gnsPo = __find_gaoneng_in_zhu(key, "破", sz)
  179. # 没有破满分,一个破扣一分
  180. sc.po = 10 - len(gnsPo)
  181. # sz.pingjia.mubiaoDetail.append(key + "破" + str(len(gnsPo)) + "次+" + str(sc.po))
  182. sc.calcTotal()
  183. return sc
  184. def __calc_caixing_score(key: str, sz: SiZhu):
  185. sc = Score(key)
  186. gnsHe = __find_gaoneng_in_zhu(key, "合", sz)
  187. # 没有合得1分,有合看合什么依次评分
  188. if len(gnsHe) == 0:
  189. sc.he = 1
  190. for gn in gnsHe:
  191. other = gn.shishen1
  192. if gn.shishen1 == key:
  193. other = gn.shishen2
  194. he = 0
  195. if other == "印":
  196. he = 10
  197. elif other == "官":
  198. he = 9
  199. elif other == "食":
  200. he = 8
  201. elif other == "枭":
  202. he = 7
  203. elif other == "比":
  204. he = 6
  205. elif other == "伤":
  206. he = 5
  207. elif other == "劫":
  208. he = 4
  209. elif other == "杀":
  210. he = 3
  211. # sz.pingjia.mubiaoDetail.append(key + "合" + other + "+" + str(he))
  212. sc.he += he
  213. # 暗合与合一样的记分方式
  214. gnsAnHe = __find_gaoneng_in_zhu(key, "暗合", sz)
  215. if len(gnsAnHe) == 0:
  216. sc.anHe = 1
  217. for gn in gnsAnHe:
  218. other = gn.shishen1
  219. if gn.shishen1 == key:
  220. other = gn.shishen2
  221. anHe = 0
  222. if other == "印":
  223. anHe = 10
  224. elif other == "官":
  225. anHe = 9
  226. elif other == "食":
  227. anHe = 8
  228. elif other == "枭":
  229. anHe = 7
  230. elif other == "比":
  231. anHe = 6
  232. elif other == "伤":
  233. anHe = 5
  234. elif other == "劫":
  235. anHe = 4
  236. elif other == "杀":
  237. anHe = 3
  238. # sz.pingjia.mubiaoDetail.append(key + "暗合" + other + "+" + str(anHe))
  239. sc.anHe += anHe
  240. gnsChong = __find_gaoneng_in_zhu(key, "冲", sz)
  241. # 没有冲给5分,有冲冲赢了给分,没赢不得分
  242. if len(gnsChong) == 0:
  243. sc.chong = 5
  244. for gn in gnsChong:
  245. other = gn.shishen1
  246. powerOther = gn.power1 + gn.extraPower1
  247. powerSelf = gn.power2 + gn.extraPower2
  248. if gn.shishen1 == key:
  249. other = gn.shishen2
  250. powerSelf = gn.power1 + gn.extraPower1
  251. powerOther = gn.power2 + gn.extraPower2
  252. chong = 0
  253. if powerSelf < powerOther:
  254. if other in ["印", "枭"]:
  255. chong = 10
  256. if other in ["比", "劫"]:
  257. chong = 9
  258. # sz.pingjia.mubiaoDetail.append(key + "冲" + other + "+" + str(chong))
  259. sc.chong += chong
  260. gnsChuan = __find_gaoneng_in_zhu(key, "穿", sz)
  261. # 没有穿满分,一个穿扣一分
  262. sc.chuan = 10 - len(gnsChuan)
  263. # sz.pingjia.mubiaoDetail.append(key + "穿" + str(len(gnsChuan)) + "次+" + str(sc.chuan))
  264. gnsPo = __find_gaoneng_in_zhu(key, "破", sz)
  265. # 没有破满分,一个破扣一分
  266. sc.po = 10 - len(gnsPo)
  267. # sz.pingjia.mubiaoDetail.append(key + "破" + str(len(gnsPo)) + "次+" + str(sc.po))
  268. sc.calcTotal()
  269. return sc
  270. def __calc_yinxiao_score(key: str, sz: SiZhu):
  271. sc = Score(key)
  272. gnsHe = __find_gaoneng_in_zhu(key, "合", sz)
  273. # 没有合得1分,有合看合什么依次评分
  274. if len(gnsHe) == 0:
  275. sc.he = 1
  276. for gn in gnsHe:
  277. other = gn.shishen1
  278. if gn.shishen1 == key:
  279. other = gn.shishen2
  280. he = 0
  281. if other == "食":
  282. he = 10
  283. elif other == "伤":
  284. he = 9
  285. elif other == "比":
  286. he = 8
  287. elif other == "劫":
  288. he = 7
  289. sc.he += he
  290. # 暗合与合一样的记分方式
  291. gnsAnHe = __find_gaoneng_in_zhu(key, "暗合", sz)
  292. if len(gnsAnHe) == 0:
  293. sc.anHe = 1
  294. for gn in gnsAnHe:
  295. other = gn.shishen1
  296. if gn.shishen1 == key:
  297. other = gn.shishen2
  298. anHe = 0
  299. if other == "食":
  300. anHe = 10
  301. elif other == "伤":
  302. anHe = 9
  303. elif other == "比":
  304. anHe = 8
  305. elif other == "劫":
  306. anHe = 7
  307. sc.anHe += anHe
  308. gnsChong = __find_gaoneng_in_zhu(key, "冲", sz)
  309. # 没有冲给5分,有冲冲赢了给分,没赢不得分
  310. if len(gnsChong) == 0:
  311. sc.chong = 5
  312. for gn in gnsChong:
  313. other = gn.shishen1
  314. powerOther = gn.power1 + gn.extraPower1
  315. powerSelf = gn.power2 + gn.extraPower2
  316. if gn.shishen1 == key:
  317. other = gn.shishen2
  318. powerSelf = gn.power1 + gn.extraPower1
  319. powerOther = gn.power2 + gn.extraPower2
  320. chong = 0
  321. if powerSelf < powerOther:
  322. if other in ["食"]:
  323. chong = 10
  324. if other in ["伤"]:
  325. chong = 9
  326. sc.chong += chong
  327. gnsChuan = __find_gaoneng_in_zhu(key, "穿", sz)
  328. # 没有穿满分,一个穿扣一分
  329. sc.chuan = 10 - len(gnsChuan)
  330. gnsPo = __find_gaoneng_in_zhu(key, "破", sz)
  331. # 没有破满分,一个破扣一分
  332. sc.po = 10 - len(gnsPo)
  333. sc.calcTotal()
  334. return sc
  335. def __calc_bijie_score(key: str, sz: SiZhu):
  336. sc = Score(key)
  337. gnsHe = __find_gaoneng_in_zhu(key, "合", sz)
  338. # 没有合得1分,有合看合什么依次评分
  339. if len(gnsHe) == 0:
  340. sc.he = 1
  341. for gn in gnsHe:
  342. other = gn.shishen1
  343. if gn.shishen1 == key:
  344. other = gn.shishen2
  345. he = 0
  346. if other == "食":
  347. he = 10
  348. elif other == "伤":
  349. he = 9
  350. sc.he += he
  351. # 暗合与合一样的记分方式
  352. gnsAnHe = __find_gaoneng_in_zhu(key, "暗合", sz)
  353. if len(gnsAnHe) == 0:
  354. sc.anHe = 1
  355. for gn in gnsAnHe:
  356. other = gn.shishen1
  357. if gn.shishen1 == key:
  358. other = gn.shishen2
  359. anHe = 0
  360. if other == "食":
  361. anHe = 10
  362. elif other == "伤":
  363. anHe = 9
  364. sc.anHe += anHe
  365. # 比肩不看冲
  366. sc.chong = 1
  367. gnsChuan = __find_gaoneng_in_zhu(key, "穿", sz)
  368. # 没有穿满分,一个穿扣一分
  369. sc.chuan = 10 - len(gnsChuan)
  370. gnsPo = __find_gaoneng_in_zhu(key, "破", sz)
  371. # 没有破满分,一个破扣一分
  372. sc.po = 10 - len(gnsPo)
  373. sc.calcTotal()
  374. return sc
  375. def __calc_shouhu_score(sz: SiZhu, bazi: BaZi):
  376. # 计算地支六合化穿破刑的部分,冲不用保护,冲可能是好事
  377. for gn in sz.gaonengs:
  378. if gn.leibie == "地支合":
  379. # 对自己这柱的保护
  380. selfShouHuChuan = __count_gaoneng_in_list(sz.gaonengs, "穿")
  381. selfShouHuPo = __count_gaoneng_in_list(sz.gaonengs, "破")
  382. selfShouHuXing = __count_gaoneng_in_list(sz.gaonengs, "刑")
  383. selfShouHuLuShen = 0
  384. if sz.isLuShen:
  385. selfShouHuLuShen += 1
  386. if sz.isBanLu:
  387. selfShouHuLuShen += 0.5
  388. selfShouHu = selfShouHuLuShen * 1.3 + selfShouHuChuan * 1.2 + selfShouHuPo * 1.1 + selfShouHuXing * 1
  389. # 对其他柱的保护
  390. otherShouHu = 0
  391. other = gn.zhu1
  392. if sz.text == gn.arg1:
  393. other = gn.zhu2
  394. zhu = bazi.getZhuByWeiZhi(other)
  395. if zhu is not None:
  396. otherShouHuChuan = __count_gaoneng_in_list(zhu.gaonengs, "穿")
  397. otherShouHuPo = __count_gaoneng_in_list(zhu.gaonengs, "破")
  398. otherShouHuXing = __count_gaoneng_in_list(zhu.gaonengs, "刑")
  399. otherShouHuLuShen = 0
  400. if zhu.isLuShen:
  401. otherShouHuLuShen += 1
  402. if zhu.isBanLu:
  403. otherShouHuLuShen += 0.5
  404. otherShouHu = otherShouHuLuShen * 1.3 + otherShouHuChuan * 1.2 + otherShouHuPo * 1.1 + otherShouHuXing * 1
  405. sz.pingjia.shouhuScore += (selfShouHu + otherShouHu)
  406. sz.pingjia.shouhuScore *= 1000
  407. def __calc_lushen_score(sz: SiZhu, bazi: BaZi):
  408. if sz.isLuShen:
  409. sz.pingjia.lushenScore += 2
  410. if sz.isBanLu:
  411. sz.pingjia.lushenScore += 1
  412. he = __count_gaoneng_in_list_by_leibie(sz.gaonengs, "地支合")
  413. if he == 0: # 没有地支合的保护,才会被破才穿
  414. po = __count_gaoneng_in_list(sz.gaonengs, "破")
  415. if po > 0:
  416. sz.pingjia.lushenScore *= 0.5
  417. chuan = __count_gaoneng_in_list(sz.gaonengs, "穿")
  418. if chuan > 0:
  419. sz.pingjia.lushenScore = 0
  420. sz.pingjia.lushenScore *= 1000
  421. def __find_gaoneng_in_zhu(key: str, guanxi: str, sz: SiZhu) -> [GaoNeng]:
  422. result: [GaoNeng] = []
  423. for gn in sz.gaonengs:
  424. if gn.guanxi == guanxi:
  425. if gn.shishen1 == key or gn.shishen2 == key:
  426. result.append(gn)
  427. return result
  428. def __count_gaoneng_in_list(gns: [GaoNeng], guanxi: str):
  429. ct = 0
  430. for gn in gns:
  431. if gn.guanxi == guanxi:
  432. ct += 1
  433. return ct
  434. def __count_gaoneng_in_list_by_leibie(gns: [GaoNeng], leibie: str):
  435. ct = 0
  436. for gn in gns:
  437. if gn.leibie == leibie:
  438. ct += 1
  439. return ct