借助单元测试修复了exppattern存在的诸多bug
This commit is contained in:
notify 2023-06-24 12:29:20 +08:00 committed by GitHub
parent ecf8ff447a
commit f7f1bb8537
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 132 additions and 20 deletions

View File

@ -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

View File

@ -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])

View File

@ -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)

View File

@ -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,
}