parent
ecf8ff447a
commit
f7f1bb8537
|
@ -79,7 +79,7 @@ function Card:initialize(name, suit, number, color)
|
||||||
self.is_derived = true
|
self.is_derived = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local name_splited = name:split("__")
|
local name_splited = self.name:split("__")
|
||||||
self.trueName = name_splited[#name_splited]
|
self.trueName = name_splited[#name_splited]
|
||||||
|
|
||||||
if suit == Card.Spade or suit == Card.Club then
|
if suit == Card.Spade or suit == Card.Club then
|
||||||
|
@ -280,6 +280,29 @@ function Card:getTypeString()
|
||||||
return "notype"
|
return "notype"
|
||||||
end
|
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)。
|
--- 获取卡牌点数并返回点数文字描述(仅限A/J/Q/K)。
|
||||||
local function getNumberStr(num)
|
local function getNumberStr(num)
|
||||||
if num == 1 then
|
if num == 1 then
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
---@field public cardType string[]
|
---@field public cardType string[]
|
||||||
---@field public id integer[]
|
---@field public id integer[]
|
||||||
|
|
||||||
|
-- v0.2.6改动: cardType会被解析为trueName数组和name数组,而不是自己单独成立
|
||||||
|
|
||||||
local numbertable = {
|
local numbertable = {
|
||||||
["A"] = 1,
|
["A"] = 1,
|
||||||
["J"] = 11,
|
["J"] = 11,
|
||||||
|
@ -44,14 +46,34 @@ local placetable = {
|
||||||
[Card.PlayerEquip] = "equip",
|
[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 function matchSingleKey(matcher, card, key)
|
||||||
local match = matcher[key]
|
local match = matcher[key]
|
||||||
if not match then return true end
|
if not match then return true end
|
||||||
local val = card[key]
|
local val = card[key]
|
||||||
if key == "suit" then
|
if key == "suit" then
|
||||||
val = card:getSuitString()
|
val = card:getSuitString()
|
||||||
elseif key == "cardType" then
|
-- elseif key == "cardType" then
|
||||||
val = card:getTypeString()
|
-- val = card:getTypeString()
|
||||||
elseif key == "place" then
|
elseif key == "place" then
|
||||||
val = placetable[Fk:currentRoom():getCardArea(card.id)]
|
val = placetable[Fk:currentRoom():getCardArea(card.id)]
|
||||||
if not val then
|
if not val then
|
||||||
|
@ -90,10 +112,31 @@ local function matchCard(matcher, card)
|
||||||
and matchSingleKey(matcher, card, "suit")
|
and matchSingleKey(matcher, card, "suit")
|
||||||
and matchSingleKey(matcher, card, "place")
|
and matchSingleKey(matcher, card, "place")
|
||||||
and matchSingleKey(matcher, card, "name")
|
and matchSingleKey(matcher, card, "name")
|
||||||
and matchSingleKey(matcher, card, "cardType")
|
-- and matchSingleKey(matcher, card, "cardType")
|
||||||
and matchSingleKey(matcher, card, "id")
|
and matchSingleKey(matcher, card, "id")
|
||||||
end
|
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)
|
local function hasIntersection(a, b)
|
||||||
if a == nil or b == nil then
|
if a == nil or b == nil then
|
||||||
return true
|
return true
|
||||||
|
@ -109,9 +152,9 @@ local function hasIntersection(a, b)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: 判断含有neg的两个matcher
|
local neg_pass = hasNegIntersection(a, b) or hasNegIntersection(b, a)
|
||||||
|
|
||||||
return false
|
return neg_pass
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param a Matcher
|
---@param a Matcher
|
||||||
|
@ -123,7 +166,7 @@ local function matchMatcher(a, b)
|
||||||
"suit",
|
"suit",
|
||||||
"place",
|
"place",
|
||||||
"name",
|
"name",
|
||||||
"cardType",
|
-- "cardType",
|
||||||
"id",
|
"id",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +303,27 @@ local function parseMatcher(str)
|
||||||
ret.suit = not table.contains(t[3], ".") and t[3] or nil
|
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.place = not table.contains(t[4], ".") and t[4] or nil
|
||||||
ret.name = not table.contains(t[5], ".") and t[5] 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
|
if not table.contains(t[7], ".") then
|
||||||
ret.id = parseRawNumTable(t[7])
|
ret.id = parseRawNumTable(t[7])
|
||||||
|
|
|
@ -250,6 +250,10 @@ function table:assign(targetTbl)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function table.empty(t)
|
||||||
|
return next(t) == nil
|
||||||
|
end
|
||||||
|
|
||||||
-- allow a = "Hello"; a[1] == "H"
|
-- allow a = "Hello"; a[1] == "H"
|
||||||
local str_mt = getmetatable("")
|
local str_mt = getmetatable("")
|
||||||
str_mt.__index = function(str, k)
|
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 = {
|
TestExppattern = {
|
||||||
testMatchExp = function()
|
testMatchExp = function()
|
||||||
assert(exp1:matchExp(exp2))
|
local exp1 = Exppattern:Parse("slash,jink")
|
||||||
|
lu.assertTrue(exp1:matchExp("peack,jink"))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
testEasyMatchCard = function()
|
testEasyMatchCard = function()
|
||||||
assert(exp1:match(slash))
|
local exp1 = Exppattern:Parse("slash,jink")
|
||||||
assert(not exp2:match(slash))
|
local exp2 = Exppattern:Parse("peach,jink")
|
||||||
|
local slash = Fk:cloneCard("slash")
|
||||||
|
lu.assertTrue(exp1:match(slash))
|
||||||
|
lu.assertFalse(exp2:match(slash))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
testMatchWithType = function()
|
testMatchWithType = function()
|
||||||
assert(not exp3:matchExp(exp1))
|
local exp3 = Exppattern:Parse(".|.|.|.|.|normal_trick")
|
||||||
assert(exp3:matchExp(exp4))
|
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,
|
end,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue