
Today I’m going to talk about Incantus and MagicWars. Both programs enforce the rules and allow you to play against other people over the Internet. Even though these two projects are completely separate, they encode Magic cards in a similar way. Each card is very short and is written in either Python or Java. Incantus was written in Python while MagicWars uses Java.
Incantus is the current king-of-the-hill when it comes to supporting the most cards. Incantus currently has more than 6,000 cards which is phenomenal. Of all of the freeware Magic programs, Incantus has the best user interface with all of the eye candy that you would ever want. Incantus has very readable, short card code that is written in Python. Currently the source code of Incantus is semi-private. It isn’t an open source project but you can get the source by reading through the Incantus forum.
MagicWars is newer than Incantus and has more than 550 cards including all 145 cards from Alara Reborn, go cascade!! MagicWars uses Groovy to encode Magic cards. The Groovy homepage says that it:
-- Builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk.
-- Makes modern programming features available to Java developers with almost-zero learning curve.
--Supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain.
Groovy compiles to Java bytecode, so it can run anywhere that Java can. The MagicWars blog also says that “A Groovy Closure is like a ‘code block’ or a method pointer. It is a piece of code that is defined and then executed at a later point.” So Groovy is short like a domain specific language (see my previous article) and yet powerful enough to be a full-fledged language all by itself. Right now I don’t know anything about Groovy but it seem very interesting.
MagicWars also has a very nice blog that describes how it specifically uses Groovy. The blog encourages non-programmers to learn some syntax and to create their own favorite card.
Incantus:
ScreenshotForum MagicWars:
Screenshot - game in progress
Screenshot - deck editor
Download ForumBlogGroovyIncantus - Royal Assassin
name = 'Royal Assassin'
cardnum = 0
expansion = ''
types = characteristic('Creature')
supertypes = no_characteristic()
subtypes = characteristic('Assassin', 'Human')
cost = '1BB'
color = characteristic('B')
power = 1
toughness = 1
text = ['T: Destroy target tapped creature.']
play_spell = play_permanent()
#################################
@activated(txt=text[0])
def ability():
def effects(controller, source):
cost = yield TapCost()
target = yield Target(isCreature.with_condition(lambda c: c.tapped))
target.destroy()
yield
return effects
abilities.add(ability)
Incantus - Shock
name = 'Shock'
cardnum = 0
expansion = ''
types = characteristic('Instant')
supertypes = no_characteristic()
subtypes = no_characteristic()
cost = 'R'
color = characteristic('R')
text = ['Shock deals 2 damage to target creature or player.']
#################################
@play_instant()
def effects(controller, source):
cost = yield source.cost
target = yield Target(isCreatureOrPlayer)
source.deal_damage(target, 2)
yield
play_spell = effects
MagicWars – Royal Assassin
name = "Royal Assassin"
types = ["Creature","Human","Assassin"]
manacost = "1 B B"
text = ["{T}: Destroy target tapped creature."]
power = 1
toughness = 1
prints = [
["M10", "R", 191318, 110],
["10E", "R", 129708, 174],
["9E", "R", 83235, 159],
["8E", "R", 45323, 159],
["4E", "R", 2124, 41]
]
script = '''\
addAbilityTap({
destroyTarget($target, $this)
}, "0")
setSpecificTarget("Select target
tapped creature to destroy.",
{
return $permanent.isCreature() &&
$permanent.isTapped()
})'
MagicWars - Shock
name = "Shock"
types = ["Instant"]
manacost = "R"
text = ["Shock deals 2 damage to target creature or player."]
prints = [
["10E", "C", 129732, 232],
["9E", "C", 83261, 220],
["ONS", "C", 39482, 227]
]
script = '''\
addSpell({
dealDamage($target, 2, $this);
})
setTarget("Creature|Player")
'''