parent
ecf8ff447a
commit
f7f1bb8537
|
@ -79,7 +79,7 @@ function Card:initialize(name, suit, number, color)
|
|||
self.is_derived = true
|
||||
end
|
||||
|
||||
local name_splited = name:split("__")
|
||||
local name_splited = self.name:split("__")
|
||||
self.trueName = name_splited[#name_splited]
|
||||
|
||||
if suit == Card.Spade or suit == Card.Club then
|
||||
|
@ -280,6 +280,29 @@ function Card:getTypeString()
|
|||
return "notype"
|
||||
end
|
||||
|
||||
local subtype_string_table = {
|
||||
[Card.SubtypeArmor] = "armor",
|
||||
[Card.SubtypeWeapon] = "weapon",
|
||||
[Card.SubtypeTreasure] = "treasure",
|
||||
[Card.SubtypeDelayedTrick] = "delayed_trick",
|
||||
[Card.SubtypeDefensiveRide] = "defensive_ride",
|
||||
[Card.SubtypeOffensiveRide] = "offensive_ride",
|
||||
}
|
||||
|
||||
function Card:getSubtypeString()
|
||||
local t = self.sub_type
|
||||
local ret = subtype_string_table[t]
|
||||
if ret == nil then
|
||||
if self.type == Card.TypeTrick then
|
||||
return "normal_trick"
|
||||
elseif self.type == Card.TypeBasic then
|
||||
return "basic"
|
||||
end
|
||||
else
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
--- 获取卡牌点数并返回点数文字描述(仅限A/J/Q/K)。
|
||||
local function getNumberStr(num)
|
||||
if num == 1 then
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
---@field public cardType string[]
|
||||
---@field public id integer[]
|
||||
|
||||
-- v0.2.6改动: cardType会被解析为trueName数组和name数组,而不是自己单独成立
|
||||
|
||||
local numbertable = {
|
||||
["A"] = 1,
|
||||
["J"] = 11,
|
||||
|
@ -44,14 +46,34 @@ local placetable = {
|
|||
[Card.PlayerEquip] = "equip",
|
||||
}
|
||||
|
||||
local card_type_table = {}
|
||||
|
||||
local function fillCardTypeTable()
|
||||
local tmp = {}
|
||||
for _, cd in ipairs(Fk.cards) do
|
||||
local t = cd:getTypeString()
|
||||
local st = cd:getSubtypeString()
|
||||
local tn = cd.trueName
|
||||
-- TODO: local n = cd.name
|
||||
|
||||
if not tmp[tn] then
|
||||
card_type_table[t] = card_type_table[t] or {}
|
||||
card_type_table[st] = card_type_table[st] or {}
|
||||
table.insertIfNeed(card_type_table[t], tn)
|
||||
table.insertIfNeed(card_type_table[st], tn)
|
||||
tmp[tn] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function matchSingleKey(matcher, card, key)
|
||||
local match = matcher[key]
|
||||
if not match then return true end
|
||||
local val = card[key]
|
||||
if key == "suit" then
|
||||
val = card:getSuitString()
|
||||
elseif key == "cardType" then
|
||||
val = card:getTypeString()
|
||||
-- elseif key == "cardType" then
|
||||
-- val = card:getTypeString()
|
||||
elseif key == "place" then
|
||||
val = placetable[Fk:currentRoom():getCardArea(card.id)]
|
||||
if not val then
|
||||
|
@ -90,10 +112,31 @@ local function matchCard(matcher, card)
|
|||
and matchSingleKey(matcher, card, "suit")
|
||||
and matchSingleKey(matcher, card, "place")
|
||||
and matchSingleKey(matcher, card, "name")
|
||||
and matchSingleKey(matcher, card, "cardType")
|
||||
-- and matchSingleKey(matcher, card, "cardType")
|
||||
and matchSingleKey(matcher, card, "id")
|
||||
end
|
||||
|
||||
local function hasNegIntersection(a, b)
|
||||
local neg_pass = false
|
||||
|
||||
-- 第一次比较: 比较neg和正常值,如有不同即认为可以匹配
|
||||
-- 比如 ^jink 可以匹配 slash,jink
|
||||
for _, neg in ipairs(a.neg or Util.DummyTable) do
|
||||
for _, e in ipairs(b) do
|
||||
if type(neg) == "table" then
|
||||
neg_pass = not table.contains(neg, e)
|
||||
else
|
||||
neg_pass = neg ~= e
|
||||
end
|
||||
if neg_pass then return true end
|
||||
end
|
||||
end
|
||||
|
||||
-- 第二次比较: 比较双方neg
|
||||
-- 比如 ^jink 可以匹配 ^slash
|
||||
-- 暂时想不出好方案
|
||||
end
|
||||
|
||||
local function hasIntersection(a, b)
|
||||
if a == nil or b == nil then
|
||||
return true
|
||||
|
@ -109,9 +152,9 @@ local function hasIntersection(a, b)
|
|||
end
|
||||
end
|
||||
|
||||
-- TODO: 判断含有neg的两个matcher
|
||||
local neg_pass = hasNegIntersection(a, b) or hasNegIntersection(b, a)
|
||||
|
||||
return false
|
||||
return neg_pass
|
||||
end
|
||||
|
||||
---@param a Matcher
|
||||
|
@ -123,7 +166,7 @@ local function matchMatcher(a, b)
|
|||
"suit",
|
||||
"place",
|
||||
"name",
|
||||
"cardType",
|
||||
-- "cardType",
|
||||
"id",
|
||||
}
|
||||
|
||||
|
@ -260,7 +303,27 @@ local function parseMatcher(str)
|
|||
ret.suit = not table.contains(t[3], ".") and t[3] or nil
|
||||
ret.place = not table.contains(t[4], ".") and t[4] or nil
|
||||
ret.name = not table.contains(t[5], ".") and t[5] or nil
|
||||
ret.cardType = not table.contains(t[6], ".") and t[6] or nil
|
||||
-- ret.cardType = not table.contains(t[6], ".") and t[6] or nil
|
||||
if table.empty(card_type_table) then
|
||||
fillCardTypeTable()
|
||||
end
|
||||
for _, ctype in ipairs(t[6]) do
|
||||
for _, n in ipairs(card_type_table[ctype] or Util.DummyTable) do
|
||||
if not ret.trueName then ret.trueName = {} end
|
||||
table.insertIfNeed(ret.trueName, n)
|
||||
end
|
||||
end
|
||||
for _, neg in ipairs(t[6].neg or Util.DummyTable) do
|
||||
if type(neg) ~= "table" then neg = { neg } end
|
||||
if not ret.trueName then ret.trueName = {} end
|
||||
if not ret.trueName.neg then ret.trueName.neg = {} end
|
||||
|
||||
local temp = {}
|
||||
for _, ctype in ipairs(neg) do
|
||||
table.insertTable(temp, card_type_table[ctype] or Util.DummyTable)
|
||||
end
|
||||
table.insert(ret.trueName.neg, temp)
|
||||
end
|
||||
|
||||
if not table.contains(t[7], ".") then
|
||||
ret.id = parseRawNumTable(t[7])
|
||||
|
|
|
@ -250,6 +250,10 @@ function table:assign(targetTbl)
|
|||
end
|
||||
end
|
||||
|
||||
function table.empty(t)
|
||||
return next(t) == nil
|
||||
end
|
||||
|
||||
-- allow a = "Hello"; a[1] == "H"
|
||||
local str_mt = getmetatable("")
|
||||
str_mt.__index = function(str, k)
|
||||
|
|
|
@ -1,22 +1,44 @@
|
|||
local exp1 = Exppattern:Parse("slash,jink")
|
||||
local exp2 = Exppattern:Parse("peach,jink")
|
||||
local exp3 = Exppattern:Parse(".|.|.|.|.|trick")
|
||||
local exp4 = Exppattern:Parse("peach,ex_nihilo")
|
||||
|
||||
local slash = Fk:cloneCard("slash")
|
||||
|
||||
TestExppattern = {
|
||||
testMatchExp = function()
|
||||
assert(exp1:matchExp(exp2))
|
||||
local exp1 = Exppattern:Parse("slash,jink")
|
||||
lu.assertTrue(exp1:matchExp("peack,jink"))
|
||||
end,
|
||||
|
||||
testEasyMatchCard = function()
|
||||
assert(exp1:match(slash))
|
||||
assert(not exp2:match(slash))
|
||||
local exp1 = Exppattern:Parse("slash,jink")
|
||||
local exp2 = Exppattern:Parse("peach,jink")
|
||||
local slash = Fk:cloneCard("slash")
|
||||
lu.assertTrue(exp1:match(slash))
|
||||
lu.assertFalse(exp2:match(slash))
|
||||
end,
|
||||
|
||||
testMatchWithType = function()
|
||||
assert(not exp3:matchExp(exp1))
|
||||
assert(exp3:matchExp(exp4))
|
||||
local exp3 = Exppattern:Parse(".|.|.|.|.|normal_trick")
|
||||
lu.assertFalse(exp3:matchExp("slash,jink"))
|
||||
lu.assertTrue(exp3:matchExp("peach,ex_nihilo"))
|
||||
|
||||
local basic = Exppattern:Parse(".|.|.|.|.|basic")
|
||||
lu.assertFalse(basic:matchExp("nullification"))
|
||||
lu.assertTrue(basic:matchExp("slash,vine"))
|
||||
lu.assertTrue(Exppattern:Parse(".|.|.|.|.|armor"):matchExp("slash,vine"))
|
||||
end,
|
||||
|
||||
testMatchNeg = function()
|
||||
lu.assertError(function() Exppattern:Parse("^(a,|1)") end)
|
||||
local not_nul = Exppattern:Parse("^nullification")
|
||||
local not_slash_jink = Exppattern:Parse("^(slash,jink)")
|
||||
local not_basic = Exppattern:Parse(".|.|.|.|.|^basic")
|
||||
local slash_jink = Exppattern:Parse("slash,jink")
|
||||
local slash = Fk:cloneCard("slash")
|
||||
|
||||
lu.assertFalse(not_nul:matchExp("nullification"))
|
||||
lu.assertTrue(not_basic:matchExp("nullification"))
|
||||
lu.assertFalse(not_slash_jink:matchExp("jink"))
|
||||
lu.assertTrue(not_nul:match(slash))
|
||||
lu.assertFalse(not_slash_jink:match(slash))
|
||||
lu.assertFalse(not_basic:match(slash))
|
||||
lu.assertTrue(not_nul:matchExp("peach"))
|
||||
lu.assertFalse(not_slash_jink:matchExp(not_basic))
|
||||
lu.assertFalse(slash_jink:matchExp(not_slash_jink))
|
||||
end,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue