Initial commit of mtgonline project

This commit is contained in:
2026-07-18 04:57:40 +00:00
commit 86c12376f8
1870 changed files with 547994 additions and 0 deletions
@@ -0,0 +1,53 @@
#include "format_legality_rules.h"
#include <libcockatrice/card/card_info.h>
bool cardMatchesCondition(const CardInfo &card, const CardCondition &cond)
{
CardMatchType type = matchTypeFromString(cond.matchType);
QString fieldValue;
if (cond.field == "name") {
fieldValue = card.getName();
} else if (cond.field == "text") {
fieldValue = card.getText();
} else {
fieldValue = card.getProperty(cond.field);
}
switch (type) {
case CardMatchType::Equals:
return fieldValue == cond.value;
case CardMatchType::NotEquals:
return fieldValue != cond.value;
case CardMatchType::Contains:
return fieldValue.contains(cond.value, Qt::CaseInsensitive);
case CardMatchType::NotContains:
return !fieldValue.contains(cond.value, Qt::CaseInsensitive);
case CardMatchType::Regex: {
QRegularExpression re(cond.value, QRegularExpression::CaseInsensitiveOption);
return re.match(fieldValue).hasMatch();
}
default:
return false;
}
}
bool exceptionAppliesToCard(const CardInfo &card, const ExceptionRule &rule)
{
for (const CardCondition &cond : rule.conditions) {
if (!cardMatchesCondition(card, cond)) {
return false; // all conditions must match
}
}
return true;
}
bool cardHasAnyException(const CardInfo &card, const FormatRules &format)
{
for (const ExceptionRule &rule : format.exceptions) {
if (exceptionAppliesToCard(card, rule)) {
return true;
}
}
return false;
}
@@ -0,0 +1,78 @@
#ifndef COCKATRICE_FORMAT_LEGALITY_RULES_H
#define COCKATRICE_FORMAT_LEGALITY_RULES_H
#include <QRegularExpression>
#include <QSharedPointer>
#include <QString>
class CardInfo;
using CardInfoPtr = QSharedPointer<CardInfo>;
struct CardCondition
{
QString field; // e.g. "type", "maintype", "text"
QString matchType; // "contains", "equals", "regex", "notContains", etc.
QString value; // e.g. "Basic Land"
};
struct AllowedCount
{
int max = 0; // 4, 1, 0, or -1 for unlimited
QString label; // "legal", "restricted", "banned"
};
struct ExceptionRule
{
QList<CardCondition> conditions; // All must match
int maxCopies = -1; // -1 = unlimited
};
struct FormatRules
{
QString formatName;
int minDeckSize = 60;
int maxDeckSize = -1; // -1 = unlimited
int maxSideboardSize = 15;
QList<AllowedCount> allowedCounts;
QList<ExceptionRule> exceptions; // Cards allowed to break maxCopies
};
enum class CardMatchType
{
Equals,
NotEquals,
Contains,
NotContains,
Regex
};
// convert string to enum
inline CardMatchType matchTypeFromString(const QString &str)
{
if (str == "equals") {
return CardMatchType::Equals;
}
if (str == "notEquals") {
return CardMatchType::NotEquals;
}
if (str == "contains") {
return CardMatchType::Contains;
}
if (str == "notContains") {
return CardMatchType::NotContains;
}
if (str == "regex") {
return CardMatchType::Regex;
}
return CardMatchType::Equals; // fallback default
}
bool cardMatchesCondition(const CardInfo &card, const CardCondition &cond);
bool exceptionAppliesToCard(const CardInfo &card, const ExceptionRule &rule);
bool cardHasAnyException(const CardInfo &card, const FormatRules &format);
#endif // COCKATRICE_FORMAT_LEGALITY_RULES_H