It is currently 29 Oct 2025, 08:53
   
Text Size

Color Identity by Hellfish

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins

Color Identity by Hellfish

Postby 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.
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);
                }
This code is intended to read identity directly from cards, but I can't figure out why cannot this be calculated?

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

Postby 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.
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

Postby 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
User avatar
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

Postby Max mtg » 01 Apr 2013, 18:50

r20706 looks amazing.
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

Postby Hellfish » 01 Apr 2013, 19:18

Sure. Improve away. :mrgreen:
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
User avatar
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

Postby Max mtg » 01 Apr 2013, 20:00

Hellfish wrote:Sure. Improve away. :mrgreen:
You haven't left much to improve. :)

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

Postby 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
User avatar
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

Postby Max mtg » 01 Apr 2013, 20:44

Hellfish wrote:Found a little bug, actually, but that should be it. :) Thanks.
With that fulfilled, decks can be checked to match commander's profile.

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 {2}

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

Postby 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?
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Color Identity by Hellfish

Postby 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
User avatar
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

Postby 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!
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

Postby friarsol » 01 Apr 2013, 23:01

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!
The EDH Damage implementation is incorrect in two ways:
- 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

Postby 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.
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

Postby 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
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

Postby 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!
Single class for single responsibility.
Max mtg
Programmer
 
Posts: 1997
Joined: 02 Jul 2011, 14:26
Has thanked: 173 times
Been thanked: 334 times


Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 20 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 20 users online :: 0 registered, 0 hidden and 20 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 20 guests

Login Form