Some updates, including a Forest card coupled with its Tap Land ability

This commit is contained in:
Correl Roush 2010-06-17 15:52:21 -04:00
parent 8a08b97c7b
commit 869b2f3357
5 changed files with 140 additions and 25 deletions

View file

@ -1,4 +1,13 @@
import logging
import mtg
class TapMana(mtg.Ability):
def __init__(self, card, mana):
mtg.Ability.__init__(self, card, name='Tap Land', tap=True)
self.mana = mana
def run(self):
self.card.owner.mana += self.mana
logging.debug('%s: Added %s to mana pool of %s', self, self.mana, self.card.owner)
class Lifelink(mtg.Ability):
pass

View file

@ -1,4 +1,17 @@
from mtg import *
import abilities
"""
Forest
Basic Land -- Forest
A-L, B-L, U-L, RV-L, 4E-L, 5E-L, 6E-L, 7E-L, 8ED-L, 9ED-L, 10E-L, M10-L, P1-L, P2-L, P3K-L, S99-L, S00-L, IA-L, MI-L, TE-L, US-L, MM-L, IN-L, OD-L, ONS-L, MRD-L,
CHK-L, RAV-L, TSP-L, LRW-L, SHM-L, ALA-L, ZEN-L, ROE-L, HOP-L
"""
class Forest(Card):
def __init__(self):
Card.__init__(self, 'Forest', 'basic land', ['forest'])
self.abilities.append(abilities.TapMana(self, 'G'))
"""
Elvish Archdruid
1GG
@ -8,7 +21,6 @@ Other Elf creatures you control get +1/+1.
{T}: Add {G} to your mana pool for each Elf you control.
M10-R
"""
class Elvish_Archdruid(Card):
def __init__(self):
Card.__init__(self, 'Elvish Archdruid', ['elf', 'druid'], '1GG', 2, 2)
Card.__init__(self, 'Elvish Archdruid', 'creature', ['elf', 'druid'], '1GG', 2, 2)

18
main.py Normal file
View file

@ -0,0 +1,18 @@
import logging
from mtg import *
import cards
logging.basicConfig(level=logging.DEBUG)
game = Game()
test_deck = Deck()
test_deck.extend(cards.Forest() * 20)
test_deck.extend(cards.Elvish_Archdruid() * 40)
opponent = Player('Opponent', game, test_deck)
you = Player('You', game, test_deck)
you.draw(7)
# Place a land
you.cast(you.hand[0])
#Tap the land
you.battlefield[0].abilities[0].activate()

120
mtg.py
View file

@ -1,5 +1,6 @@
import copy
import random
import logging
from observable import Observable
class Game:
@ -99,39 +100,81 @@ class ManaCost:
return self.mana.converted() + self.any
class Player:
def __init__(self, name, deck=None):
def __init__(self, name, game, deck=None):
self.name = name
self.game = game
self.life = 20
self.mana = Mana()
self.deck = None
self.library = CardList(self, 'library')
self.hand = CardList(self, 'hand')
self.graveyard = CardList(self, 'graveyard')
self.battlefield = CardList(self, 'battlefield')
self.setDeck(deck)
self.hand = CardList()
self.graveyard = CardList()
self.battlefield = CardList()
self.lifeChanged = Observable()
self.defeated = Observable()
self.casts = Observable()
logging.debug('Initialized %s', self)
def __repr__(self):
return 'Player: {0} [Deck:{1}]'.format(self.name, len(self.deck))
return 'Player: {0} [Life:{1},Mana:{2},Hand:{3},Library:{4}]'.format(self.name, self.life, self.mana, len(self.hand), len(self.library) if self.library else self.library)
def setDeck(self, deck):
if not deck:
return
self.deck = copy.copy(deck)
for card in deck:
self.deck = copy.deepcopy(deck)
self.deck.owner = self
self.library = copy.copy(self.deck)
self.library.zone = 'library'
for card in self.deck:
# Re-initialize so the references are correct
card.__init__()
card.owner = self
def draw(self):
card = self.deck.pop()
self.hand.append(card)
card.moved.emit('deck', 'hand')
def setLife(self, life):
self.life = life
self.lifeChanged.emit(self.life)
def affectLife(self, amount):
self.life = self.life + amount
if amount:
self.lifeChanged.emit(self.life)
def payMana(self, cost):
try:
self.mana -= cost
except:
logging.debug('%s could not pay mana cost %s', self, cost)
return False
logging.debug('%s paid mana cost %s', self, cost)
return True
def draw(self, count=1):
for i in xrange(count):
card = self.library[0]
card.move(self.library, self.hand)
logging.debug('%s drew %s', self, card)
def cast(self, card):
hand.remove(card)
self.battlefield.append(card)
card.moved.emit('hand', 'battlefield')
logging.debug('%s attempts to cast %s', self, card)
if not self.payMana(card.cost):
logging.debug('%s failed to cast %s: Not enough mana', self, card)
return False
card.move(self.hand, self.battlefield)
logging.debug('%s successfully casts %s', self, card)
self.casts.emit(card)
return True
class Card:
def __init__(self, name, attributes, cost, power, toughness, owner=None):
self.name = name
def __init__(self, name, type, attributes, cost=0, power=0, toughness=0, owner=None):
self.name = name
self.type = type.lower()
self.attributes = [a.lower() for a in attributes]
self.cost = cost
self.cost = ManaCost(cost)
self.power = power
self.toughness = toughness
self.is_tapped = False
self.abilities = []
self.owner = owner
self.zone = None
# Events
self.moved = Observable()
@ -140,7 +183,7 @@ class Card:
self.store()
def __repr__(self):
return 'Card: [{2}] {0}: {1} [{3}/{4}]'.format(self.name, ' '.join([a.capitalize() for a in self.attributes]), self.cost, self.power, self.toughness)
return 'Card: [{3}] {0} -- {1}: {2} [{4}/{5}]{6}'.format(self.name, self.type.title(), ' '.join([a.capitalize() for a in self.attributes]), self.cost, self.power, self.toughness, ' [T]' if self.is_tapped else '')
def __mul__(self, other):
result = []
for i in xrange(other):
@ -150,27 +193,58 @@ class Card:
self.__stored = copy.copy(self)
def restore(self):
self = copy.copy(self.__stored)
def move(self, origin, destination):
origin.remove(self)
destination.append(self)
logging.debug('%s moved from %s to %s', self, origin.zone, destination.zone)
self.moved.emit(origin.zone, destination.zone)
def tap(self):
if self.is_tapped:
return False
self.is_tapped = True
logging.debug('%s is tapped', self)
self.tapped.emit()
return True
class Ability:
def __init__(self, target):
self.target = target
def __init__(self, card, name='Unknown', cost=0, tap=False):
self.card = card
self.name = name
self.cost = ManaCost(cost)
self.tap = tap
self.init()
def __repr__(self):
return 'Ability: {0} [{1}{2}]'.format(self.name, self.cost, ', T' if self.tap else '')
def init(self):
pass
def run(self):
pass
def activate(self):
logging.debug('%s attempting to activate %s on %s', self.card.owner, self, self.card)
if self.tap and self.card.is_tapped:
logging.debug('%s failed to activate %s on %s', self.card.owner, self, self.card)
return False
if self.card.owner.payMana(self.cost):
if self.tap:
self.card.tap()
logging.debug('%s succeeded activating %s on %s', self.card.owner, self, self.card)
self.run()
return True
logging.debug('%s failed to activate %s on %s', self.card.owner, self, self.card)
return False
class CardList(list):
def __init__(self, game):
def __init__(self, owner, zone):
list.__init__(self)
self.game = game
self.owner = owner
self.zone = zone
def append(self, item):
item.list = self
list.append(self, item)
class Deck(CardList):
def __init__(self):
pass
CardList.__init__(self, None, 'deck')
def shuffle(self):
random.shuffle(self)
def cards(self):

View file

@ -3,6 +3,8 @@ class Observable(object):
self.subscribers = []
def subscribe(self, subscriber):
self.subscribers.append(subscriber)
def unsubscribe(self, subscriber):
self.subscribers.remove(subscriber)
def emit(self, *args):
for fn in self.subscribers:
fn(*args)