Some updates, including a Forest card coupled with its Tap Land ability
This commit is contained in:
parent
8a08b97c7b
commit
869b2f3357
5 changed files with 140 additions and 25 deletions
|
@ -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
|
||||
|
|
16
cards.py
16
cards.py
|
@ -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
18
main.py
Normal 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
120
mtg.py
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue