Drafting
by mtgrares
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Re: Drafting
by delirimouse » 19 Dec 2011, 05:35
It is my understanding that no one has taught the AI to decide which non-basic lands are good for the deck. Thus it might throw a Badlands into its UW deck not realizing this is a bad idea.
(But this could easily be incorrect, I in no way program for Forge)
(But this could easily be incorrect, I in no way program for Forge)
- delirimouse
- Posts: 39
- Joined: 30 Aug 2011, 23:33
- Has thanked: 0 time
- Been thanked: 3 times
Re: Drafting
by Sloth » 19 Dec 2011, 07:21
You are correct delirimouse. And I've already answered this question, juzamjedi:delirimouse wrote:It is my understanding that no one has taught the AI to decide which non-basic lands are good for the deck. Thus it might throw a Badlands into its UW deck not realizing this is a bad idea.
(But this could easily be incorrect, I in no way program for Forge)
Sloth wrote:Unfortunately the AI will not recognize lands in it's colors, which is not unimportand since in my testing the AI did include some drafted (late picked) lands in the decks and most of them were pretty useless (off color duals and manlands). So if you want to make your cube really is AI friendly, color aligned lands would have to go.juzamjedi wrote:Slightly less important but worth asking: does AI draft lands in its colors now too?![]()
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Drafting
by juzamjedi » 19 Dec 2011, 23:08
I am VERY hesitant to remove dual lands and fetchlands. They do so much to make your mana better and allow you to play greedy color cards (2UUU for Future Sight in the same deck with 2WW for Wrath of God, etc.). Mana (and the color wheel) is THE defining feature of MTG and mana fixing is so important to casting your spells.
I could see the point of taking out some of the color-aligned tap-lands. They're powerful and will help your mana a lot, but coming into play tapped is bad and AI has a tendency to animate manlands more often than it should.
I think at this point we should try to improve AI to draft mana-fixing lands. Is mana coded in a special way like
etc so that AI can pick lands that produce the colors they are drafting? Also have the AI pick lands that have a land type in its rules text that matches what colors are drafted {Plains} etc
Edit: humorously, I just found out that when you put {} around W you get
I could see the point of taking out some of the color-aligned tap-lands. They're powerful and will help your mana a lot, but coming into play tapped is bad and AI has a tendency to animate manlands more often than it should.
I think at this point we should try to improve AI to draft mana-fixing lands. Is mana coded in a special way like


Edit: humorously, I just found out that when you put {} around W you get

Re: Drafting
by Rob Cashwalker » 20 Dec 2011, 06:25
Here's the beginning of a revised draft rating alorithm:
- Code: Select all
public class LiveDraftRatings {
private Map<String,CardRules> myDraftedCards = new HashMap<String, CardRules>();
private Map<String, Integer> myDraftedRatings = new HashMap<String, Integer>();
private int ColorCounts[] = {0,0,0,0,0,0};
public void addCard (CardRules crCard, String fmtID) {
String cardName = crCard.getName() + "|" + fmtID;
int cardRating = 50; // base rating
boolean cardNotPresent = true;
if (myDraftedRatings.size() > 0) {
if (myDraftedRatings.containsKey(cardName)) {
cardRating = myDraftedRatings.get(cardName);
cardRating += 8; // bonus this card when drafted in multiples
cardNotPresent = false;
}
boolean noSharedColor = true;
boolean noSharedSubType = true;
for (String cn : myDraftedCards.keySet()) {
CardRules cr = myDraftedCards.get(cn);
CardColor cc = cr.getColor();
if (crCard.getColor().sharesColorWith(cc)) {
myDraftedRatings.put(cn, myDraftedRatings.get(cn) + 1); // bonus other cards that share a color
noSharedColor = false;
}
CardType ct = cr.getType();
if (crCard.getType().sharesSubTypeWith(ct)) {
myDraftedRatings.put(cn, myDraftedRatings.get(cn) + 1); // bonus other cards that share a sub type
cardRating += 2; // bonus this card when drafted with like sub types (detects themes)
}
}
if (noSharedColor && !crCard.getColor().isColorless()) {
cardRating -= 2; // deduct for off-color picks
}
if (noSharedSubType && !crCard.getType().getSubTypes().isEmpty()) {
cardRating -= 2; // deduct for not sharing sub types (a theme indicator)
}
}
// count colors and bonus this card when drafted with like colors
if (crCard.getColor().isWhite()) {
ColorCounts[0] += 1;
if (ColorCounts[0] > 4)
cardRating += 1;
if (ColorCounts[0] > 8)
cardRating += 2;
if (ColorCounts[0] > 16)
cardRating += 4;
}
if (crCard.getColor().isBlue()) {
ColorCounts[1] += 1;
if (ColorCounts[1] > 4)
cardRating += 1;
if (ColorCounts[1] > 8)
cardRating += 2;
if (ColorCounts[1] > 16)
cardRating += 4;
}
if (crCard.getColor().isBlack()) {
ColorCounts[2] += 1;
if (ColorCounts[2] > 4)
cardRating += 1;
if (ColorCounts[2] > 8)
cardRating += 2;
if (ColorCounts[2] > 16)
cardRating += 4;
}
if (crCard.getColor().isRed()) {
ColorCounts[3] += 1;
if (ColorCounts[3] > 4)
cardRating += 1;
if (ColorCounts[3] > 8)
cardRating += 2;
if (ColorCounts[3] > 16)
cardRating += 4;
}
if (crCard.getColor().isGreen()) {
ColorCounts[4] += 1;
if (ColorCounts[4] > 4)
cardRating += 1;
if (ColorCounts[4] > 8)
cardRating += 2;
if (ColorCounts[4] > 16)
cardRating += 4;
}
if (crCard.getColor().isColorless()) {
ColorCounts[5] += 1;
if (ColorCounts[5] > 4)
cardRating += 1;
if (ColorCounts[5] > 8)
cardRating += 2;
if (ColorCounts[5] > 16)
cardRating += 4;
}
if (myDraftedCards.size() > 10)
cardRating += 2; // bonus after a draft strategy has been developed
if (myDraftedCards.size() > 20) // more bonus for later picks
cardRating += 2;
if (cardNotPresent)
myDraftedCards.put(cardName, crCard);
myDraftedRatings.put(cardName, cardRating);
}
}
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Drafting
by Sloth » 20 Dec 2011, 12:18
What's the goal of myDraftedRatings? What do you want to use it for?Rob Cashwalker wrote:Here's the beginning of a revised draft rating alorithm:What other kinds of metrics do you think I could consider?
- Code: Select all
public class LiveDraftRatings {
private Map<String,CardRules> myDraftedCards = new HashMap<String, CardRules>();
private Map<String, Integer> myDraftedRatings = new HashMap<String, Integer>();
private int ColorCounts[] = {0,0,0,0,0,0};
public void addCard (CardRules crCard, String fmtID) {
String cardName = crCard.getName() + "|" + fmtID;
int cardRating = 50; // base rating
boolean cardNotPresent = true;
if (myDraftedRatings.size() > 0) {
if (myDraftedRatings.containsKey(cardName)) {
cardRating = myDraftedRatings.get(cardName);
cardRating += 8; // bonus this card when drafted in multiples
cardNotPresent = false;
}
boolean noSharedColor = true;
boolean noSharedSubType = true;
for (String cn : myDraftedCards.keySet()) {
CardRules cr = myDraftedCards.get(cn);
CardColor cc = cr.getColor();
if (crCard.getColor().sharesColorWith(cc)) {
myDraftedRatings.put(cn, myDraftedRatings.get(cn) + 1); // bonus other cards that share a color
noSharedColor = false;
}
CardType ct = cr.getType();
if (crCard.getType().sharesSubTypeWith(ct)) {
myDraftedRatings.put(cn, myDraftedRatings.get(cn) + 1); // bonus other cards that share a sub type
cardRating += 2; // bonus this card when drafted with like sub types (detects themes)
}
}
if (noSharedColor && !crCard.getColor().isColorless()) {
cardRating -= 2; // deduct for off-color picks
}
if (noSharedSubType && !crCard.getType().getSubTypes().isEmpty()) {
cardRating -= 2; // deduct for not sharing sub types (a theme indicator)
}
}
// count colors and bonus this card when drafted with like colors
if (crCard.getColor().isWhite()) {
ColorCounts[0] += 1;
if (ColorCounts[0] > 4)
cardRating += 1;
if (ColorCounts[0] > 8)
cardRating += 2;
if (ColorCounts[0] > 16)
cardRating += 4;
}
if (crCard.getColor().isBlue()) {
ColorCounts[1] += 1;
if (ColorCounts[1] > 4)
cardRating += 1;
if (ColorCounts[1] > 8)
cardRating += 2;
if (ColorCounts[1] > 16)
cardRating += 4;
}
if (crCard.getColor().isBlack()) {
ColorCounts[2] += 1;
if (ColorCounts[2] > 4)
cardRating += 1;
if (ColorCounts[2] > 8)
cardRating += 2;
if (ColorCounts[2] > 16)
cardRating += 4;
}
if (crCard.getColor().isRed()) {
ColorCounts[3] += 1;
if (ColorCounts[3] > 4)
cardRating += 1;
if (ColorCounts[3] > 8)
cardRating += 2;
if (ColorCounts[3] > 16)
cardRating += 4;
}
if (crCard.getColor().isGreen()) {
ColorCounts[4] += 1;
if (ColorCounts[4] > 4)
cardRating += 1;
if (ColorCounts[4] > 8)
cardRating += 2;
if (ColorCounts[4] > 16)
cardRating += 4;
}
if (crCard.getColor().isColorless()) {
ColorCounts[5] += 1;
if (ColorCounts[5] > 4)
cardRating += 1;
if (ColorCounts[5] > 8)
cardRating += 2;
if (ColorCounts[5] > 16)
cardRating += 4;
}
if (myDraftedCards.size() > 10)
cardRating += 2; // bonus after a draft strategy has been developed
if (myDraftedCards.size() > 20) // more bonus for later picks
cardRating += 2;
if (cardNotPresent)
myDraftedCards.put(cardName, crCard);
myDraftedRatings.put(cardName, cardRating);
}
}
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Drafting
by Rob Cashwalker » 20 Dec 2011, 15:13
OK, I'll try to do some 'splaining....
This class, LiveDraftRatings will only exist during the time the player is drafting. Each card picked will be sent through the addCard method for analysis. Short of doing some funky wrapper-class, I use the two hash maps to store the two main things I need to know about each time a card comes through.
myDraftedCards simply associates the cardName (which may also include a set code or a cube name) with a reference to the card object which lets me examine things like color and type.
myDraftedRatings associates the cardName (same one) with a temporary rating.
As cards get picked, cards start at a default rating. (may swap the 50 for a lookup in the CardRatingsData class (mental note, rename that class)) Based on some ideas we had about rating the cards against the other cards picked, the temporary ratings have the opportunity to swing higher or lower, based on the criteria I commented on. I need more reasons to lower a rating....
I added a method to CardColor, sharesColorWith. It basically does this:
If the card wasn't already picked, add it to the myDraftedCards. After examining all aspects of a picked card, its new temporary rating is put into myDraftedRatings.
When the draft is done, another method will be used to massage the ratings (enforce min/max 0/100) and integrate them into the main CardRatingsData class. (which will get uploaded to cardforge.org on a periodic basis, not during draft)
Right now, it's for analyzing the human's picks. HOWEVER, the essence of this algorithm can be used in the AI side. For each base rating of the cards presented in a pack, this algorithm could adjust the perception of the ratings based on what it has already picked. I will probably split the rating algorithm into its own method.
This class, LiveDraftRatings will only exist during the time the player is drafting. Each card picked will be sent through the addCard method for analysis. Short of doing some funky wrapper-class, I use the two hash maps to store the two main things I need to know about each time a card comes through.
myDraftedCards simply associates the cardName (which may also include a set code or a cube name) with a reference to the card object which lets me examine things like color and type.
myDraftedRatings associates the cardName (same one) with a temporary rating.
As cards get picked, cards start at a default rating. (may swap the 50 for a lookup in the CardRatingsData class (mental note, rename that class)) Based on some ideas we had about rating the cards against the other cards picked, the temporary ratings have the opportunity to swing higher or lower, based on the criteria I commented on. I need more reasons to lower a rating....
I added a method to CardColor, sharesColorWith. It basically does this:
- Code: Select all
boolean sharesColorWith(CardColor ccOther) {
if (this.isWhite && ccOther.isWhite)
return true;
if (this.isBlue && ccOther.isBlue)
return true;
...
return false;
}
If the card wasn't already picked, add it to the myDraftedCards. After examining all aspects of a picked card, its new temporary rating is put into myDraftedRatings.
When the draft is done, another method will be used to massage the ratings (enforce min/max 0/100) and integrate them into the main CardRatingsData class. (which will get uploaded to cardforge.org on a periodic basis, not during draft)
Right now, it's for analyzing the human's picks. HOWEVER, the essence of this algorithm can be used in the AI side. For each base rating of the cards presented in a pack, this algorithm could adjust the perception of the ratings based on what it has already picked. I will probably split the rating algorithm into its own method.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Drafting
by friarsol » 20 Dec 2011, 15:31
In this drafting AI, where's the best place to consider the Color Identity (Color of Mana in Activated Abilities, or Produced by Mana Abilities)? I thought I had seen a color identity function floating around at some point, and it would be the easiest way to allow Moxen and On-Color Lands to not be removed from Draft Cubes.
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Drafting
by Rob Cashwalker » 20 Dec 2011, 15:39
Yeah, that's something I'd like to consider.
I recall in the drafting AI, I had some means of identifying in-color lands by iterating their ManaAbilities or something. It was cumbersome. If that method was available for the CardRules object, that would be very good. It also would identify in-color artifacts.
I also would try to match keywords... bonus when drafting multiple flyers...
I recall in the drafting AI, I had some means of identifying in-color lands by iterating their ManaAbilities or something. It was cumbersome. If that method was available for the CardRules object, that would be very good. It also would identify in-color artifacts.
I also would try to match keywords... bonus when drafting multiple flyers...
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Drafting
by Sloth » 20 Dec 2011, 16:36
I don't understand the point in making most of these calculatings for the rating data base. For example: Why do all picked cards get a +2 ranking after the 10th pick?Rob Cashwalker wrote:When the draft is done, another method will be used to massage the ratings (enforce min/max 0/100) and integrate them into the main CardRatingsData class. (which will get uploaded to cardforge.org on a periodic basis, not during draft)
This is the place, where most of the function makes sense.Rob Cashwalker wrote:Right now, it's for analyzing the human's picks. HOWEVER, the essence of this algorithm can be used in the AI side. For each base rating of the cards presented in a pack, this algorithm could adjust the perception of the ratings based on what it has already picked. I will probably split the rating algorithm into its own method.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Drafting
by Rob Cashwalker » 20 Dec 2011, 16:58
I figure by that that time, the cards being picked are probably important cards. Mind you, if it was a default last-pick-of-a-pack, then the off color and off-type deductions would likely negate the +2 for being more than 10picks. BTW, it's not exactly the 10th pick.. if you picked multiples of a card during the first 10 picks, the size of the temporary ratings list isn't 10, it may be more like 8 or 9....I don't understand the point in making most of these calculatings for the rating data base. For example: Why do all picked cards get a +2 ranking after the 10th pick?
The question becomes, how should we score a card that the human picks early and how should that score be any different if it's picked again later, or if it's picked because it's on-theme with the other picks. The old way gave the highest score to the early picks and lowest score to the last pick. The method I propose now is to allow the later picks to influence the rating of earlier picks. Cards that work together get better ratings during this draft than the cards that don't.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Drafting
by Sloth » 20 Dec 2011, 19:03
The first pick in the second booster is important, because it has to compete with 14 other cards, the last pick of booster one holds no information at all.Rob Cashwalker wrote:I figure by that that time, the cards being picked are probably important cards. Mind you, if it was a default last-pick-of-a-pack, then the off color and off-type deductions would likely negate the +2 for being more than 10picks. BTW, it's not exactly the 10th pick.. if you picked multiples of a card during the first 10 picks, the size of the temporary ratings list isn't 10, it may be more like 8 or 9....
I don't know if it has been discussed before, but a simple system would be to give each card that was not picked -1 to its score and each card picked +X where X is the number of other cards in the pack.Rob Cashwalker wrote:The question becomes, how should we score a card that the human picks early and how should that score be any different if it's picked again later, ...
If the product is a draft rating for each card, the whole working together information is lost. It should actually be the reverse: if the human late-picks the mediocre elf card A into a pool of elf cards, the rating of card A should be lower than normal.Rob Cashwalker wrote:Cards that work together get better ratings during this draft than the cards that don't.
-
Sloth - Programmer
- Posts: 3498
- Joined: 23 Jun 2009, 19:40
- Has thanked: 125 times
- Been thanked: 507 times
Re: Drafting
by delirimouse » 20 Dec 2011, 22:30
There are a lot of linear keywords, i.e. keywords that work better if you have a lot of them (for example, you listed flying, which definitely has that). Would you like me to make a list of all the keywords I think are linear, perhaps with a numerical indication of how linear they are, so that you can encourage clumping of that sort of thing?
Edited to add:
Okay I went and made something like that for the past few blocks and evergreen keywords. Below I draw attention to the relevant linear mechanics and creature types that I think are relevant. I tried to rate the importance of the linearity on a scale from 1 to 5.
Even in the most extreme case (Infect), these ratings should not completely overshadow the base pick rating. Something like this might work:
Scale the inherent rating of cards from draft pick data to a 0 to 10 scale so that the distribution is uniform. After filtering based on color, the perceived rating of a card to a bot should then be something like 2^base_rating + (Modifier for synergy), where the modifier can be positive or negative of course.
This way if a card is truly exceptional, it will be picked regardless of synergy, e.g., no matter how many fliers I have I should always pick Batterskull.
Evergreen:
First Strike - 2
Flying - 2
Reach - value inversely proportionate to the number of fliers you have
Innistrad:
Type: Zombie -- 2
Type: Spirit -- 1
Type: Human -- 3 (also likes equipment)
Type: Vampire -- 1
Type: Werewolf -- 1
Scars of Mirrodin:
Infect - 5 - also increases in value with equipment
Equipment - increases in value with infect
Metalcraft - value proportional to the number of artifacts you have
Zendikar:
Type: Ally - 5
Shards of Alara:
Exalted - 3
----------------------------------
I would discourage rewarding clumping creature types except those specifically encouraged within the blocks, as it is worthless 99% of the time. Recent notable exceptions are listed above.
Edited to add:
Okay I went and made something like that for the past few blocks and evergreen keywords. Below I draw attention to the relevant linear mechanics and creature types that I think are relevant. I tried to rate the importance of the linearity on a scale from 1 to 5.
Even in the most extreme case (Infect), these ratings should not completely overshadow the base pick rating. Something like this might work:
Scale the inherent rating of cards from draft pick data to a 0 to 10 scale so that the distribution is uniform. After filtering based on color, the perceived rating of a card to a bot should then be something like 2^base_rating + (Modifier for synergy), where the modifier can be positive or negative of course.
This way if a card is truly exceptional, it will be picked regardless of synergy, e.g., no matter how many fliers I have I should always pick Batterskull.
Evergreen:
First Strike - 2
Flying - 2
Reach - value inversely proportionate to the number of fliers you have
Innistrad:
Type: Zombie -- 2
Type: Spirit -- 1
Type: Human -- 3 (also likes equipment)
Type: Vampire -- 1
Type: Werewolf -- 1
Scars of Mirrodin:
Infect - 5 - also increases in value with equipment
Equipment - increases in value with infect
Metalcraft - value proportional to the number of artifacts you have
Zendikar:
Type: Ally - 5
Shards of Alara:
Exalted - 3
----------------------------------
I would discourage rewarding clumping creature types except those specifically encouraged within the blocks, as it is worthless 99% of the time. Recent notable exceptions are listed above.
- delirimouse
- Posts: 39
- Joined: 30 Aug 2011, 23:33
- Has thanked: 0 time
- Been thanked: 3 times
Re: Drafting
by juzamjedi » 23 Dec 2011, 21:36
Yes - some cards are so good you take them no matter what your deck already has in it. Maybe think of this as the Base Value for the draft pick.
Supporting linears is good, but I think we could do it all more systematically by just using covariance of cards already selected during a draft. Something like:
Draft Value = Base Value + Covariance(Card1) + Covariance(Card2)...
Covariance could be estimated by human draft picks, after the end of the draft (and updated each draft). Then this is used for future AI draft picks.
An example that is obvious if you draft often, but would not be obvious to computer: there is a very strong, positive correlation between Wild Nacatl and Taiga.
Supporting linears is good, but I think we could do it all more systematically by just using covariance of cards already selected during a draft. Something like:
Draft Value = Base Value + Covariance(Card1) + Covariance(Card2)...
Covariance could be estimated by human draft picks, after the end of the draft (and updated each draft). Then this is used for future AI draft picks.
An example that is obvious if you draft often, but would not be obvious to computer: there is a very strong, positive correlation between Wild Nacatl and Taiga.
Re: Drafting
by delirimouse » 23 Dec 2011, 23:21
Computing the covariance would indeed be a very smart way to get the computer to learn to draft smart decks. I don't, however, think the draft data collector actually takes this information (Rob will tell me if I am wrong).
I think it is important to just get some system that uses human pick data in place so that we stop getting last pick Garruks, and then as people play a bunch they can observe things the AI does well and poorly and then the various knobs can be tuned accordingly.
Also, is it possible to see the current ratings of cards based on data submission so that it can be verified that is working correctly? I recall something like this was posted before for the old algorithm, but there was a problem with the algorithm that made it produce less useful numbers.
I think it is important to just get some system that uses human pick data in place so that we stop getting last pick Garruks, and then as people play a bunch they can observe things the AI does well and poorly and then the various knobs can be tuned accordingly.
Also, is it possible to see the current ratings of cards based on data submission so that it can be verified that is working correctly? I recall something like this was posted before for the old algorithm, but there was a problem with the algorithm that made it produce less useful numbers.
- delirimouse
- Posts: 39
- Joined: 30 Aug 2011, 23:33
- Has thanked: 0 time
- Been thanked: 3 times
Re: Drafting
by Rob Cashwalker » 26 Dec 2011, 02:38
No matter what the rating algorithm will be, the MySQL database portion is ready, with an average of 8 data points per card. There is a page for viewing the data (just dumps the averaged data).
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Who is online
Users browsing this forum: No registered users and 79 guests