Monday, November 24, 2008

The Future of This Blog

I have confused and/or frustrated a few people by saying that I plan on making my own version this great, physics game. It is called Fantastic Contraption and you can play it in your browser here.

I'm glad people are interested in MTG Forge version 2. Not to further confuse everybody, I plan on working on MTG Forge version 2 to at least get it playable. I'm thinking around 50 cards and hopefully a little better AI. I really want to have undo and use my idea of plaintext cards. After I get version 2 working, I'll probably work on Fantastic Contraption (FC) and blog about that. I'm guessing that I'll work about 6 months on FC and then get back to MTG Forge 2.0.

I tentatively plan to get MTG Forge 2.0 working and then blog about my creative efforts to copy FC. FC will be cool because it will force me to write a real videogame interface and I get to use some cool physics code that someone else wrote. (I thought I might have to write my own little physics engine but thankfully I don't, thank you Internet.)

---------------

Well I've decided to keep working on MTG Forge version 2. My interest in Magic has been renewed. (Sometimes I think I enjoy programming Magic as much as playing Magic, it just depends what kind of mood I am in.)

Wednesday, November 19, 2008

Suggest a Topic

This is probably the lamest post ever but hopefully it will generate a number of comments. What do you, the reader, want to read about? What topics interest you the most? I feel like I’ve talked about everything concerning Magic and MTG Forge twice over.

I do a decent job of just working on MTG Forge and then writing about my experiences. I try to write about computer programming in an interesting fashion. I love to program and I think programming is exciting. And computer programming is especially exciting when you combine it with something fun like Magic: The Gathering. While I’m sure I could get a little excited about coding some sort of business billing application, working on a game I enjoy is much more interesting.

My goal when I write for this blog is to involve both computer programming and Magic. I try not to delve too deep into programming because I don’t want to alienate anyone, although I have a great idea for my update of the Observer pattern which I call an Ordered Observer.

So in closing, tell me what you want to read about. Do you want me to do the occasional Magic rules lawyering, such as explaining the interaction of continuous effects which has 6 layers, section 418.5 in the comprehensive rules? Or do you just want me to talk more about programming Magic? I wouldn’t mind writing a few articles about just Magic but I’m not sure what specifically to write about.

So just post a comment about what topics are interesting to you. For each comment you post I'll send you one mythic rare (this offer is invalid if you own more than 3 Magic cards). Truthfully I don't any mythic rares, so you all are out of luck ;)

Monday, November 17, 2008

Programming CardArray

Let me state the obvious, Magic is a game that involves cards, so almost every aspect of MTG Forge involves moving or counting cards, thus the “CardArray” object was created. (CardArray is an array that holds Card objects. Also remember that an object is just group of related code.) To begin with CardArray was very simple but as time went on more and more methods were added to it. (An object is a collection of many methods.)

CardArray does many things like it can return all cards that are creatures or lands. CardArray even has a filter option that lets you specify any type of criteria. The computer AI for Shock uses the filter option to burn 2/2 or 3/1 flyers.

The filter option is used for many different types of cards. Nevinyrral's Disk uses filter to first create a CardArray of only artifacts, creatures, and enchantments and then loops through that CardArray destroying everything. Needle Storm uses the filter to only damage creatures with flying. Anytime a card interacts with multiple other cards, CardArray is used. All zones, like your library and graveyard, are basically just CardArray objects.

And although CardArray is a simple chunk of code, it is very important. Since CardArray does one thing well, it holds cards, you can use it absolutely everywhere since it is very versatile.

p.s.
MTG Forge doesn’t have an object named CardArray, instead it is called CardList since it is basically just a fancy ArrayList. I used the name CardArray since most programmers know what the word “array” means.

Wednesday, November 12, 2008

AI – MTG Forge, Alpha-beta pruning

MTG Forge’s current AI is very basic. It tries to play the highest costed card and it attacks unless you have a creature that is bigger. A better AI would generate possible future game states and would then choose the best future. In other words, the AI would simulate what if it played card A and then simulate what if it played card B. This type of AI deals only with predicting future game states. Min-max and alpha-beta pruning are two types of predicting algorithms. This type of AI does not learn.

In order to effectively use predicting algorithms you have to generate many future states and you must decide how “deep” you want to test. Do you generate just one level deep for combat or do you want to generate three levels deep Main1, combat, Main2 or do you want to generate Computer Combat, Human Computer, Computer Combat?

On another issue, a better AI for MTG Forge’s draft mode would have access to a pick list and would just select the card that was highest on the list. The pick list could be a global pick list of all the cards or could be divided up into deck archetypes. The AI for sealed could be similar and use the same pick lists as the draft AI. The current draft AI randomly chooses two colors before the draft starts and then chooses creatures then spells in those colors. (It sounds brain-dead but it was pretty hard to program, lol.)

Monday, November 10, 2008

AI Thoughts – Genetic Algorithms and Neural Networks

AI (artificial intelligence) is a great subject so I thought I would discuss what little I know about it. Let me first tell you a little about my educational background, I have my bachelor’s in Information Science and I didn’t take any AI classes in college. My knowledge about AI comes from miscellaneous web articles and the three random books I have own the subject.

AI encompasses a huge number of topics ranging from getting a computer to drive a car to trying to find fraudulent credit card charges. There are many different types of AI algorithms and techniques. Some techniques require a vast amount of historical data while others do not. Videogame AI usually has to be fast, to simulate the response of a real human. In my opinion most videogames have only a very basic AI. Many videogames like Mario don’t have any AI and it is just the player versus the environment.

People sometimes talk about neural networks or genetic algorithms but they don’t usually work well for videogames. Neural networks usually have many inputs and only one output. They are typically used to output an answer like yes or no. Neural networks are also very complicated to setup and test.

Genetic algorithms find an optimal or near-optimal solution to a problem by generating random actions. Granted the problem could be “how to win a game of Magic” but encoding a game of Magic into a genetic algorithm would be extremely difficult. Usually genetic algorithms are encoded as strings, although this is not a requirement. The strings are split and combined to form new strings. Each string is evaluated until a solution is found.

Join me next time as I continue our journey into AI.

Friday, November 7, 2008

MTG Forge – New Version

I posted a new version of MTG Forge and you can get it here. This is only a minor update. You can now import and export any type of deck: sealed, draft, or constructed. When you import another person’s draft deck, it will be listed with your other draft decks, the same goes for sealed and constructed. When you import a draft deck it will only show the cards that the person picked, you don’t get to draft again.

The export deck option now creates a text file showing the deck’s contents. Below is an example of what the text file looks like. This should save some time when you post a deck. You can post and download decks here. Creating a new deck and posting it is really fun, I encourage you to try it out. You can even checkout some of my (lame) decks, lol.

And remember to save a copy of the file "all-decks2" since that holds all of the decks that you have created.

40 Total Cards

22 Creatures
-------------
1x Haunted Angel
4x Lantern Kami
4x Leonin Skyhunter
4x Mistral Charger
3x Radiant, Archangel
2x Serra Avenger
4x Suntail Hawk

2 Spells
----------
1x Glorious Anthem
1x Wrath of God

16 Land
--------
16x Plains

Wednesday, November 5, 2008

Random Thoughts

I don’t have anything specific to talk about today, so I’m just going to ramble until I get 200-300 words. I haven’t worked much on MTG Forge version 2 recently. Real life is getting in the way of my hobbies, lol. I still think about version 2, I just need to sit down for about 30 minutes a day and just get something done. I enjoy programming because it is actually pretty easy. (Usually programming is easy, but trying to fix a specific bug is usually very hard.)

For version 2 I want to implement a better AI but if I can’t, you’ll just have to make do with the current AI. Artificial intelligence is very interesting to programmers and non-programmers alike. AI covers everything, so it is hard to learn a specific concept and apply to the problem that you are working on. Like a car racing AI can only race cars. The AI also is tightly integrated with the rest of the program, so you can’t really strip the AI out and use it for something else.

On a different front, Shards of Alara looks like a great set. It is dripping flavor and has several new mechanics to learn. I remember when Lorwyn came out and no one was sure how clash was going to work, the same thing goes for Ravnica and dredge.

p.s. The card picture is from the Jace vs. Chandra decks which have their own unique, set symbol.

p.s.s. Join me next week for two semi-decent AI articles :)

Monday, November 3, 2008

How to Program Royal Assassin

From time to time I like looking at how other Magic projects implemnt a card. I love Royal Assassin, this is how Firemox (formally the Magic-Project) and Incantus encode it. Incantus has card characteristics and if you read Magic’s comprehensive rules you will notice that it uses characteristics also. Since both Firemox and Incantus put each card in a separate file, all you have to do is download the file from the Internet and put it in the right directory and voila you have just added a new card.

In an effort to be complete, I’ll also show you the code for Royal Assassin taken from MTG Forge. The code is a little long and complicated compared to Firemox and Incantus. The Input class handles all mouse input, so a new Input object is created and used to target a tapped creature.


Incantus
//filename: Royal Assassin
name = 'Royal Assassin'
cardnum = 174
type = characteristic('Creature')
supertype = characteristic('')
subtypes = characteristic(['Human', 'Assassin'])
cost = '1BB'
color = characteristic(['B'])
text = ['T Destroy target tapped creature.']

in_play_role = Creature(card, 1, 1)
in_play_role.abilities = [ActivatedAbility(card, TapCost(),
target=Target(target_types=isCreature.with(lambda c: c.tapped)),
effects=Destroy())
]
in_play_role.triggered_abilities = []
in_play_role.static_abilities = []


Firemox
//filename: Royal_Assassin.xml
//all brackets were converted to quotes
//in order to be displayed correctly

"?xml version="1.0"?"
"card xmlns="http://sourceforge.net/projects/firemox" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=http://sourceforge.net/projects/firemox ../../validator.xsd name="Royal Assassin""
"rules-author-comment"By fabdouglas"/rules-author-comment"

"init"
"registers"
"register index="colorless" value="1"/"
"register index="black" value="2"/"
"register index="power" value="1"/"
"register index="toughness" value="1"/"
"/registers"

"colors"black"/colors"
"idcards"creature "/idcards"
"properties"assassin"/properties"
"/init"

"abilities"
"ability ref="cast-spell"/"
"activated-ability playable="instant" name="" zone="play""
"cost"
"action ref="T"/"
"action ref="target-creature""
"test"
"in-zone zone="playANDtapped"/"
"/test"
"/action"
"/cost"

"effects"
"action ref="destroy"/"
"/effects"
"/activated-ability"
"/abilities"
"/card"


MTG Forge
//taken from the infamous CardFactory

if(cardName.equals("Royal Assassin"))
{

final Ability_Tap ability = new Ability_Tap(card)
{

public boolean canPlayAI()
{
CardList human =
CardFactoryUtil.AI_getHumanCreature();

human = human.filter(new CardListFilter()
{
public boolean addCard(Card c)
{return c.isTapped();}
});

CardListUtil.sortAttack(human);
CardListUtil.sortFlying(human);

if(0 < human.size())
setTargetCard(human.get(0));

return 0 < human.size();
}//canPlayAI()

public void resolve()
{
Card c = getTargetCard();

if(AllZone.GameAction.isCardInPlay(c)
&& c.isTapped())
{
AllZone.GameAction.destroy(c);
}

}//resolve()
};//SpellAbility

Input target = new Input()
{
public void showMessage()
{
AllZone.Display.showMessage("Select target tapped creature to destroy");

ButtonUtil.enableOnlyCancel();
}

public void selectButtonCancel()
{stop();}

public void selectCard(Card c, PlayerZone zone)
{
if(c.isCreature() &&
zone.is(Constant.Zone.Play) &&
c.isTapped())
{
//tap ability
card.tap();

ability.setTargetCard(c);
AllZone.Stack.add(ability);
stop();
}//if
}//selectCard()
};//Input

card.addSpellAbility(ability);
ability.setDescription("tap: Destroy target tapped creature.");
ability.setBeforePayMana(target);
}