From 0670598bf4b8b8f96e8523fb2aac3bdd21403b00 Mon Sep 17 00:00:00 2001 From: hefanyang Date: Sun, 24 May 2026 10:48:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=B8=E6=88=8F=E5=8F=AF=E4=BB=A5=E8=BF=90?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- card_game/__pycache__/ai.cpython-312.pyc | Bin 10014 -> 10862 bytes card_game/__pycache__/main.cpython-312.pyc | Bin 31864 -> 32061 bytes card_game/__pycache__/player.cpython-312.pyc | Bin 9866 -> 9811 bytes card_game/ai.py | 48 ++++++++++++------- card_game/main.py | 7 ++- card_game/player.py | 2 +- saved_decks/qi.json | 35 ++++++++++++++ 7 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 saved_decks/qi.json diff --git a/card_game/__pycache__/ai.cpython-312.pyc b/card_game/__pycache__/ai.cpython-312.pyc index abd2ed98ad507361db246b0f2d5e7f126ce0d556..3a0805a9245551e0452018394f61468d8c3043de 100644 GIT binary patch delta 1574 zcmb7EZA@EL7(VB=_x6L*QhI4`>Ft2F^5vF6sLV0c;ksJbKn6yf%1Wgjqv30}9sBTh zGP6ZA#Fd=HMQ60pKTh_8NzCw<(;v%>3F%D>Ep=1&h!< z-trhD(js#TlOqaIAw)!l3!GODQbS;n>bGI9Qd9;tNKYA{939oLXq;7|yQQjjyTu-o^MPcd)3H+_9IyK6Hn(ALztpMl~Gr3cj(SfWNLtP?4aP0J&S} zAz;UlDGH1QMo)SV3*%$qO!4L>bZlZ`TnJ}WzL61c&V_cHS#)5F5sjNI)L9D6n9KER z3@9_D*m{YrPq16Fpagwsb{tCcwiNG_cxQrdp6*O@_SmSzHBGm#>bP`G!-{1fRyE&t zb^n$9*IX%AzvSvqxV#Cc_k*^$Wgx1=uxhZ}v{uGAY5U%!)jjL}5pT>=Lr>D$8+D^U z%DYWfC90ik)w$%g5?h;K>(_xn^)$L_w!QH{dY$3?>9ZB#$rQ8B9Dm_z8?x_@f>Ss~tTb_U7tXwz`uqy%K*lfcr3l z+wmI!2jLzn>Q1vZT&&dqnqX$bgSIexl;1fS`C)9Ru4){)7p*f9te0J+{o5~$^c$U z06z#r4&1|U8f+a~nQskpjMt&9qmjApkYl`o{msmG*x$S`W!Zo*gHBnO;4o_6vJ0MB zIJdG7jXiyF_IaM|>e)I4s~%`rYn^@1r@}r_3ZF948L$A~8=A&|t_g ze&48XD1h0QjV?;)$Q}9^J>zKPP7o5A$_z8=JK;StA-qUDeQ4S-45JHK$0bN_qfOaE qC|2DH-$J*lxw>~SgS?a>6NWVzgm4u!{RHaoGcQwcdlnGPCH@Ns(5z5DE4MYg_pZ$oT?f*0ny z=jS`;-j6f)_oxMk{Og3kbUlG@~K7 z*D8Z5xBF{6vT?B!jzkjpH>yQT#BIJ9*gp8dZno37MtN$$#487FUr~VL-I^xYf?@x! z@bTTkrCq|sozhC79XUbw@64404`lnOZ1|&fZ}i_U$J@+H>M4Wf&)6 zR_l5GNoM9K)Pi&7w2?2(7WBRrBgn!MgBXKT40sfeE3;mTP@&Q|4v z4J5%+@m}ApHWievbbnO)G0}ZlaSo4eCdMv~{Yo9pd1z`g@yvxWk7zDQJ0$Ir0f!8H zW^FuMB_kJjxE+6FG$93t>M0Z>uAFh?OjXV{(4OE>WyFh;OT+IEU)J6IgWv5R+_1hp zfBpRC@F}ld@zict?RV7vsya}4V(SX$;BGv7jL_1$irPs$9Rf2J5m#ZcyoxK5Z1r#YGQm3zUux47vO{Bqj+)s`{aZVzXM(SmO4(-N`t+c zD_qTgHgD!F%b?TvsIwF5y@&9-@YlXiM1zsc?Vz&C+(ibh6l$WLU&zlEXqBXlaK?#k z9tK!VA5knuWJ9ir3;EZl&%SD$VUa2D(sOuu{qf8dEF=Ze7=wCW4!;G5vP$3El)+w~ bNhs8P7~@;$=xvn!Q=H`R;Ra%O|M0&7bRZ*Z diff --git a/card_game/__pycache__/main.cpython-312.pyc b/card_game/__pycache__/main.cpython-312.pyc index e9caf3fcb992dc834ca273934289ba62e4cbc300..42a1eb7fc198ca58d08981d2e693621bae93a5a0 100644 GIT binary patch delta 1215 zcmbV~e`s4(6vuO3lGmg^vb0H8tLs#%e{9GKF@*aa!E;{hJBq{UomFj<%K$8KqZO{CXv#=en=98Jch814z2gir8xK+?_@+3=B|-*qf~RcM|O znrDTUIdkiRrD95)6z44V1?yu|?UU`No}Nx$v3uvN&G_L{A23h6*pb9-Lb!ZkeF z(GN@bONR&{b!+EqTH6Yfxr*f~Qh!D`Ll6klgu6Ju*9~{j(6tS&qql1SUQ|EmYS6)t zIJ?iyU#FfMSQM^b~eV9DJ(UV>R06AJF+h!YqTU zP~JqbgU~|QN^-i{Y!Q1wk!W8;Ny$mMjcScl+d$EM2A5W@r9M7-K^G&2~y6J=SywCT(&-;AO8TY`(1_Zp8 zNJKvTd0G_GG^85|c#zG^v$$3kg_A9*D9O1m;FcYLQ{|xy=fEvZxbIm9G)ZwPHIm_s z*sF;E5gyJ{hKZ>QJ+_GL>f_@O;8a>DJ_A22&z0c1Op5PwRS<|$J@!WXvRFjOizZBa1bA(zht zGmwHqt#V-&bfJ`^pN_=za{+okD1|j2Z&|fsWOv+e1K}y? diff --git a/card_game/__pycache__/player.cpython-312.pyc b/card_game/__pycache__/player.cpython-312.pyc index 6106fc675dc0df072c9ec330825a4435d456d5f2..2a4d497589f22be77131d66753af519ae5895247 100644 GIT binary patch delta 614 zcmZ9}&ubGw6bJBqlbCc9R?@Pe$+k_l=`R{VN)aVZh*n6`Vr**(ZKPsTHd}2?S(&Xt zFe;uD=|$hoo2T9iIvzas-is2UWyL~I9{dkHw9X46*g1Um?auc-X4uy^TP1B@(?W_| zpK4tju@71y$c_NZ!5`{fMS1FL`ZhXoPdBjK;ed{-5xw^TQxq4rD>Z-9w-TmSTH95> z(p28+I;Pby#M?dd>Ii7~SgqktwF=*GI`lq#ke>LOp7^}nN>7WE&?$o~o@n1;Qh4X% zY$`7&@yim=@7A3yo}l+DL^m-*#3f#U+nY|q9zDmC^zAw^M;oxtiz3tc5+eV?e4chE z#h0!ki_B8pLm0#yjzq75D zY4c(}NhU`7$$JIl7`-On5s=_>2HH~;03>cPW)^vDW)f^?6z~FxNrH$#5aG0WrjR?6 zfIo;W4I-pKM8M<^BKDFtK;|v>{DS!8{NfU@IYmJrS&z*gqTWp2;Xt+~XA!zqkP0&p z5d|X5L4+KLumBR8tVQx5HppZY1Mi8KG0A{jT4WC*z>WYpN0SMvVRM002P327=AY8i zjEpIhMP(l{rcM4Xo5q+iIZke~WeiA{Fp#*#S(=ww5?@kTka~+bH?cyK8OcVF-;0@n zgo1)Xkphq|irnlae}hpe1<1a|o{^fElUh^^c3m+GL>W|_)n*q(BT(R$E6cNi10iMd z9OZkA5tFM`EZuEEMrnfxUl0)tB0@n#EQp8)5s4te1Vp5Rh%68h2_mdOL^+6X+x%OF SiILH5@;_Ax#`?+PYBm5Xc$6#v diff --git a/card_game/ai.py b/card_game/ai.py index b278ff4..68f6c24 100644 --- a/card_game/ai.py +++ b/card_game/ai.py @@ -82,36 +82,48 @@ class AIPlayer: def _attack(self, ai): actions = [] player = self.battlefield.player + + # Frontline units: attack enemy frontline > enemy support > capital for unit in ai.get_frontline_units(): if not unit.can_attack or unit.has_attacked: continue - enemy_units = player.get_frontline_units() - if enemy_units: - killable = [u for u in enemy_units if u.current_hp <= unit.get_effective_attack()] + enemy_front = player.get_frontline_units() + enemy_support = player.get_support_units() + all_enemy = enemy_front + enemy_support + if all_enemy: + killable = [u for u in all_enemy if u.current_hp <= unit.get_effective_attack()] if killable: target = min(killable, key=lambda u: u.current_hp) else: - target = max(enemy_units, key=lambda u: u.get_effective_attack()) - dead = self.battlefield.resolve_attack(unit, target) - actions.append(("attack_unit", unit, target)) - else: - self.battlefield.attack_capital(unit) - actions.append(("attack_capital", unit)) - - # Ranged units in support attack - for unit in ai.get_support_units(): - if not unit.can_attack or unit.has_attacked or not unit.is_ranged(): - continue - enemy_units = player.get_frontline_units() - if enemy_units: - killable = [u for u in enemy_units if u.current_hp <= unit.get_effective_attack()] - target = min(killable, key=lambda u: u.current_hp) if killable else min(enemy_units, key=lambda u: u.current_hp) + target = max(all_enemy, key=lambda u: u.get_effective_attack()) self.battlefield.resolve_attack(unit, target) actions.append(("attack_unit", unit, target)) else: self.battlefield.attack_capital(unit) actions.append(("attack_capital", unit)) + # Support units: attack enemy frontline > enemy support > capital (ranged only) + for unit in ai.get_support_units(): + if not unit.can_attack or unit.has_attacked: + continue + enemy_front = player.get_frontline_units() + enemy_support = player.get_support_units() + if unit.is_ranged(): + all_enemy = enemy_front + enemy_support + if all_enemy: + killable = [u for u in all_enemy if u.current_hp <= unit.get_effective_attack()] + target = min(killable, key=lambda u: u.current_hp) if killable else min(all_enemy, key=lambda u: u.current_hp) + self.battlefield.resolve_attack(unit, target) + actions.append(("attack_unit", unit, target)) + else: + self.battlefield.attack_capital(unit) + actions.append(("attack_capital", unit)) + elif enemy_front: + killable = [u for u in enemy_front if u.current_hp <= unit.get_effective_attack()] + target = min(killable, key=lambda u: u.current_hp) if killable else min(enemy_front, key=lambda u: u.current_hp) + self.battlefield.resolve_attack(unit, target) + actions.append(("attack_unit", unit, target)) + return actions def _handle_deploy(self, card, ai): diff --git a/card_game/main.py b/card_game/main.py index 9662646..95a125f 100644 --- a/card_game/main.py +++ b/card_game/main.py @@ -267,11 +267,13 @@ class Game: opponent = self.battlefield.get_opponent(player) if unit.zone == "support": - if unit.can_attack and not unit.has_attacked and unit.is_ranged(): + if unit.can_attack and not unit.has_attacked: self.ui.selected_unit = unit self.ui.target_mode = "attack" targets = list(opponent.get_frontline_units()) - targets.append(("capital", opponent)) + targets.extend(opponent.get_support_units()) + if unit.is_ranged(): + targets.append(("capital", opponent)) self.ui.valid_targets = targets return if self.battlefield.can_move_to_frontline(player): @@ -284,6 +286,7 @@ class Game: self.ui.selected_unit = unit self.ui.target_mode = "attack" targets = list(opponent.get_frontline_units()) + targets.extend(opponent.get_support_units()) targets.append(("capital", opponent)) self.ui.valid_targets = targets diff --git a/card_game/player.py b/card_game/player.py index ada2569..4547a59 100644 --- a/card_game/player.py +++ b/card_game/player.py @@ -55,7 +55,7 @@ class Player: unit.reset_turn_flags() if unit.zone == "frontline" and unit.turn_played < turn_number: unit.can_attack = True - if unit.zone == "support" and unit.is_ranged() and unit.turn_played < turn_number: + if unit.zone == "support" and unit.turn_played < turn_number: unit.can_attack = True # Chu healer diff --git a/saved_decks/qi.json b/saved_decks/qi.json new file mode 100644 index 0000000..66fea01 --- /dev/null +++ b/saved_decks/qi.json @@ -0,0 +1,35 @@ +{ + "faction": "qi", + "cards": [ + "qi_tongshang", + "qi_tongshang", + "qi_tongshang", + "qi_changgong", + "qi_changgong", + "qi_changgong", + "qi_guanzhong", + "qi_guanzhong", + "qi_jiji", + "qi_jiji", + "qi_jiji", + "qi_shangren", + "qi_shangren", + "qi_shangren", + "qi_sunbin", + "qi_sunbin", + "qi_gongshou", + "qi_gongshou", + "qi_gongshou", + "qi_maobing", + "qi_maobing", + "qi_maobing", + "qi_fuguo", + "qi_tianqi", + "qi_tianqi", + "ally_wu_shuijun", + "ally_wu_shuijun", + "ally_wu_shuijun", + "ally_yue_nvjian", + "ally_yue_nvjian" + ] +} \ No newline at end of file