Monday, June 29, 2009

Xbox AI

I wanted to briefly talk about the two articles that Wizards posted about the new Xbox game. (The game doesn't have a deck editor if you can believe it and is an introduction to the game of Magic.) The AI seems pretty good. The game starts on medium difficulty but the user can change it to make it more challenging.

The article mentions that the AI will attack with a 1/1 into a 2/2 if it is holding Giant Growth and an untapped Forest. And "there's the time it attacked with a bunch of green creatures, let me block, and only then used Elvish Piper to drop a Roughshod Mentor into play and give everything trample." While these examples wouldn't win a pro tournament they are still impressive for a computer. While effectively using Giant Growth isn't rocket science the key idea is that the Xbox AI can use other cards like Giant Growth without additional programming.

One of the articles mentions that the AI can only look ahead for one combat phase. For example the computer might attack with all of its creatures just to lose when the human player attacks with his creatures. I find that this scenario occurs often in the games that I play. MTG Forge's AI also makes this error because the combat logic is relatively primitive.

The user interface is separate from the rules engine which is always good. One of the articles even shows the internal representation of Angel of Mercy. While I think using XML for Magic cards is cumbersome, it is interesting to see how a "commercial Magic" project does it. (You can right click and open the gif below in a new window in order to see it more clearly.)

p.s. It is great to see Lightning Bolt again in Magic 2010. I didn't think it would ever be reprinted.

7 comments:

willow said...

I wish we could have our AIs compete against each other to reveal their strengths and their flaws :)

Rule said...

Hey, you seem to be much in favour of plain text format for storing cards. What are your main reasons for preferring it over XML? I'm curious to know.

nantuko84 said...

Hi, Forge
I also use plain text for cards (especially since I started with your code that included cards.txt ;))

one reason is that a plain text makes more sense for me than xml
moreover it's so simple to copy cards' info from e.g. magiccards.info for simple ones that it takes few seconds.

the second was that I was not familiar with xml parsing. it seemed rather difficult for me ;)

and not long ago I've tried jaxb
that can create classes from xsd and parse xml for you. you just call unmarshal(file) and that's it!
after that you just call methods mapped to nodes

but I guess the most difficult part is not with parsing, but with implementing triggers and abilities. first you need to create engine that will "eat" such xmls and do whatever you want ;)

Forge said...

I like the idea of XML with self-describing tags but parsing it is almost insane. You either have to read the whole XML file and then parse it, or read it on the fly and create triggers that activate when it reads a certain tag. I wrote my own very simple XML parser that had two methods. getTags() and readTag(String tag). XML also has exploded into multiple other technologies, much like Java, DOM Level 2, SAX 2, XSLT, and Namespaces.

My philosophy is to use whatever technology that you like: XML, plaintext, Visual Basic, or Perl.

Unknown said...

I didn't read the two Wizards articles yet, but...

As you see in the Angel of Mercy example... XML is a standard human readable format that lets you nest a tree of items. Example: CARD -> STATIC_ABILITY -> TRIGGERED_ABILITY -> (TRIGGER, EFFECT). Emphasis on standard and nested (similar to the OO Composite design pattern, since an XML element can have children that are either elements or values).

This example XML is defining the rules for one card, and referencing code functions from the XML. Flying(), return SelfTriggered(), YouGainLife( 3 ). These might be functions in Python or Lua, that expose functionality in the core C++ code.

Using XML to specify the card's rules does not preclude you from using a simpler human readable txt file to specify decks, such as a simpler INI file:

; 60 card deck list, example shows 8 cards:
[deck]
4, ANGEL_OF_MERCY
4, PLAINS

; 15 card side deck, , example shows 4 cards:
[side]
4, ANGEL_OF_MERCY

So you could have the following... Core C++ code. Python (or Lua) scripting language that exposes a simpler form of the core C++ code. XML per card rules which reference the Python (or Lua) scripting language. Then, finally, per deck INI files that simply specify what cards are in the deck

Unrelated aside, I think it's weird how their example XML says ANGEL_OF_MERCY_FLAVOUR, instead of just specifying the flavor text directly in the card's XML.

Unknown said...

I didn't read the two Wizards articles yet, but...

As you see in the Angel of Mercy example... XML is a standard human readable format that lets you nest a tree of items. Example: CARD -> STATIC_ABILITY -> TRIGGERED_ABILITY -> (TRIGGER, EFFECT). Emphasis on standard and nested (similar to the OO Composite design pattern, since an XML element can have children that are either elements or values).

This example XML is defining the rules for one card, and referencing code functions from the XML. Flying(), return SelfTriggered(), YouGainLife( 3 ). These might be functions in Python or Lua, that expose functionality in the core C++ code.

Using XML to specify the card's rules does not preclude you from using a simpler human readable txt file to specify decks, such as a simpler INI file:

; 60 card deck list, example shows 8 cards:
[deck]
4, ANGEL_OF_MERCY
4, PLAINS

; 15 card side deck, , example shows 4 cards:
[side]
4, ANGEL_OF_MERCY

So you could have the following... Core C++ code. Python (or Lua) scripting language that exposes a simpler form of the core C++ code. XML per card rules which reference the Python (or Lua) scripting language. Then, finally, per deck INI files that simply specify what cards are in the deck

Unrelated aside, I think it's weird how their example XML says ANGEL_OF_MERCY_FLAVOUR, instead of just specifying the flavor text directly in the card's XML.

Unknown said...

I didn't read the two Wizards articles yet, but...

As you see in the Angel of Mercy example... XML is a standard human readable format that lets you nest a tree of items. Example: CARD -> STATIC_ABILITY -> TRIGGERED_ABILITY -> (TRIGGER, EFFECT). Emphasis on standard and nested (similar to the OO Composite design pattern, since an XML element can have children that are either elements or values).

This example XML is defining the rules for one card, and referencing code functions from the XML. Flying(), return SelfTriggered(), YouGainLife( 3 ). These might be functions in Python or Lua, that expose functionality in the core C++ code.

Using XML to specify the card's rules does not preclude you from using a simpler human readable txt file to specify decks, such as a simpler INI file:

; 60 card deck list, example shows 8 cards:
[deck]
4, ANGEL_OF_MERCY
4, PLAINS

; 15 card side deck, , example shows 4 cards:
[side]
4, ANGEL_OF_MERCY

So you could have the following... Core C++ code. Python (or Lua) scripting language that exposes a simpler form of the core C++ code. XML per card rules which reference the Python (or Lua) scripting language. Then, finally, per deck INI files that simply specify what cards are in the deck

Unrelated aside, I think it's weird how their example XML says ANGEL_OF_MERCY_FLAVOUR, instead of just specifying the flavor text directly in the card's XML.