diff --git a/lua/server/ai/skill.lua b/lua/server/ai/skill.lua index 659997f70c2660e4a54989660dac1dc72350a826..6047c6a7e9b2140848dd22075133771631f29f9f 100644 --- a/lua/server/ai/skill.lua +++ b/lua/server/ai/skill.lua @@ -65,8 +65,8 @@ end -- 但是也没办法一次性算出所有情况并拿去遍历。为此,只要每次调用都算出和之前不一样的解法就行了 local function cardsAcceptable(smart_ai) - -- return smart_ai:okButtonEnabled() or (#smart_ai:getEnabledTargets() > 0) - return false + return smart_ai:okButtonEnabled() or (#smart_ai:getEnabledTargets() > 0) + -- return false end local function cardsString(cards) @@ -83,10 +83,12 @@ function SkillAI:searchCardSelections(smart_ai) local selected = smart_ai:getSelectedCards() -- 搜索起点 local to_remove = selected[#selected] -- 空情况也考虑一下 + verbose(1, "当前已选:%s", table.concat(selected, "|")) if #selected == 0 and not searched[""] and cardsAcceptable(smart_ai) then searched[""] = true return {} end + verbose(1, "当前可选:%s", table.concat(smart_ai:getEnabledCards(), "|")) -- 从所有可能的下一步找 for _, cid in ipairs(smart_ai:getEnabledCards()) do table.insert(selected, cid) @@ -123,12 +125,14 @@ function SkillAI:searchTargetSelections(smart_ai) local searched = {} local function search() local selected = smart_ai:getSelectedTargets() -- 搜索起点 - local to_remove = selected[#selected] + -- local to_remove = selected[#selected] -- 空情况也考虑一下 + verbose(1, "当前已选:%s", table.concat(table.map(selected, Util.IdMapper), "|")) if #selected == 0 and not searched[""] and smart_ai:okButtonEnabled() then searched[""] = true return {} end + verbose(1, "当前可选:%s", table.concat(table.map(smart_ai:getEnabledTargets(), Util.IdMapper), "|")) -- 从所有可能的下一步找 for _, target in ipairs(smart_ai:getEnabledTargets()) do table.insert(selected, target) diff --git a/lua/server/ai/smart_ai.lua b/lua/server/ai/smart_ai.lua index cf0224966612748107317ca8b721dea7822ed6df..90098e0b621ce4bef2c8cf832fe5e000f5c09613 100644 --- a/lua/server/ai/smart_ai.lua +++ b/lua/server/ai/smart_ai.lua @@ -96,11 +96,11 @@ function SmartAI.static:setSkillAI(key, spec, inherit) local ret, val = v(_self, _ai) if ret and type(ret) == "table" then if ret.cards then - ret.card = { skill = ai.skill.name, subcards = ret.cards } + ret.card = { skill = _self.skill.name, subcards = ret.cards } ret.cards = nil end if not ret.card then - ret.card = { skill = ai.skill.name, subcards = Util.DummyTable } + ret.card = { skill = _self.skill.name, subcards = Util.DummyTable } end if ret.targets then if type(ret.targets[1]) == "table" then @@ -240,7 +240,10 @@ function SmartAI:handleAskForUseActiveSkill() if current_skill then ai = fk.ai_skills[current_skill.name] end if not ai then ai = fk.ai_skills[name] end if not ai then return "" end - return ai:think(self) + verbose(1, "正在询问技能:%s", ai.skill.name) + local ret, real_val = ai:think(self) + verbose(1, "%s: 思考结果是%s, 收益是%s", ai.skill.name, json.encode(ret), json.encode(real_val)) + return ret, real_val end function SmartAI:handlePlayCard() diff --git a/standard/ai/init.lua b/standard/ai/init.lua index 54c5298ac7681951daf29675ebdc100c03529977..d574025bab73cdc032a890cbc61af117c440433a 100644 --- a/standard/ai/init.lua +++ b/standard/ai/init.lua @@ -82,7 +82,7 @@ SmartAI:setSkillAI("tuxi", { if i == 2 then break end end if #targets == 0 or total_benefit <= 0 then return "" end - return { targets = targets } + return { targets = targets }, total_benefit end, }) @@ -104,8 +104,12 @@ SmartAI:setSkillAI("jizhi", { SmartAI:setSkillAI("zhiheng", { think = function(self, ai) + local player = ai.player local cards = ai:getEnabledCards() - return { cards = cards }, 0 + return { cards = cards }, ai:getBenefitOfEvents(function(logic) + logic:throwCard(cards, self.skill.name, player, player) + logic:drawCards(player, #cards, self.skill.name) + end) end, }) @@ -143,3 +147,13 @@ SmartAI:setSkillAI("xiaoji", { }) SmartAI:setSkillAI("biyue", nil, "jizhi") + +SmartAI:setSkillAI("wusheng", nil, "spear_skill") + +SmartAI:setSkillAI("longdan", nil, "spear_skill") + +SmartAI:setSkillAI("guose", nil, "spear_skill") + +SmartAI:setSkillAI("jijiu", nil, "spear_skill") + +SmartAI:setSkillAI("qixi", nil, "spear_skill") \ No newline at end of file diff --git a/standard_cards/ai/init.lua b/standard_cards/ai/init.lua index 3e3e44ee13a5730d67d41b9241a7f637c70e76c8..67acbe448b1a32eebeeb234456f8e3a07cddc2b4 100644 --- a/standard_cards/ai/init.lua +++ b/standard_cards/ai/init.lua @@ -136,3 +136,55 @@ SmartAI:setTriggerSkillAI("#nioh_shield_skill", { return self.skill:triggerable(event, target, player, data) end, }) + +SmartAI:setSkillAI("spear_skill", { + choose_targets = function(self, ai) + local logic = AIGameLogic:new(ai) + local val_func = function(targets) + logic.benefit = 0 + logic:useCard({ + from = ai.player.id, + tos = table.map(targets, function(p) return { p.id } end), + card = self.skill:viewAs(ai:getSelectedCards()), + }) + verbose(1, "目前状况下,对[%s]的预测收益为%d", table.concat(table.map(targets, function(p)return tostring(p)end), "+"), logic.benefit) + return logic.benefit + end + local best_targets, best_val = nil, -100000 + for targets in self:searchTargetSelections(ai) do + local val = val_func(targets) + if (not best_targets) or (best_val < val) then + best_targets, best_val = targets, val + end + end + return best_targets or {}, best_val + end, + think = function(self, ai) + local skill_name = self.skill.name + local estimate_val = self:getEstimatedBenefit(ai) + -- local cards = ai:getEnabledCards() + -- cards = table.random(cards, math.min(#cards, 5)) --[[@as integer[] ]] + -- local cid = table.random(cards) + + local best_cards, best_ret, best_val = nil, "", -100000 + for cards in self:searchCardSelections(ai) do + local ret, val = self:chooseTargets(ai) + verbose(1, "就目前选择的这张牌,考虑[%s],收益为%d", table.concat(table.map(ret, function(p)return tostring(p)end), "+"), val) + val = val or -100000 + if best_val < val then + best_cards, best_ret, best_val = cards, ret, val + end + -- if best_val >= estimate_val then break end + end + + if best_ret and best_ret ~= "" then + if best_val < 0 then + return "", best_val + end + + best_ret = { cards = best_cards, targets = best_ret } + end + + return best_ret, best_val + end, +}, "__card_skill") \ No newline at end of file