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
|
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):
|
class Lifelink(mtg.Ability):
|
||||||
pass
|
pass
|
||||||
|
|
16
cards.py
16
cards.py
|
@ -1,4 +1,17 @@
|
||||||
from mtg import *
|
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
|
Elvish Archdruid
|
||||||
1GG
|
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.
|
{T}: Add {G} to your mana pool for each Elf you control.
|
||||||
M10-R
|
M10-R
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Elvish_Archdruid(Card):
|
class Elvish_Archdruid(Card):
|
||||||
def __init__(self):
|
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()
|
118
mtg.py
118
mtg.py
|
@ -1,5 +1,6 @@
|
||||||
import copy
|
import copy
|
||||||
import random
|
import random
|
||||||
|
import logging
|
||||||
from observable import Observable
|
from observable import Observable
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
|
@ -99,39 +100,81 @@ class ManaCost:
|
||||||
return self.mana.converted() + self.any
|
return self.mana.converted() + self.any
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
def __init__(self, name, deck=None):
|
def __init__(self, name, game, deck=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.game = game
|
||||||
|
self.life = 20
|
||||||
|
self.mana = Mana()
|
||||||
self.deck = None
|
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.setDeck(deck)
|
||||||
self.hand = CardList()
|
|
||||||
self.graveyard = CardList()
|
self.lifeChanged = Observable()
|
||||||
self.battlefield = CardList()
|
self.defeated = Observable()
|
||||||
|
self.casts = Observable()
|
||||||
|
|
||||||
|
logging.debug('Initialized %s', self)
|
||||||
def __repr__(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):
|
def setDeck(self, deck):
|
||||||
if not deck:
|
if not deck:
|
||||||
return
|
return
|
||||||
self.deck = copy.copy(deck)
|
self.deck = copy.deepcopy(deck)
|
||||||
for card in 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
|
card.owner = self
|
||||||
def draw(self):
|
def setLife(self, life):
|
||||||
card = self.deck.pop()
|
self.life = life
|
||||||
self.hand.append(card)
|
self.lifeChanged.emit(self.life)
|
||||||
card.moved.emit('deck', 'hand')
|
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):
|
def cast(self, card):
|
||||||
hand.remove(card)
|
logging.debug('%s attempts to cast %s', self, card)
|
||||||
self.battlefield.append(card)
|
|
||||||
card.moved.emit('hand', 'battlefield')
|
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:
|
class Card:
|
||||||
def __init__(self, name, attributes, cost, power, toughness, owner=None):
|
def __init__(self, name, type, attributes, cost=0, power=0, toughness=0, owner=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
self.type = type.lower()
|
||||||
self.attributes = [a.lower() for a in attributes]
|
self.attributes = [a.lower() for a in attributes]
|
||||||
self.cost = cost
|
self.cost = ManaCost(cost)
|
||||||
self.power = power
|
self.power = power
|
||||||
self.toughness = toughness
|
self.toughness = toughness
|
||||||
|
self.is_tapped = False
|
||||||
|
self.abilities = []
|
||||||
|
|
||||||
self.owner = owner
|
self.owner = owner
|
||||||
|
self.zone = None
|
||||||
|
|
||||||
# Events
|
# Events
|
||||||
self.moved = Observable()
|
self.moved = Observable()
|
||||||
|
@ -140,7 +183,7 @@ class Card:
|
||||||
|
|
||||||
self.store()
|
self.store()
|
||||||
def __repr__(self):
|
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):
|
def __mul__(self, other):
|
||||||
result = []
|
result = []
|
||||||
for i in xrange(other):
|
for i in xrange(other):
|
||||||
|
@ -150,27 +193,58 @@ class Card:
|
||||||
self.__stored = copy.copy(self)
|
self.__stored = copy.copy(self)
|
||||||
def restore(self):
|
def restore(self):
|
||||||
self = copy.copy(self.__stored)
|
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):
|
def tap(self):
|
||||||
|
if self.is_tapped:
|
||||||
|
return False
|
||||||
|
self.is_tapped = True
|
||||||
|
logging.debug('%s is tapped', self)
|
||||||
self.tapped.emit()
|
self.tapped.emit()
|
||||||
|
return True
|
||||||
|
|
||||||
class Ability:
|
class Ability:
|
||||||
def __init__(self, target):
|
def __init__(self, card, name='Unknown', cost=0, tap=False):
|
||||||
self.target = target
|
self.card = card
|
||||||
|
self.name = name
|
||||||
|
self.cost = ManaCost(cost)
|
||||||
|
self.tap = tap
|
||||||
self.init()
|
self.init()
|
||||||
|
def __repr__(self):
|
||||||
|
return 'Ability: {0} [{1}{2}]'.format(self.name, self.cost, ', T' if self.tap else '')
|
||||||
def init(self):
|
def init(self):
|
||||||
pass
|
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):
|
class CardList(list):
|
||||||
def __init__(self, game):
|
def __init__(self, owner, zone):
|
||||||
list.__init__(self)
|
list.__init__(self)
|
||||||
self.game = game
|
self.owner = owner
|
||||||
|
self.zone = zone
|
||||||
def append(self, item):
|
def append(self, item):
|
||||||
item.list = self
|
item.list = self
|
||||||
list.append(self, item)
|
list.append(self, item)
|
||||||
|
|
||||||
class Deck(CardList):
|
class Deck(CardList):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
CardList.__init__(self, None, 'deck')
|
||||||
def shuffle(self):
|
def shuffle(self):
|
||||||
random.shuffle(self)
|
random.shuffle(self)
|
||||||
def cards(self):
|
def cards(self):
|
||||||
|
|
|
@ -3,6 +3,8 @@ class Observable(object):
|
||||||
self.subscribers = []
|
self.subscribers = []
|
||||||
def subscribe(self, subscriber):
|
def subscribe(self, subscriber):
|
||||||
self.subscribers.append(subscriber)
|
self.subscribers.append(subscriber)
|
||||||
|
def unsubscribe(self, subscriber):
|
||||||
|
self.subscribers.remove(subscriber)
|
||||||
def emit(self, *args):
|
def emit(self, *args):
|
||||||
for fn in self.subscribers:
|
for fn in self.subscribers:
|
||||||
fn(*args)
|
fn(*args)
|
||||||
|
|
Loading…
Reference in a new issue