Color Identity by Hellfish
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
15 posts
• Page 1 of 1
Color Identity by Hellfish
by Max mtg » 30 Mar 2013, 13:52
There is a commit from Hellfish (r20671) that introduces color identities of cards.
I heartly welcome your next step towards EDH, but have to argue about it's implementation.
Since "color identity of a card is specified by all mana symbols that appear on the card anywhere, including within its rules text" it's easy to determine it.
We already have card's casting cost, that's one set of mana symbols. The remaining mana symbols can be parsed from oracle text, where all mana symbols are enclosed in curly braces. The only thing to do is write that parser, take StringTokenizer get that enclosed fragments and for each when it's not number feed it to ManaCostShard.parseNonGeneric() method.
Why not precalculate and store color identity in card scripts?
- Harder to mantain scripts (will have to add identity to newly created cards)
- Have to develop a tool to calculate anyway, that will mean parsing some external data sources, which can be late from the date the set is avaliable and Forge ready to play with it's cards.
- Excessive or duplicate data was never good.
Will you, Hellfish, please write a routine to calculate card's color identity?
PS: Answering the question in comments - forge.CardColor uses strings array to identify colors and has to be replaced with that newer other class, however that replace still was not made because the former class contains a timestamp. I don't think it's useful to create separate classes for color+timestamp, type+timestamp, but instead create a class TimeStamped<T> to store a number of values coupled with their timestamp.
I heartly welcome your next step towards EDH, but have to argue about it's implementation.
- Code: Select all
else if ("ColorIdentity".equals(key)) {
// This is forge.card.CardColor not forge.CardColor.
// Why do we have two classes with the same name?
ColorSet newCol = ColorSet.fromNames(value.split(","));
this.faces[this.curFace].setColorIdentity(newCol);
}
Since "color identity of a card is specified by all mana symbols that appear on the card anywhere, including within its rules text" it's easy to determine it.
We already have card's casting cost, that's one set of mana symbols. The remaining mana symbols can be parsed from oracle text, where all mana symbols are enclosed in curly braces. The only thing to do is write that parser, take StringTokenizer get that enclosed fragments and for each when it's not number feed it to ManaCostShard.parseNonGeneric() method.
Why not precalculate and store color identity in card scripts?
- Harder to mantain scripts (will have to add identity to newly created cards)
- Have to develop a tool to calculate anyway, that will mean parsing some external data sources, which can be late from the date the set is avaliable and Forge ready to play with it's cards.
- Excessive or duplicate data was never good.
Will you, Hellfish, please write a routine to calculate card's color identity?
PS: Answering the question in comments - forge.CardColor uses strings array to identify colors and has to be replaced with that newer other class, however that replace still was not made because the former class contains a timestamp. I don't think it's useful to create separate classes for color+timestamp, type+timestamp, but instead create a class TimeStamped<T> to store a number of values coupled with their timestamp.
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Max mtg » 30 Mar 2013, 14:04
And speaking of data incapsulation, colorIdentity is sooner a property of CardRules, than of CardFace.
That is to say the identity has to be calculated in CardPrinted ctor or on first access, and be removed from CardFace and ICardCharacteristics.
That is to say the identity has to be calculated in CardPrinted ctor or on first access, and be removed from CardFace and ICardCharacteristics.
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Hellfish » 30 Mar 2013, 19:03
I had a reply here about how the color identity field was only required for a select few cards before I realised other cards would need a corrected identity as well... D'oh! :S I'll take a look at doing it better soon.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-

Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Color Identity by Hellfish
by Max mtg » 01 Apr 2013, 18:50
r20706 looks amazing.
May I commit a different revision of method calculateColorIdentity?
May I commit a different revision of method calculateColorIdentity?
- Code: Select all
private byte calculateColorIdentity(ICardFace face)
{
byte res = face.getManaCost() == null ? 0 : face.getManaCost().getColorProfile();
boolean isReminder = false;
boolean isSymbol = false;
String oracleText = face.getOracleText();
int len = oracleText.length();
for(int i = 0; i < len; i++) {
char c = oracleText.charAt(i); // This is to avoid needless allocations performed by toCharArray()
switch(c) {
case('('): isReminder = true; break;
case(')'): isReminder = false; break;
case('{'): isSymbol = true; break;
case('}'): isSymbol = false; break;
default:
if(isSymbol && !isReminder) {
switch(c) {
case('W'): res |= MagicColor.WHITE; break;
case('U'): res |= MagicColor.BLUE; break;
case('B'): res |= MagicColor.BLACK; break;
case('R'): res |= MagicColor.RED; break;
case('G'): res |= MagicColor.GREEN; break;
}
}
break;
}
}
return res;
}
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Hellfish » 01 Apr 2013, 19:18
Sure. Improve away. 
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-

Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Color Identity by Hellfish
by Max mtg » 01 Apr 2013, 20:00
You haven't left much to improve.Hellfish wrote:Sure. Improve away.
That is the only thing I wanted to change.
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Hellfish » 01 Apr 2013, 20:10
Found a little bug, actually, but that should be it.
Thanks.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-

Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Color Identity by Hellfish
by Max mtg » 01 Apr 2013, 20:44
With that fulfilled, decks can be checked to match commander's profile.Hellfish wrote:Found a little bug, actually, but that should be it.Thanks.
Remaining features:
* add a special attribute on card which acts as a general.
* accumulation of damage dealt to players by generals, check it as a lose condition.
* add a replacement trigger on commander when game starts
* cast commander from command zone and count number of times it was cast to adjust the price by

Am I right about that?
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by friarsol » 01 Apr 2013, 21:05
I believe also:
"A deck may not generate mana outside its colours. If an effect would generate mana of an illegal colour, it generates colourless mana instead."
Does the implementation of color identity conform to this rule?
"A card's colour identity is its colour plus the colour of any mana symbols in the card's rules text. A card's colour identity is established before the game begins, and cannot be changed by game effects."
Do we already have a banned list setup for Commander?
"A deck may not generate mana outside its colours. If an effect would generate mana of an illegal colour, it generates colourless mana instead."
Does the implementation of color identity conform to this rule?
"A card's colour identity is its colour plus the colour of any mana symbols in the card's rules text. A card's colour identity is established before the game begins, and cannot be changed by game effects."
Do we already have a banned list setup for Commander?
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Color Identity by Hellfish
by Hellfish » 01 Apr 2013, 21:16
Color Identity is calculated when loading the scripts so the bold bit is fine.
The other bits are not implemented yet though.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-

Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: Color Identity by Hellfish
by Max mtg » 01 Apr 2013, 21:52
Sol, identity won't change as long as CardRules remains immutable.
Hellfish, I could not help implementing that small feature about 21 general damage as GL reason - because it's easy and gives lots of fun - sorry!
Hellfish, I could not help implementing that small feature about 21 general damage as GL reason - because it's easy and gives lots of fun - sorry!
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by friarsol » 01 Apr 2013, 23:01
The EDH Damage implementation is incorrect in two ways:Max mtg wrote:Hellfish, I could not help implementing that small feature about 21 general damage as GL reason - because it's easy and gives lots of fun - sorry!
- Needs to be combat damage
- It's 21 damage by a particular Commander, not total from all Commanders.
"If a player has been dealt 21 points of combat damage by a particular Commander during the game, that player loses a game"
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Color Identity by Hellfish
by Max mtg » 02 Apr 2013, 06:27
Uh.. right. I have reverted the variable added to player class, there has to be a map of player(cmdr ctrl'er)->int(damage dealt) instead and only combat damage taken into consideration.
The rest like GL reason and player outcome still can be used.
The rest like GL reason and player outcome still can be used.
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Max mtg » 02 Apr 2013, 21:36
I saw you've copied the InputMulligan class.
I wrote this not to say that copy-paste is a bad practice (you know that it is), but at the moment InputMulligan contains some logic that is to be execute in pooled thread, not EDT, and should be moved outside of mulligan class - that is everything related to leylines and chancellors
I wrote this not to say that copy-paste is a bad practice (you know that it is), but at the moment InputMulligan contains some logic that is to be execute in pooled thread, not EDT, and should be moved outside of mulligan class - that is everything related to leylines and chancellors
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
Re: Color Identity by Hellfish
by Max mtg » 26 Apr 2013, 19:29
Oh, I almost forgot: Thanks for your color identity code!
The colored deck generation looks much better when backed by the color identity you've implemented!
The colored deck generation looks much better when backed by the color identity you've implemented!
Single class for single responsibility.
- Max mtg
- Programmer
- Posts: 1997
- Joined: 02 Jul 2011, 14:26
- Has thanked: 173 times
- Been thanked: 334 times
15 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 20 guests