跳转到主要内容

VTES卡牌和TWDA库。

项目描述

KRCG

PyPI version Validation Coverage Python version License Code Style

KRCG是一个Python包,用于提供VEKN 官方卡牌文本比赛获胜套牌存档(TWDA) 的接口。

它还包含一个不断增长的卡牌规则列表,这些规则通过我们贡献者的辛勤工作保持最新。

部分材料是Paradox Interactive AB的版权和商标,已获得许可使用。版权所有。更多信息请访问 white-wolf.com

Dark Pack

子项目

中卡工具库已被多个 子项目 使用

  • krcg-cli 是库的便捷命令行界面

  • krcg-static 用于为Web开发者生成易于使用的静态文件。它可在 static.krcg.org 上找到

  • krcg-api 是一个免费的RESTful网络API,可以充分利用库功能为Web项目服务。它可在v2.api.krcg.org在线获取。

  • krcg-bot 是一个友好的Discord机器人,提供官方卡牌文本和规则,免费使用。您可以通过免费使用

安装

需要Python 3

使用pip安装 krcg 工具

pip install krcg

使用库

KRCG 是用于 VTES 的 Python 库。代码具有良好的文档,可以使用 Python 内置的 help 函数进行探索。

以下是一些快速入门示例,展示如何使用该库

VTES

krcg.vtes.VTES 是卡牌库。需要使用 VTES.load() 方法进行加载。请注意,这将从 KRCG 静态服务器 加载数据,那里已经以JSON格式免费提供,供任何想要玩耍的人使用。

如果您想直接从官方的 VEKN CSV 文件 加载,可以使用 VTES.load_from_vekn(),但这会稍微慢一些。实际上,[krcg-static] 就是使用这种方法来生成标准加载所使用的静态JSON文件。

然后您就可以对 VTES 进行操作,访问卡牌、完整的卡牌名称或搜索。

>>> from krcg.vtes import VTES
>>> VTES.load()
>>> VTES["Alastor"].to_json()
{
  'id': 100038,
  'name': 'Alastor'
  '_name': 'Alastor',
  'url': 'https://static.krcg.org/card/alastor.jpg',
  'types': ['Political Action'],
  'card_text': (
    'Requires a justicar or Inner Circle member.\n'
    'Choose a ready Camarilla vampire. If this referendum is successful, '
    'search your library for an equipment card and place this card and the equipment '
    'on the chosen vampire. Pay half the cost (round down) of the equipment. '
    'This vampire may enter combat with any vampire controlled by another Methuselah '
    'as a +1 stealth Ⓓ action. This vampire cannot commit diablerie. '
    'A vampire may have only one Alastor.'),
  'artists': ['Monte Moore'],
  'sets': {
    'Gehenna': [{'release_date': '2004-05-17', 'rarity': 'Rare'}],
    'Kindred Most Wanted': [{'release_date': '2005-02-21', 'precon': 'Alastors', 'copies': 1}],
    'Keepers of Tradition': [{'release_date': '2008-11-19', 'rarity': 'Rare'}]},
 'rulings': {
   'text': [
     'If the given weapon costs blood, the target Alastor pays the cost. [LSJ 20040518]',
      'Requirements do not apply. [ANK 20200901]'
    ],
    'links': {
      '[LSJ 20040518]': 'https://groups.google.com/d/msg/rec.games.trading-cards.jyhad/4emymfUPwAM/B2SCC7L6kuMJ',
      '[ANK 20200901]': 'http://www.vekn.net/forum/rules-questions/78830-alastor-and-ankara-citadel#100653'
    }
  }
}
>>> VTES.complete("pentex")
['Pentex™ Loves You!',
 'Pentex™ Subversion',
 'Enzo Giovanni, Pentex Board of Directors',
 'Enzo Giovanni, Pentex Board of Directors (ADV)',
 'Harold Zettler, Pentex Director']
 >>> VTES.search(type=["political action"], sect=["anarch"], artist=["Drew Tucker"])
{<#100790 Free States Rant>}
>>> VTES.search(precon=["Fifth Edition: Nosferatu"])
{<#201534 Aunt Linda>,
 <#201536 Baixinho>,
 <#201537 Belinde>,
 <#100301 Carrion Crows>,
 <#100308 Cats' Guidance>,
 <#102213 Creeping Sabotage>,
 <#100515 Deep Song>,
 <#100698 Fame>,
 <#100863 Guard Dogs>,
 <#100866 Guardian Angel>,
 <#100897 Haven Uncovered>,
 <#201549 Horace Radcliffe>,
 <#100959 Immortal Grapple>,
 <#100995 Instinctive Reaction>,
 <#201553 Larissa Moreira>,
 <#201555 Lenny Burkhead>,
 <#101125 Lost in Crowds>,
 <#101254 Murder of Crows>,
 <#101321 On the Qui Vive>,
 <#101483 Preternatural Strength>,
 <#102214 Protected District>,
 <#101550 Raven Spy>,
 <#101564 Rebel>,
 <#102215 Roundhouse>,
 <#201568 Ryan>,
 <#101808 Slum Hunting Ground>,
 <#101811 Smiling Jack, The Anarch>,
 <#101945 Taste of Vitae>,
 <#201545 The Dowager>,
 <#101070 The Labyrinth>,
 <#102216 The Warrens>,
 <#102065 Underbridge Stray>,
 <#102113 Vessel>,
 <#102149 Warsaw Station>,
 <#201573 Wauneka>}
 >>> VTES.search(set=["Sword of Caine"], rarity=["Rare"])
{<#100167 Black Hand Emissary>,
 <#100314 Census Taker>,
 <#100360 Cloak of Blood>,
 <#100589 Drink the Blood of Ahriman>,
 <#100590 Drop Point Network>,
 <#100655 Epiphany>,
 <#100757 Follow the Blood>,
 <#100787 Framing an Ancient Grudge>,
 <#100865 Guarded Rubrics>,
 <#101024 Joseph Pander>,
 <#101111 Liquefy the Mortal Coil>,
 <#101161 Mantle of the Bestial Majesty>,
 <#101446 Praetorian Backer>,
 <#101489 Prison of the Mind>,
 <#101658 Ruins of Ceoris>,
 <#101724 Seraph's Second>,
 <#102057 The Uncoiling>,
 <#102022 Tribunal Judgment>,
 <#102027 Trophy: Chosen>,
 <#102158 Watchtower: The Wolves Feed>}

TWDA,分析器和牌组

krcg.twda.TWDA 是TWDA的接口。需要使用与 VTES 实例相同的方式加载,使用 TWDA.load() 方法。那时,使用 TWDA.load_from_vekn() 会慢得多。

加载后,可以用来浏览其中的牌组。

>>> from krcg.twda import TWDA
>>> TWDA.load()
>>> TWDA["2019ecday2pf"]
<Deck #2019ecday2pf: Finnish Politics>
>>> print(TWDA["2019ecday2pf"].to_txt())
EC 2019 - Day 2
Paris, France
August 18th 2019
3R+F
50 players
Otso Saariluoma

-- 2gw8.5 + 1.5vp in the final

Deck Name: Finnish Politics

Crypt (12 cards, min=4, max=38, avg=5.75)
-----------------------------------------
4x Anarch Convert     1 -none-                     Caitiff:ANY
3x Nana Buruku        8 ANI POT PRE                Guruhi:4
2x Nangila Were       9 ANI POT PRE obf ser        Guruhi:4
1x Enkidu, The Noah  11 ANI CEL OBF POT PRO for    Gangrel antitribu:4
1x Black Annis        9 OBF POT ani pro            Nosferatu antitribu:4
1x Andre LeRoux       3 aus                        Toreador:5

Library (65 cards)
Master (26; 6 trifle)
4x Anarch Revolt
1x Archon Investigation
6x Ashur Tablets
1x Dreams of the Sphinx
1x Fame
1x Giant's Blood
1x Information Highway
1x Mbare Market, Harare
2x Pentex(TM) Subversion
1x Powerbase: Luanda
1x Powerbase: Montreal
5x Villein
1x Wider View

Action (5)
3x Deep Song
1x Entrancement
1x Well-Marked

Retainer (1)
1x Mr. Winthrop

Reaction (6)
1x Cats' Guidance
1x Delaying Tactics
2x On the Qui Vive
2x Sense the Savage Way

Combat (26)
1x Canine Horde
5x Carrion Crows
1x Glancing Blow
5x Immortal Grapple
1x Mighty Grapple
1x Slam
1x Stunt Cycle
4x Taste of Vitae
2x Thrown Sewer Lid
4x Torn Signpost
1x Undead Strength

Event (1)
1x Dragonbound

>>> from datetime import date
>>> len([d for d in TWDA.values() if date(2019, 1, 1) < d.date < date(2020, 1, 1) and d.players_count >= 25])
27

krcg.analyzer 可以提供一组牌组的统计信息

>>> from krcg.analyzer import Analyzer
>>> # You can analyze the whole TWDA, or a fragment of it, or any collection of decks
>>> A = Analyzer([d for d in TWDA.values() if date(2019, 1, 1) < d.date < date(2020, 1, 1)])
>>> # A blank refresh will provide basic statistics
>>> A.refresh()
>>> A.played.most_common(5)
[(<#100588 Dreams of the Sphinx>, 101),
 (<#101384 Pentex™ Subversion>, 96),
 (<#101321 On the Qui Vive>, 86),
 (<#102121 Villein>, 83),
 (<#100824 Giant's Blood>, 74)]
>>> A.average[VTES["Villein"]]
4.409638554216869
>>> A.variance[VTES["Villein"]]
3.6876179416461032
>>> # Refreshing with a list of cards will compute cards affinity using similar decks
>>> # similarity=1 tells the engine to select decks that contains all provided cards
>>> A.refresh(VTES["Aid from Bats"], similarity=1)
>>> # now the candidates method can be used
>>> A.candidates(VTES["Aid from Bats"])[:5]
[(<#100515 Deep Song>, 1.0000000000000002),
 (<#100301 Carrion Crows>, 1.0000000000000002),
 (<#101945 Taste of Vitae>, 0.7777777777777779),
 (<#200185 Beetleman>, 0.6666666666666667),
 (<#100698 Fame>, 0.6666666666666667)]

krcg.seating 模块提供计算最佳座位的函数

>>> from krcg import seating
>>> # permutations gives you the list of players for each round
>>> seating.permutations(12, 3)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]
>>> # things get funny when you have 6, 7 or 11 players: you need more rounds
>>> # but not all players play every round
>>> seating.permutations(7, 3)
[[4, 5, 6, 7],
 [1, 2, 3, 7],
 [3, 4, 5, 6],
 [1, 2, 6, 7],
 [1, 2, 3, 4, 5]]
>>> # you can use the Round class to get tables from the permutations
>>> [seating.Round(p) for p in seating.permutations(14, 3)]
[[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]],
 [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]],
 [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]]]
>>> # and the optimise function to search for an optimal seating
>>> result, score = seating.optimise(seating.permutations(12, 3), iterations=50000)
>>> result
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
 [[2, 9, 6, 10], [12, 8, 1, 5], [3, 7, 4, 11]],
 [[11, 5, 10, 1], [6, 4, 12, 7], [8, 3, 9, 2]]]
>>> # score.rules gives a score over the nine official rules for optimal seating
>>> score.rules
[0, 0, 0.0, 9, 0, 0, 0, 1.118033988749895, 2]
>>> # you can inspect violations individualy
>>> # for example rule #4 (players are opponents twice) has 9 violations, to see them:
>>> score.R4
[[1, 5], [2, 3], [2, 9], [3, 4], [4, 7], [5, 8], [6, 7], [9, 10], [10, 11]]
>>> # for more details about the Score structure, check the docstring
>>> help(seating.Score)

最后,krcg.deck.Deck 类可以用来解析和操作任何牌组。

>>> from krcg.deck import Deck
>>> with open("First_Blood_Nosferatu.txt") as f:
>>>     deck = Deck.from_txt(f)
>>> deck.crypt
[(<#200549 Gustaphe Brunnelle>, 2),
 (<#200571 Harold Tanner>, 2),
 (<#200696 Jeremy "Wix" Wyzchovsky>, 2),
 (<#201116 Petra>, 2),
 (<#200185 Beetleman>, 2),
 (<#200190 Benjamin Rose>, 2)]
>>> deck.library
[(<#100698 Fame>, 2),
 (<#100070 Animalism>, 2),
 (<#101015 J. S. Simmons, Esq.>, 1),
 (<#101070 The Labyrinth>, 1),
 (<#101073 Laptop Computer>, 2),
 (<#101125 Lost in Crowds>, 6),
 (<#100093 Army of Rats>, 2),
 (<#101550 Raven Spy>, 4),
 (<#101808 Slum Hunting Ground>, 1),
 (<#100199 Blood Doll>, 6),
 (<#100029 Aid from Bats>, 12),
 (<#100308 Cats' Guidance>, 4),
 (<#100362 Cloak the Gathering>, 6),
 (<#100390 Computer Hacking>, 4)]
>>> # fetch a deck from Amaranth UID
>>> deck = Deck.from_amaranth("4d3aa426-70da-44b7-8cb7-92377a1a0dbd")
>>> deck.name
'First Blood: Tremere'
>>> deck.crypt
[(<Card #201020 Muhsin Samir>, 2),
 (<Card #201213 Rutor>, 2),
 (<Card #201388 Troius>, 2),
 (<Card #201501 Zane>, 2),
 (<Card #200025 Aidan Lyle>, 2),
 (<Card #200280 Claus Wegener>, 2)]
>>> print(deck.to_txt("lackey"))
1	Academic Hunting Ground
1	Arcane Library
4	Blood Doll
1	Chantry
2	Vast Wealth
12	Govern the Unaligned
1	Thadius Zho
4	.44 Magnum
1	Ivory Bow
2	Sport Bike
1	Charnas the Imp
6	Bonding
4	Enhanced Senses
5	Forced Awakening
5	On the Qui Vive
4	Precognition
4	Spirit's Touch
8	Telepathic Misdirection
8	Apportation
10	Theft of Vitae
2	Walk of Flame
Crypt:
2	Muhsin Samir
2	Rutor
2	Troius
2	Zane
2	Aidan Lyle
2	Claus Wegener

贡献

请随时提交拉取请求,只要它们通过测试,就会合并。如果您想实现某个功能,请不要犹豫,提交问题或对其进行投票。

设计考虑

出于设计考虑,该包不使用数据库。TWDA、搜索引擎和卡牌字典都保留在内存中,以提高性能。整个库生成的内存占用在 128MB 到 256MB 之间。

该包使用外部数据源进行卡牌列表,因此不需要在发布新套件或官方VEKN CSV文件更改时更新:它可以在新数据集可用时立即使用它们。

贡献规则(非开发者)

请随时贡献规则:所有帮助都受欢迎。

为认为应该添加的规则打开一个 问题,提供一个规则总监在线帖子链接

贡献规则(开发者)

请随时直接通过拉取请求贡献规则,这非常受欢迎。

将规则链接添加到 rulings-links.yaml,并将规则本身添加到 cards-rulings.yamlgeneral-rulings.yaml,具体取决于情况。

格式大多不言自明

  • 卡片通过 ID 和名称以 ID|Name 格式引用。

  • 规则文本中的卡片名称应放在括号内,例如 {.44 Magnum}

  • cards-rulings.yaml 中的个别规则必须在文本末尾提供一到多个对规则链接的引用,放在括号内,例如 [LSJ 20100101]

在此过程中,请遵循以下指南

  • 保持 YAML 文件整洁并按字母顺序排序(您可以使用 YAML 格式化工具)

  • 尽可能使规则简洁

  • 在规则前加上适用的学科级别和/或规则适用的类型(如果有的话),例如,如果规则仅适用于在高级异能战斗中播放的卡片,则前缀为 [PRO] [COMBAT]

  • 根据规则适用的卡片调整规则措辞(即使用阳性/阴性形式)

  • 您可以使用 pytest 命令运行测试以检查一切是否正常

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

krcg-4.2.tar.gz (388.1 kB 查看散列值)

上传时间 源代码

构建分发

krcg-4.2-py3-none-any.whl (394.9 kB 查看散列值)

上传时间 Python 3

由以下支持