mirror of
https://github.com/goraph/17rooms.git
synced 2024-05-19 10:38:15 +03:00
434 lines
8.1 KiB
Lua
434 lines
8.1 KiB
Lua
|
local type = type
|
|||
|
local kbdru = {
|
|||
|
["q"] = "й",
|
|||
|
["w"] = "ц",
|
|||
|
["e"] = "у",
|
|||
|
["r"] = "к",
|
|||
|
["t"] = "е",
|
|||
|
["y"] = "н",
|
|||
|
["u"] = "г",
|
|||
|
["i"] = "ш",
|
|||
|
["o"] = "щ",
|
|||
|
["p"] = "з",
|
|||
|
["["] = "х",
|
|||
|
["]"] = "ъ",
|
|||
|
["a"] = "ф",
|
|||
|
["s"] = "ы",
|
|||
|
["d"] = "в",
|
|||
|
["f"] = "а",
|
|||
|
["g"] = "п",
|
|||
|
["h"] = "р",
|
|||
|
["j"] = "о",
|
|||
|
["k"] = "л",
|
|||
|
["l"] = "д",
|
|||
|
[";"] = "ж",
|
|||
|
["'"] = "э",
|
|||
|
["z"] = "я",
|
|||
|
["x"] = "ч",
|
|||
|
["c"] = "с",
|
|||
|
["v"] = "м",
|
|||
|
["b"] = "и",
|
|||
|
["n"] = "т",
|
|||
|
["m"] = "ь",
|
|||
|
[","] = "б",
|
|||
|
["."] = "ю",
|
|||
|
["`"] = "ё",
|
|||
|
["/"] = ".",
|
|||
|
shifted = {
|
|||
|
["q"] = "Й",
|
|||
|
["w"] = "Ц",
|
|||
|
["e"] = "У",
|
|||
|
["r"] = "К",
|
|||
|
["t"] = "Е",
|
|||
|
["y"] = "Н",
|
|||
|
["u"] = "Г",
|
|||
|
["i"] = "Ш",
|
|||
|
["o"] = "Щ",
|
|||
|
["p"] = "З",
|
|||
|
["["] = "Х",
|
|||
|
["]"] = "Ъ",
|
|||
|
["a"] = "Ф",
|
|||
|
["s"] = "Ы",
|
|||
|
["d"] = "В",
|
|||
|
["f"] = "А",
|
|||
|
["g"] = "П",
|
|||
|
["h"] = "Р",
|
|||
|
["j"] = "О",
|
|||
|
["k"] = "Л",
|
|||
|
["l"] = "Д",
|
|||
|
[";"] = "Ж",
|
|||
|
["'"] = "Э",
|
|||
|
["z"] = "Я",
|
|||
|
["x"] = "Ч",
|
|||
|
["c"] = "С",
|
|||
|
["v"] = "М",
|
|||
|
["b"] = "И",
|
|||
|
["n"] = "Т",
|
|||
|
["m"] = "Ь",
|
|||
|
[","] = "Б",
|
|||
|
["."] = "Ю",
|
|||
|
["`"] = "Ё",
|
|||
|
["1"] = "!",
|
|||
|
["2"] = "@",
|
|||
|
["3"] = "#",
|
|||
|
["4"] = ";",
|
|||
|
["5"] = "%",
|
|||
|
["6"] = ":",
|
|||
|
["7"] = "?",
|
|||
|
["8"] = "*",
|
|||
|
["9"] = "(",
|
|||
|
["0"] = ")",
|
|||
|
["-"] = "_",
|
|||
|
["="] = "+",
|
|||
|
["/"] = ",",
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
local toupper = {
|
|||
|
["й"] = "Й",
|
|||
|
["ц"] = "Ц",
|
|||
|
["у"] = "У",
|
|||
|
["к"] = "К",
|
|||
|
["е"] = "Е",
|
|||
|
["н"] = "Н",
|
|||
|
["г"] = "Г",
|
|||
|
["ш"] = "Ш",
|
|||
|
["щ"] = "Щ",
|
|||
|
["з"] = "З",
|
|||
|
["х"] = "Х",
|
|||
|
["ъ"] = "Ъ",
|
|||
|
["ф"] = "Ф",
|
|||
|
["ы"] = "Ы",
|
|||
|
["в"] = "В",
|
|||
|
["а"] = "А",
|
|||
|
["п"] = "П",
|
|||
|
["р"] = "Р",
|
|||
|
["о"] = "О",
|
|||
|
["л"] = "Л",
|
|||
|
["д"] = "Д",
|
|||
|
["ж"] = "Ж",
|
|||
|
["э"] = "Э",
|
|||
|
["я"] = "Я",
|
|||
|
["ч"] = "Ч",
|
|||
|
["с"] = "С",
|
|||
|
["м"] = "М",
|
|||
|
["и"] = "И",
|
|||
|
["т"] = "Т",
|
|||
|
["ь"] = "Ь",
|
|||
|
["б"] = "Б",
|
|||
|
["ю"] = "Ю",
|
|||
|
["ё"] = "Ё",
|
|||
|
}
|
|||
|
|
|||
|
local function lower(str)
|
|||
|
if type(str) ~= 'string' then
|
|||
|
return str
|
|||
|
end
|
|||
|
str = str:lower()
|
|||
|
for k, v in pairs(toupper) do
|
|||
|
str = str:gsub(v, k)
|
|||
|
end
|
|||
|
return str
|
|||
|
end
|
|||
|
|
|||
|
local function upper(str)
|
|||
|
if type(str) ~= 'string' then
|
|||
|
return str
|
|||
|
end
|
|||
|
str = str:upper();
|
|||
|
for k, v in pairs(toupper) do
|
|||
|
str = str:gsub(k, v)
|
|||
|
end
|
|||
|
return str
|
|||
|
end
|
|||
|
|
|||
|
local function is_cap(str)
|
|||
|
if type(str) ~= 'string' then
|
|||
|
return false
|
|||
|
end
|
|||
|
local s, e
|
|||
|
for _, v in pairs(toupper) do
|
|||
|
if not s and str:find("^"..v) then
|
|||
|
s = true
|
|||
|
end
|
|||
|
if not e and str:find(v.."$") then
|
|||
|
e = true
|
|||
|
end
|
|||
|
if not s and str:find("^[A-Z]") then
|
|||
|
s = true
|
|||
|
end
|
|||
|
if not e and str:find("[A-Z]$") then
|
|||
|
e = true
|
|||
|
end
|
|||
|
end
|
|||
|
return s, e
|
|||
|
end
|
|||
|
|
|||
|
local function cap(str)
|
|||
|
if type(str) ~= 'string' then
|
|||
|
return str
|
|||
|
end
|
|||
|
if str:find("^[a-z]") then
|
|||
|
str = str:gsub("^.", function(v) return v:upper() end)
|
|||
|
return str
|
|||
|
end
|
|||
|
for k, v in pairs(toupper) do
|
|||
|
local s = str:gsub("^"..k, v)
|
|||
|
if s ~= str then
|
|||
|
return s
|
|||
|
end
|
|||
|
end
|
|||
|
return str
|
|||
|
end
|
|||
|
|
|||
|
local lang
|
|||
|
|
|||
|
local function norm(str)
|
|||
|
if type(str) ~= 'string' then
|
|||
|
return str
|
|||
|
end
|
|||
|
if not lang.yo then
|
|||
|
str = str:gsub("ё", "е"):gsub("Ё", "Е")
|
|||
|
end
|
|||
|
return str
|
|||
|
end
|
|||
|
|
|||
|
local vowels = {
|
|||
|
["у"] = true,
|
|||
|
["е"] = true,
|
|||
|
["ы"] = true,
|
|||
|
["а"] = true,
|
|||
|
["о"] = true,
|
|||
|
["и"] = true,
|
|||
|
["ю"] = true,
|
|||
|
["ё"] = true,
|
|||
|
["э"] = true,
|
|||
|
["я"] = true,
|
|||
|
}
|
|||
|
|
|||
|
local function is_vowel(l)
|
|||
|
l = lower(l);
|
|||
|
return vowels[l]
|
|||
|
end
|
|||
|
|
|||
|
local gram_tt = {
|
|||
|
["ИНФИНИТИВ"] = true;
|
|||
|
["КР_ПРИЛ"] = true;
|
|||
|
["КР_ПРИЧАСТИЕ"] = true;
|
|||
|
["Г"] = true;
|
|||
|
}
|
|||
|
|
|||
|
local function flex_filter(v)
|
|||
|
local an = v.an
|
|||
|
if an["им"] then
|
|||
|
return true
|
|||
|
end
|
|||
|
if an["рд"] or an["дт"] or an["тв"] or an["пр"] or an["вн"] then
|
|||
|
return false
|
|||
|
end
|
|||
|
if an["0"] then
|
|||
|
return true
|
|||
|
end
|
|||
|
return gram_tt[an.t]
|
|||
|
end
|
|||
|
|
|||
|
local function gram_info(a)
|
|||
|
local t = { }
|
|||
|
if a['мр'] then
|
|||
|
t.gen = 'male'
|
|||
|
elseif a['жр'] then
|
|||
|
t.gen = 'female'
|
|||
|
elseif a['ср'] then
|
|||
|
t.gen = 'neuter'
|
|||
|
else
|
|||
|
t.gen = 'any'
|
|||
|
end
|
|||
|
|
|||
|
if a['мн'] then
|
|||
|
t.num = 'singular'
|
|||
|
elseif a['ед'] then
|
|||
|
t.num = 'plural'
|
|||
|
else
|
|||
|
t.num = 'any'
|
|||
|
end
|
|||
|
|
|||
|
if a['буд'] then
|
|||
|
t.time = 'future'
|
|||
|
elseif a['прш'] then
|
|||
|
t.time = 'past'
|
|||
|
elseif a['нст'] then
|
|||
|
t.time = 'present'
|
|||
|
else
|
|||
|
t.time = 'any'
|
|||
|
end
|
|||
|
|
|||
|
if a['1л'] then
|
|||
|
t.face = 'first'
|
|||
|
elseif a['2л'] then
|
|||
|
t.face = 'second'
|
|||
|
elseif a['3л'] then
|
|||
|
t.face = 'third'
|
|||
|
else
|
|||
|
t.face = 'any'
|
|||
|
end
|
|||
|
|
|||
|
return t
|
|||
|
end
|
|||
|
|
|||
|
local function __gram_compat(g1, g2, time)
|
|||
|
if g1.gen ~= g2.gen and g1.gen ~= 'any' and g2.gen ~= 'any' then return false end
|
|||
|
if not time then
|
|||
|
if g1.num ~= g2.num and g1.num ~= 'any' and g2.num ~= 'any' then return false end
|
|||
|
end
|
|||
|
if g1.time ~= g2.time and g1.time ~= 'any' and g2.time ~= 'any' then return false end
|
|||
|
if g1.face ~= g2.face and g1.face ~= 'any' and g2.face ~= 'any' then return false end
|
|||
|
return true
|
|||
|
end
|
|||
|
|
|||
|
local function gram_eq(a, b)
|
|||
|
if not a or not b then return true end
|
|||
|
if a == 'ИНФИНИТИВ' or b == 'ИНФИНИТИВ' then
|
|||
|
return b == a or b == 'Г' or a == 'Г'
|
|||
|
end
|
|||
|
if a == 'КР_ПРИЛ' or b == 'КР_ПРИЛ' then
|
|||
|
return b == a -- or b == 'П'
|
|||
|
end
|
|||
|
if a == 'КР_ПРИЧАСТИЕ' or b == 'КР_ПРИЧАСТИЕ' then
|
|||
|
return b == a
|
|||
|
end
|
|||
|
if a == 'ПРИЧАСТИЕ' or b == 'ПРИЧАСТИЕ' then
|
|||
|
return b == a
|
|||
|
end
|
|||
|
if a == 'Г' or b == 'Г' then return a == b end
|
|||
|
return true
|
|||
|
end
|
|||
|
|
|||
|
local function gram_compat(base, aa, bb)
|
|||
|
if not gram_eq(base.t, aa.t) then
|
|||
|
return false
|
|||
|
end
|
|||
|
-- local a, b = aa.t, bb.t
|
|||
|
local g1, g2 = gram_info(aa), gram_info(bb)
|
|||
|
if bb.noun then
|
|||
|
if not base['им'] then
|
|||
|
return false
|
|||
|
end
|
|||
|
local g0 = gram_info(base)
|
|||
|
if not __gram_compat(g0, g1, true) then return false end
|
|||
|
if not __gram_compat(g0, g2, true) then return false end
|
|||
|
end
|
|||
|
return __gram_compat(g1, g2)
|
|||
|
end
|
|||
|
|
|||
|
local function gram_norm(an)
|
|||
|
local a = {}
|
|||
|
local g = {}
|
|||
|
for _, v in ipairs(an) do
|
|||
|
a[v] = true
|
|||
|
table.insert(g, v)
|
|||
|
end
|
|||
|
if not a['1л'] and not a['2л'] and not a['3л'] then
|
|||
|
table.insert(g, '3л')
|
|||
|
end
|
|||
|
return g
|
|||
|
end
|
|||
|
|
|||
|
local function gram_score(an, g)
|
|||
|
local score = 0
|
|||
|
g = gram_norm(g)
|
|||
|
if an["фам"] then score = score - 0.1 end
|
|||
|
if an["арх"] then score = score - 0.1 end
|
|||
|
for _, vv in ipairs(g or {}) do
|
|||
|
if vv:sub(1, 1) == '~' then
|
|||
|
vv = vv:sub(2)
|
|||
|
if an[vv] then
|
|||
|
score = score - 1
|
|||
|
elseif an.t == vv then
|
|||
|
score = score - 10
|
|||
|
end
|
|||
|
else
|
|||
|
if an[vv] then
|
|||
|
score = score + 1
|
|||
|
elseif an.t == vv then
|
|||
|
score = score + 10
|
|||
|
end
|
|||
|
end
|
|||
|
end
|
|||
|
return score
|
|||
|
end
|
|||
|
|
|||
|
lang = { yo = false,
|
|||
|
kbd = kbdru,
|
|||
|
norm = norm,
|
|||
|
upper = upper,
|
|||
|
lower = lower,
|
|||
|
cap = cap,
|
|||
|
is_cap = is_cap,
|
|||
|
is_vowel = is_vowel,
|
|||
|
flex_filter = flex_filter,
|
|||
|
gram_compat = gram_compat,
|
|||
|
gram_score = gram_score,
|
|||
|
gram_t = {
|
|||
|
noun = 'С',
|
|||
|
nom = 'им',
|
|||
|
live = 'од',
|
|||
|
nonlive = 'но',
|
|||
|
neuter = 'ср',
|
|||
|
male = 'мр',
|
|||
|
female = 'жр',
|
|||
|
plural = 'мн',
|
|||
|
proper = 'имя',
|
|||
|
surname = 'фам',
|
|||
|
first = '1л',
|
|||
|
second = '2л',
|
|||
|
third = '3л',
|
|||
|
};
|
|||
|
dict = {
|
|||
|
["ведро/ср,но,С"] = {
|
|||
|
"ведро/им", "вёдра/им,мн",
|
|||
|
"ведро/вн", "вёдра/вн,мн",
|
|||
|
"ведра/рд", "вёдер/рд,мн",
|
|||
|
"ведру/дт", "ведрам/дт,мн",
|
|||
|
"ведром/тв", "вёдрами/тв,мн",
|
|||
|
"ведре/пр", "вёдрах/пр,мн",
|
|||
|
},
|
|||
|
["деревья/ср,но,мн,С"] = {
|
|||
|
"деревья/им";
|
|||
|
"деревья/вн";
|
|||
|
"деревьев/рд";
|
|||
|
"деревьями/тв";
|
|||
|
"деревьях/пр";
|
|||
|
"деревьям/дт";
|
|||
|
};
|
|||
|
["дерево/ср,но,С"] = {
|
|||
|
"дерево/им", "деревья/им,мн";
|
|||
|
"дерево/вн", "деревья/вн,мн";
|
|||
|
"дерева/рд", "деревьев/рд,мн";
|
|||
|
"деревом/тв", "деревьями/тв,мн";
|
|||
|
"дереве/пр", "деревьях/пр,мн";
|
|||
|
"дереву/пр", "деревьям/дт,мн";
|
|||
|
};
|
|||
|
["огонь/мр,но,С"] = {
|
|||
|
"огонь/им", "огни/им,мн",
|
|||
|
"огонь/вн", "огни/вн,мн",
|
|||
|
"огня/рд", "огней/рд,мн",
|
|||
|
"огню/дт", "огням/дт,мн",
|
|||
|
"огнём/тв", "огнями/тв,мн",
|
|||
|
"огне/пр", "огнях/пр,мн",
|
|||
|
};
|
|||
|
["цветы/мн,мр,но,С"] = { -- цветки
|
|||
|
"цветы/им",
|
|||
|
"цветы/вн",
|
|||
|
"цветов/рд",
|
|||
|
"цветам/дт",
|
|||
|
"цветами/тв",
|
|||
|
"цветах/пр",
|
|||
|
};
|
|||
|
["хлам/пр,2"] = "хламе";
|
|||
|
["клевер/пр"] = "клевере";
|
|||
|
["песок/пр,2"] = "песке";
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
return lang
|