2010-09-22 04:12:54 +00:00
|
|
|
import re
|
2010-07-01 19:37:43 +00:00
|
|
|
from django.db import models
|
2010-09-23 01:26:05 +00:00
|
|
|
from mtgweb.lib.mtg import mtg, analyze
|
2010-07-01 19:37:43 +00:00
|
|
|
|
|
|
|
# Create your models here.
|
2010-09-16 18:11:55 +00:00
|
|
|
class CardType(models.Model):
|
|
|
|
name = models.CharField(max_length=200, unique=True, db_index=True)
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
2010-08-26 19:19:32 +00:00
|
|
|
class Attribute(models.Model):
|
|
|
|
name = models.CharField(max_length=200, unique=True, db_index=True)
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
2010-09-16 18:11:55 +00:00
|
|
|
class Card(models.Model, mtg.Card):
|
2010-08-26 19:19:32 +00:00
|
|
|
name = models.CharField(max_length=200, unique=True)
|
2010-09-16 18:11:55 +00:00
|
|
|
type = models.ForeignKey(CardType)
|
2010-08-26 19:19:32 +00:00
|
|
|
attributes = models.ManyToManyField(Attribute)
|
|
|
|
cost = models.CharField(max_length=80)
|
|
|
|
converted_cost = models.IntegerField(default=0)
|
|
|
|
power = models.CharField(max_length=10)
|
|
|
|
toughness = models.CharField(max_length=10)
|
2010-09-21 19:46:28 +00:00
|
|
|
rarity = models.CharField(max_length=1)
|
2010-08-26 19:19:32 +00:00
|
|
|
text = models.TextField()
|
|
|
|
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
2010-09-23 01:26:21 +00:00
|
|
|
def get_cost(self):
|
|
|
|
return mtg.ManaCost(self.cost)
|
2010-08-26 19:19:32 +00:00
|
|
|
class Deck(models.Model):
|
|
|
|
name = models.CharField(max_length=80)
|
2010-09-17 21:28:46 +00:00
|
|
|
cards = models.ManyToManyField(Card, through='Included')
|
|
|
|
def __unicode__(self):
|
|
|
|
return self.name
|
2010-09-23 02:20:57 +00:00
|
|
|
def get_cards(self):
|
2010-09-23 04:02:46 +00:00
|
|
|
return self.included_set.all().order_by('card__type__name', 'card__name')
|
2010-09-23 03:48:05 +00:00
|
|
|
def card_count(self):
|
|
|
|
return sum([i.count for i in self.included_set.all()])
|
2010-09-22 18:22:21 +00:00
|
|
|
def lands(self):
|
2010-09-22 04:12:54 +00:00
|
|
|
symbols = {}
|
|
|
|
for symbol in mtg.Mana.types.keys():
|
|
|
|
symbols[symbol] = 0
|
2010-09-22 18:22:21 +00:00
|
|
|
for included in self.included_set.all():
|
|
|
|
card = included.card
|
|
|
|
types = card.type.name.split(' ')
|
|
|
|
attributes = [a.name for a in card.attributes.all()]
|
|
|
|
if 'land' not in types:
|
|
|
|
continue
|
|
|
|
if 'forest' in attributes:
|
|
|
|
symbols['G'] += included.count
|
|
|
|
if 'mountain' in attributes:
|
|
|
|
symbols['R'] += included.count
|
|
|
|
if 'island' in attributes:
|
|
|
|
symbols['U'] += included.count
|
|
|
|
if 'plains' in attributes:
|
|
|
|
symbols['W'] += included.count
|
|
|
|
if 'swamp' in attributes:
|
|
|
|
symbols['B'] += included.count
|
|
|
|
|
|
|
|
# Get symbols from abilities
|
|
|
|
pattern = '{%s}' % mtg.ManaCost.symbolPattern
|
|
|
|
costs = [mtg.ManaCost(cost) for cost in re.findall(pattern, str(card.text))]
|
|
|
|
for cost in costs:
|
|
|
|
for color, count in cost.mana.mana.iteritems():
|
|
|
|
symbols[color] += count * included.count
|
|
|
|
return symbols
|
|
|
|
def symbols(self):
|
|
|
|
symbols = {}
|
|
|
|
for symbol in mtg.Mana.types.keys():
|
|
|
|
symbols[symbol] = 0
|
|
|
|
for included in self.included_set.all():
|
|
|
|
card = included.card
|
2010-09-22 04:12:54 +00:00
|
|
|
# Get symbols from card cost
|
2010-09-22 01:37:00 +00:00
|
|
|
cost = mtg.ManaCost(card.cost)
|
|
|
|
for color, count in cost.mana.mana.iteritems():
|
2010-09-22 18:22:21 +00:00
|
|
|
symbols[color] += count * included.count
|
2010-09-22 04:12:54 +00:00
|
|
|
|
|
|
|
# Get symbols from abilities
|
|
|
|
pattern = '{%s}' % mtg.ManaCost.symbolPattern
|
|
|
|
costs = [mtg.ManaCost(cost) for cost in re.findall(pattern, str(card.text))]
|
|
|
|
for cost in costs:
|
|
|
|
for color, count in cost.mana.mana.iteritems():
|
2010-09-22 18:22:21 +00:00
|
|
|
symbols[color] += count * included.count
|
|
|
|
return symbols
|
|
|
|
def mana_curve(self):
|
|
|
|
curve = {}
|
|
|
|
for included in self.included_set.all():
|
|
|
|
card = included.card
|
|
|
|
if 'land' in card.type.name.split(' '):
|
|
|
|
continue
|
|
|
|
cost = mtg.ManaCost(card.cost).converted()
|
|
|
|
if cost not in curve:
|
|
|
|
curve[cost] = included.count
|
|
|
|
else:
|
|
|
|
curve[cost] += included.count
|
|
|
|
return curve
|
2010-09-23 01:26:05 +00:00
|
|
|
def ramp(self, type=None):
|
|
|
|
ramp = {}
|
|
|
|
deck_size = sum([i.count for i in self.included_set.all()])
|
|
|
|
lands = sum([i.count for i in self.included_set.all() if 'land' in i.card.type.name.split(' ')])
|
|
|
|
if type:
|
|
|
|
cards = [i for i in self.included_set.all() if type in i.card.type.name.split(' ')]
|
|
|
|
else:
|
|
|
|
cards = [i for i in self.included_set.all() if 'land' not in i.card.type.name.split(' ')]
|
|
|
|
card_count = sum([i.count for i in cards])
|
|
|
|
card_costs = sum([i.count * mtg.ManaCost(i.card.cost).converted() for i in cards])
|
|
|
|
max_cost = max([mtg.ManaCost(i.card.cost).converted() for i in cards])
|
|
|
|
avg_cost = card_costs / float(card_count)
|
|
|
|
avg_cost = int(round(avg_cost))
|
|
|
|
turns = []
|
|
|
|
for turn in range(avg_cost, max_cost + 1):
|
|
|
|
castable = sum([i.count for i in cards if mtg.ManaCost(i.card.cost).converted() <= turn])
|
|
|
|
p_land = 1 - analyze.draw_probability(lands, deck_size, avg_cost, turn)
|
|
|
|
p_spell = 1 - analyze.draw_probability(castable, deck_size, 1, turn, avg_cost)
|
|
|
|
probability = 1 - p_land - p_spell
|
|
|
|
turns.append({'turn': turn, 'probability': probability * 100})
|
|
|
|
return turns
|
|
|
|
|
2010-09-17 21:28:46 +00:00
|
|
|
class Included(models.Model):
|
|
|
|
card = models.ForeignKey(Card)
|
|
|
|
deck = models.ForeignKey(Deck)
|
|
|
|
count = models.IntegerField(default=0)
|
|
|
|
def __unicode__(self):
|
|
|
|
return '{0}x {1}'.format(self.count, self.card)
|