---------------------------------------- -- beginning of touhou character data -- data taken from http://tohosort.comoj.com/src/fnc_data_v2.js -- sets converted to arrays ---------------------------------------- local CHAR = { -- main gals {"Reimu Hakurei", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20}, {4}}, {"Marisa Kirisame", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, {4, 7}}, -- eosd {"Rumia", {1, 6, 15, 20}, {1}}, {"Daiyousei", {1, 20}, {2, 7}}, {"Cirno", {1, 2, 5, 6, 10, 13, 15, 16, 17, 20}, {2}}, {"Hong Meiling", {1, 3, 6, 10, 20}, {3}}, {"Koakuma", {1, 20}, {4}}, {"Patchouli Knowledge", {1, 3, 6, 8, 10, 15, 20}, {4, 7}}, {"Sakuya Izayoi", {1, 2, 3, 4, 5, 6, 8, 10, 15, 16, 17, 20}, {5, 6}}, {"Remilia Scarlet", {1, 3, 4, 6, 8, 10, 15, 17, 20}, {6}}, {"Flandre Scarlet", {1, 6, 20}, {7}}, -- pcb {"Letty Whiterock", {2, 6, 15, 20}, {1}}, {"Chen", {2, 3, 6, 8, 10, 15, 20}, {2, 7}}, {"Alice Margatroid", {2, 3, 4, 6, 8, 10, 15, 20}, {3}}, {"Lily White", {2, 5, 15, 20}, {4, 7}}, {"Lunasa Prismriver", {2, 5, 15, 20}, {4}}, {"Merlin Prismriver", {2, 5, 15, 20}, {4}}, {"Lyrica Prismriver", {2, 5, 15, 20}, {4}}, {"Youmu Konpaku", {2, 3, 4, 5, 6, 8, 10, 14, 15, 17, 20}, {5, 6}}, {"Yuyuko Saigyouji", {2, 3, 4, 6, 8, 10, 14, 15, 17, 20}, {1, 6}}, {"Ran Yakumo", {2, 3, 4, 6, 8, 10, 15, 20}, {7}}, {"Yukari Yakumo", {2, 3, 4, 6, 8, 10, 15, 17, 20}, {7}}, -- iamp {"Suika Ibuki", {3, 6, 8, 10, 12, 15, 17, 20}, {6}}, -- in {"Wriggle Nightbug", {4, 6, 15, 20}, {1}}, {"Mystia Lorelei", {4, 5, 6, 15, 20}, {2}}, {"Keine Kamishirasawa", {4, 6, 15, 17, 20}, {3, 7}}, {"Tewi Inaba", {4, 5, 6, 15, 20}, {5}}, {"Reisen Udongein Inaba", {4, 5, 6, 10, 15, 19, 20}, {5}}, {"Eirin Yagokoro", {4, 6, 15, 20}, {6}}, {"Kaguya Houraisan", {4, 6, 15, 20}, {6}}, {"Fujiwara no Mokou", {4, 6, 15, 17, 18, 20}, {7}}, -- pofv {"Aya Shameimaru", {5, 6, 7, 8, 10, 15, 17, 20}, {4}}, {"Medicine Melancholy", {5, 6, 15, 20}, {4}}, {"Yuuka Kazami", {5, 6, 15, 20}, {5}}, {"Komachi Onozuka", {5, 6, 8, 10, 15, 20}, {5}}, {"Eiki Shiki, Yamaxanadu", {5, 6, 15, 20}, {6}}, -- mof {"Shizuha Aki", {7, 12, 15}, {1}}, {"Minoriko Aki", {7, 12, 15}, {1}}, {"Hina Kagiyama", {7, 12, 15}, {2}}, {"Nitori Kawashiro", {7, 12, 15, 17, 18}, {3}}, {"Momiji Inubashiri", {7, 12, 17}, {4}}, {"Sanae Kochiya", {7, 9, 10, 11, 12, 14, 15, 17, 19}, {5, 7}}, {"Kanako Yasaka", {7, 10, 12, 15, 17}, {6, 7}}, {"Suwako Moriya", {7, 9, 10, 12, 15, 17}, {7}}, -- swr {"Iku Nagae", {8, 10, 12, 15}, {5}}, {"Tenshi Hinanawi", {8, 10, 12, 15, 17}, {6}}, -- sa {"Kisume", {9, 12}, {1}}, {"Yamame Kurodani", {9, 12, 15}, {1}}, {"Parsee Mizuhashi", {9, 12, 15}, {2}}, {"Yuugi Hoshiguma", {9, 12, 15}, {3}}, {"Satori Komeiji", {9, 12, 15}, {4}}, {"Rin Kaenbyou (Orin)", {9, 12, 15}, {4, 5, 6}}, {"Utsuho Reiuji (Okuu)", {9, 10, 12, 15}, {6}}, {"Koishi Komeiji", {9, 12, 15, 18}, {7}}, -- soku {"Great Catfish", {10}, {6}}, -- ufo {"Nazrin", {11, 12, 15}, {1, 5}}, {"Kogasa Tatara", {11, 12, 15}, {2, 7}}, {"Ichirin Kumoi", {11, 12, 15, 18}, {3}}, {"Unzan", {11, 12, 15, 18}, {3}}, {"Minamitsu Murasa", {11, 12, 15}, {4}}, {"Shou Toramaru", {11, 12, 15}, {5}}, {"Byakuren Hijiri", {11, 12, 15, 17, 18}, {6}}, {"Nue Houjuu", {11, 12, 14, 15}, {4, 6, 7}}, -- ds {"Hatate Himekaidou", {12, 15, 17}, {7}}, -- gfw {"Sunny Milk", {13, 15, 20}, {1, 2, 3}}, {"Luna Child", {13, 15, 20}, {1, 2, 3}}, {"Star Sapphire", {13, 15, 20}, {1, 2, 3}}, -- td {"Kyouko Kasodani", {14, 15, 17}, {2}}, {"Yoshika Miyako", {14, 15, 17}, {3, 4}}, {"Seiga Kaku", {14, 15, 17}, {4}}, {"Soga no Tojiko", {14, 15}, {5}}, {"Mononobe no Futo", {14, 15, 17, 18}, {5}}, {"Toyosatomimi no Miko", {14, 15, 17, 18}, {6}}, {"Mamizou Futatsuiwa", {14, 15, 17, 18}, {7}}, -- hm {"Hata no Kokoro", {15, 18}, {6}}, -- ddc {"Wakasagihime", {16, 17}, {1}}, {"Sekibanki", {16, 17}, {2}}, {"Kagerou Imaizumi", {16, 17}, {3}}, {"Benben Tsukumo", {16, 17}, {4, 7}}, {"Yatsuhashi Tsukumo", {16, 17}, {4, 7}}, {"Seija Kijin", {16, 17}, {5, 6}}, {"Shinmyoumaru Sukuna", {16, 17, 18}, {6}}, {"Raiko Horikawa", {16, 17}, {7}}, -- ulil {"Sumireko Usami", {18}, {6}}, -- lolk {"Seiran", {19}, {1}}, {"Ringo", {19}, {2}}, {"Doremy Sweet", {19}, {3, 7}}, {"Sagume Kishin", {19}, {4}}, {"Clownpiece", {19}, {5}}, {"Junko", {19}, {6, 7}}, {"Hecatia Lapislazuli", {19}, {7}}, -- peeps {"Rinnosuke Morichika", {15, 20}, {}}, {"Hieda no Akyuu", {20}, {}}, {"Tokiko", {20}, {}}, {"Reisen (Manga)", {20}, {}}, {"Watatsuki no Toyohime", {20}, {}}, {"Watatsuki no Yorihime", {20}, {}}, {"Maribel Hearn", {20}, {}}, {"Renko Usami", {20}, {}}, {"Kasen Ibaraki", {18, 20}, {5}}, {"Kosuzu Motoori", {15, 20}, {}}, -- hrtp {"Reimu Hakurei (PC-98)", {21, 22, 23, 24, 25}, {4}}, {"Genji", {21, 22, 23, 24, 25}, {}}, {"Shingyoku (Male)", {21}, {1}}, {"Shingyoku (Female)", {21}, {1}}, {"YuugenMagan", {21}, {3}}, {"Mima", {21, 22, 23, 25}, {3, 5, 6}}, {"Elis", {21}, {5}}, {"Kikuri", {21}, {5}}, {"Sariel", {21}, {6}}, {"Konngara", {21}, {6}}, -- soew {"Rika", {22}, {1, 7}}, {"Evil Eye Sigma", {22}, {7}}, {"Meira", {22}, {2}}, {"Marisa Kirisame (PC-98)", {22, 23, 24, 25}, {4}}, -- podd {"Ellen", {23}, {}}, {"Kotohime", {23}, {}}, {"Kana Anaberal", {23}, {}}, {"Rikako Asakura", {23}, {}}, {"Chiyuri Kitashirakawa", {23}, {5}}, {"Yumemi Okazaki", {23}, {6}}, {"Ruukoto", {23}, {}}, -- lls {"Orange", {24}, {1}}, {"Kurumi", {24}, {2}}, {"Elly", {24}, {3}}, {"Yuuka (PC-98)", {24, 25}, {5, 6}}, {"Mugetsu", {24}, {7}}, {"Gengetsu", {24}, {7}}, -- ms {"Sara", {25}, {1}}, {"Louise", {25}, {2, 4}}, {"Alice (PC-98)", {25}, {3, 7}}, {"Yuki", {25}, {4}}, {"Mai", {25}, {4}}, {"Yumeko", {25}, {5}}, {"Shinki", {25}, {6}}, -- more peeps {"Layla Prismriver", {26}, {}}, {"Youki Konpaku", {26}, {}}, {"Myouren Hijiri", {26}, {}}, } local SERIES = { "Embodiment of Scarlet Devil", "Perfect Cherry Blossom", "Immaterial and Missing Power", "Imperishable Night", "Phantasmagoria of Flower View", "Shoot the Bullet", "Mountain of Faith", "Scarlet Weather Rhapsody", "Subterranean Animism", "Touhou Hisoutensoku", "Undefined Fantastic Object", "Double Spoiler", "Great Fairy Wars", "Ten Desires", "Hopeless Masquerade", "Double Dealing Character", "Impossible Spell Card", "Urban Legend in Limbo", "Legacy of Lunatic Kingdom", "Books and CDs", "The Highly Responsive to Prayers", "The Story of Eastern Wonderland", "Phantasmagoria of Dim.Dream", "Lotus Land Story", "Mystic Square", "Others", } local STAGE = {"Stage 1", "Stage 2", "Stage 3", "Stage 4", "Stage 5", "Final Stage", "EX/Phantasm"} local function makeTable () local sel = {} for i = 1, 20 --[[#SERIES]] do sel[i] = true end while true do for i, v in ipairs(SERIES) do print(string.format(" %s %2d - %s", sel[i] and "X" or " ", i, v)) end local n = tonumber(io.read()) if not n or not SERIES[n] then break end sel[n] = not sel[n] end local stg = {} for i = 1, #STAGE do stg[i] = true end local filter = false while true do print(" " .. (filter and "X" or " ") .. " 0 - Filter by stage") for i, v in ipairs(STAGE) do print(string.format(" %s %2d - %s", not filter and "-" or stg[i] and "X" or " ", i, v)) end local n = tonumber(io.read()) if n == 0 then filter = not filter elseif n and STAGE[n] then if filter then stg[n] = not stg[n] end else break end end local t = {} for _, v in ipairs(CHAR) do local use = not filter if filter then for _, s in ipairs(v[3]) do if stg[s] then use = true end end end if use then for _, game in ipairs(v[2]) do if sel[game] then t[#t + 1] = v[1] break end end end end if #t >= 2 then return t end print("Not enough entries!") os.execute("pause") return makeTable() end ---------------------------------------- -- end of touhou character data ---------------------------------------- local HELP = [[ Y - Left wins N - Right wins T - Tie]] local GREATER = 3 local EQUAL = 2 local LESS = 1 local rank = function (entry) local rel = {} local d = 0 local count = 0 local battle = {} local pool = {} for i = 1, #entry do rel[i] = {[i] = EQUAL} battle[i] = 1 pool[i] = i end local showHelp = true local disp = function () local ch = {[GREATER] = ">", [LESS] = "<", [EQUAL] = "="} print(" " .. table.concat(entry, " ")) for i, v in ipairs(entry) do io.write(v) for j = 1, #entry do io.write(" ", ch[rel[i][j]] or " ") end io.write(" ", tostring(battle[i])) io.write("\n") end end local OPTION = {Y = GREATER, N = LESS, T = EQUAL} math.randomseed(os.time()) while #pool > 0 do local left, right, result repeat left = math.random(#pool) right = math.random(#pool - 1) if right == left then right = right + 1 end left, right = pool[left], pool[right] until not rel[left][right] d = d + 1 repeat print("Battle No. " .. d .. " (" .. math.floor(count * 100 / #entry / (#entry - 1)) .. "% complete)") print(entry[left] .. " > " .. entry[right]) if showHelp then print(HELP) end local str = io.read() result = OPTION[str:upper()] showHelp = not result until result ~= nil showHelp = false local closure = {} local set = {{}, {}, {}} local function step (x, res) closure[x] = res set[res][x] = true for i = 1, #entry do if rel[i][x] and not closure[i] then if res == GREATER then if rel[i][x] == GREATER or rel[i][x] == EQUAL then step(i, GREATER) end elseif res == LESS then if rel[i][x] == LESS or rel[i][x] == EQUAL then step(i, LESS) end elseif res == EQUAL then step(i, rel[i][x]) end end end end step(left, result) step(right, 4 - result) for _, a in ipairs {GREATER, EQUAL} do for _, b in ipairs {EQUAL, LESS} do for i in pairs(set[a]) do for j in pairs(set[b]) do if not rel[i][j] then count = count + 2 rel[i][j] = a == b and EQUAL or GREATER rel[j][i] = a == b and EQUAL or LESS battle[i] = battle[i] + 1 battle[j] = battle[j] + 1 print(string.format("%s %s %s", entry[i], a == b and "ties with" or "defeats", entry[j])) end end end end end for i in pairs(closure) do if battle[i] == #entry then for p, v in ipairs(pool) do if v == i then table.remove(pool, p) break end end end end -- disp() end local t = {} for i = 1, #entry do t[i] = {} end for i = 1, #entry do local c = 0 for j = 1, #entry do if rel[i][j] == LESS then c = c + 1 end end t[c + 1][#t[c + 1] + 1] = entry[i] end return t end local main = function () local t = rank(makeTable()) local str = {} for i, v in ipairs(t) do for _, s in ipairs(v) do str[#str + 1] = i .. "\t" .. s .. "\n" end end str = table.concat(str) print("Save to:") local fname = io.read() if fname == "" then print(str) else local f = io.open(fname, "w") f:write(str) f:close() end os.execute("pause") end main(arg)