Monday, April 20, 2009

A Million Details - Part 1

MTG Forge is made up of a million little bits of code. Magic has a huge number of details and you have to tackle each one without being overwhelmed. How will the user interface show damage and assigned combat damage? How will decks be stored, plain text or some other format? How will players assign combat damage to multiple blockers? How do you make a decent deck editor? Which dialog boxes are required during a typical game of Magic? (Dialog boxes are those things that pop up and say, "Are you sure you want to quit?")

Obviously Magic is very big so you have break it down into very small parts in order to translate it into specific steps that you can code. MTG Forge currently requires mana costs to have a space, such as "1 G G" and "W W". I made this decision because it was easier to decode the mana cost since it was already broken into pieces. Having the computer decode "1 G G" is easier than "1GG".

Requiring all mana costs to have spaces isn't a very big decision but it is a decision that affects the whole project. I could have spent a little more time on the code so the computer could decode "1GG" but I made a decision and stuck with it.

p.s.
If you want a small programming challenge write your own method to convert "1GG" into "1 G G". Other good test cases include "G", "GG", "10" and "10GGG". You can compare your code to mine on Wednesday.

15 comments:

Gando the Wandering Fool said...

Just off the top of my head this looks like a good use for a regular expression and a split.

Kaoru said...

kaoru@rukia:~$ cat split_manacosts.pl
#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;
$Data::Dumper::Indent = 0;

my @costs = qw(1GG G GG 10 10GGG);

foreach my $cost (@costs) {
my @split_cost = $cost =~ m/( \d+ | \w )/gmsx;
print Dumper(\@split_cost), "\n";
}

kaoru@rukia:~$ ./split_manacosts.pl
$VAR1 = ['1','G','G'];
$VAR1 = ['G'];
$VAR1 = ['G','G'];
$VAR1 = ['10'];
$VAR1 = ['10','G','G','G'];

----

Forge is written in Java right? Java supports Perl regular expressions so you should be able to use the /(\d+|\w)/ somehow.

Forge said...

Yes MTG Forge uses Java and Java supports regular expressions. Feel free to write your code or pseudocode in any language.

Forge said...

I didn't use regular expressions but it seems like a good way to go. My code is a longer that yours. Hopefully I can use
/(\d+|\w)/ but I've never used regular expressions before.

Silly Freak said...

The place to go is Pattern.
I don't memorize all that classes of regex, and I use it once in a while. There are also many more things you can do with Matchers than only matches().

By the way, a mistake that cost me hours in the beginning are backslashes. To produce "\" in a regular expression, you must escape it due to the regex syntax, that is "\\". But to write that string in java syntax, you have to escape them another time, meaning the result in your java source is "\\\\"

Silly Freak said...

and for extra coding fun, also include hybrid in the form X/Y. Or even X/Y/Z...

have fun ;)

grendel said...

One statement in Ruby. Tested from the console.

irb(main):055:0> "1GG".scan(/[[:digit:]]+|\{.*\}|\S/)
=> ["1", "G", "G"]

irb(main):056:0> "X3RR".scan(/[[:digit:]]+|\{.*\}|\S/)
=> ["X", "3", "R", "R"]

irb(main):057:0> "5{B/G}R".scan(/[[:digit:]]+|\{.*\}|\S/)
=> ["5", "{B/G}", "R"]

irb(main):058:0> "10".scan(/[[:digit:]]+|\{.*\}|\S/)
=> ["10"]

irb(main):059:0> "10U".scan(/[[:digit:]]+|\{.*\}|\S/)
=> ["10", "U"]

Forge said...

One line of Ruby can do alot.

grendel said...

Yea, I am constantly impressed by the simplicity of the language. However, to be honest, RegEx is the muscle in the operation. The base String class exposes a scan method which will take the RegEx pattern and return matches.

What I really like to do is to construct the cards in Ruby. You can do some really interesting stuff by dynamically adding new methods to an instantiated class. But this is a much more difficult problem.

Look forward to your next post.

Vio said...

Love the program a whole lot but ive run into a few problems and idk if you know about them or not but here goes. I play MTG Forge mostly on my Asus 1000HE Eee Pc and the bottom of the program stretches down past the bottom of the screen below the taskbar causing me to be unable to see the cards ive added into my deck. Therefor, i am unable to play quest whatsooever without having to memorize everything in my deck. Maybe you could, when maximized, have it show it to the side or something. Maximizing does help during matches when it stretches just below the taskbar but not too much. Thanks a million. Vio.

Vio said...

Oh and additionally, only about half or so of the card pictures are able to download before i get a "you must be connected to the internet" error message and the download stops. You may already know and are trying to fix the problem, its not too big of one atm in my opinion but its probably a good thing for you to know. Thanks again for the great program. Vio.

Forge said...

Vio,
You can get all the card pictures from here 37MB.

You can also try the "resizable game area" checkbox near the bottom of the screen, that may help you resize the window better.

Vio said...

Thanks a lot, the card pictures make playing much more agreeable but im still having the problem with the deck editor going too far below the screen. For one, i cant pull it up far enough to resize its not just in quest mode that i have the problem, its the deck editor in general. I hope you can give me some more help soon, oh and is there a forum i can post in or is commenting your blog the only thing i can do? Vio.

Vio said...

*Slaps forehead after reading the forum link* Lulz. Enough said. Will post further questions/commments where they should go, in the forum. Vio.

Forge said...

You could also try increasing the resolution, I think that will let you see more on the screen.