Sealed Deck development / Draft ranking problem
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
8 posts
• Page 1 of 1
Sealed Deck development / Draft ranking problem
by RumbleBBU » 31 Aug 2012, 11:51
I have modified the Sealed Deck tournament mode to allow choosing up to two stater packs instead of boosters if they are available for the selected sets. While coding this, I came across an old bug (it seems). Basically, the problem is that certain cards cause the draft ranking code to crash and burn with a null pointer exception. Yes, this has happened before, bu with the ordinary 6 booster packs, it was not quite as likely that the computer got any of the problem cards. But with the increased cardpool of 2 starter packs + 4 boosters, the problem cards are much, much more frequent. Furthermore, 'ranking' basic lands (not normally present in booster packs but included in starter packs) seems to cause the null pointer exception as well.
For basic lands, this was easy enough to fix. I simply added this test to ReadDraftRankings::getRanking():
But I haven't figured out why certain other cards cause this as well. Ironclaw Orcs, for example, is a relatively common card when drawn from the Unlimited (2ED), and causes the problem. More specifically, the bad thing happens here:
In an example run, the Eclipse debugger reports the following values for the variables:
this = ReadDraftRankings (id=39)
cardName = "Ironclaw Orcs" (id=40)
edition = "2ED" (id=46)
rank = null
safeName = "Ironclaw Orcs" (id=40)
Any thoughts why this results in a null pointer exception would be helpful. (The 'null' for rank is, as I understand, irrelevant here.)
For basic lands, this was easy enough to fix. I simply added this test to ReadDraftRankings::getRanking():
- Code: Select all
if (cardName.equals("Island") || cardName.equals("Forest") || cardName.equals("Swamp")
|| cardName.equals("Plains") || cardName.equals("Mountain")) {
return null;
}
But I haven't figured out why certain other cards cause this as well. Ironclaw Orcs, for example, is a relatively common card when drawn from the Unlimited (2ED), and causes the problem. More specifically, the bad thing happens here:
- Code: Select all
rank = (double) draftRankings.get(edition).get(safeName) / (double) setSizes.get(edition);
In an example run, the Eclipse debugger reports the following values for the variables:
this = ReadDraftRankings (id=39)
cardName = "Ironclaw Orcs" (id=40)
edition = "2ED" (id=46)
rank = null
safeName = "Ironclaw Orcs" (id=40)
Any thoughts why this results in a null pointer exception would be helpful. (The 'null' for rank is, as I understand, irrelevant here.)
Re: Sealed Deck development / Draft ranking problem
by friarsol » 31 Aug 2012, 12:51
What are the calculated values of:
(double) setSizes.get(edition)
(double) draftRankings.get(edition).get(safeName)
(double) setSizes.get(edition)
(double) draftRankings.get(edition).get(safeName)
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: Sealed Deck development / Draft ranking problem
by RumbleBBU » 31 Aug 2012, 14:17
For Ironclaw Orcs:
(double) setSizes.get(edition) = 286.0
(double) draftRankings.get(edition).get(safeName) causes the null pointer exception (and, thus, cannot be evaluated)
Inspecting the draftRankings.get(edition) 286 (supposedly Unlimited/2ED) list, the Ironclaw Orcs don't seem to be included at all.
Theory: Null Pointer Exception occurs when the card to be looked up isn't on the list.
Proposed fix: Before trying to call draftRankings.get(edition).get(safeName) check that safeName can be found in draftRankings.get(edition). If not, return null from getRanking().
I'm trying it soon.
(double) setSizes.get(edition) = 286.0
(double) draftRankings.get(edition).get(safeName) causes the null pointer exception (and, thus, cannot be evaluated)
Inspecting the draftRankings.get(edition) 286 (supposedly Unlimited/2ED) list, the Ironclaw Orcs don't seem to be included at all.
Theory: Null Pointer Exception occurs when the card to be looked up isn't on the list.
Proposed fix: Before trying to call draftRankings.get(edition).get(safeName) check that safeName can be found in draftRankings.get(edition). If not, return null from getRanking().
I'm trying it soon.
Re: Sealed Deck development / Draft ranking problem
by RumbleBBU » 31 Aug 2012, 14:53
Yeah, that seems to do the trick.
I would suggest adding the following lines before line 210 in ReadDraftRankings.java:

I would suggest adding the following lines before line 210 in ReadDraftRankings.java:
- Code: Select all
if (draftRankings.get(edition).get(safeName) == null) {
return null;
}

Re: Sealed Deck development / Draft ranking problem
by Chris H. » 31 Aug 2012, 23:19
RumbleBBU wrote:Yeah, that seems to do the trick.
I would suggest adding the following lines before line 210 in ReadDraftRankings.java:I'll post my 'starter pack patch' later, I need to refine it a bit first.
- Code: Select all
if (draftRankings.get(edition).get(safeName) == null) {
return null;
}
You may want to consider the getting started wiki instructions for requesting commit privs. I can give you the commit priv if you want it.

-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Sealed Deck development / Draft ranking problem
by RumbleBBU » 03 Sep 2012, 06:47
Thanks for the commit privileges! They work, I've just used them to commit two patches.
1) An updated ReadDraftRankings.java that contains the above fixes.
2) An updated SealedDeckFormat.java that allows you to choose to include up to two starter packs instead of boosters, if available in the selected block.
Here's a brief description of how it works:
After you have selected a block, the game checks if any of the sets has starter packs available. If yes, you will be presented with one more list box where you can choose to include up to two starter packs instead of boosters in this sealed deck game. (And yes, the choice you make also applies to the AI player, of course.)
Notes:
- The code is built so that if a block contains more than one sets with starter packs available, it will prefer to offer two different starter packs rather than two starter packs from the same set. You can choose to use either or both.
- It also looks for starter packs in the same order as the sets are listed in the block definition (blocks.txt) file, so if there are more than two sets in the block that have starter packs, only the first two are offered. In such a case, you can get different starter pack choices by reordering the sets within the block definition line in blocks.txt.
(Addendum: I've updated the starter pack code so that it supports any number of sets and not just 6 or more. If you select two starter packs, with 2 starter packs and 4 boosters you could get more cards than you want in a limited game. But now the code also supports a sealed deck game with just 1 starter pack and, say, 2 or 3 boosters.)

1) An updated ReadDraftRankings.java that contains the above fixes.
2) An updated SealedDeckFormat.java that allows you to choose to include up to two starter packs instead of boosters, if available in the selected block.
Here's a brief description of how it works:
After you have selected a block, the game checks if any of the sets has starter packs available. If yes, you will be presented with one more list box where you can choose to include up to two starter packs instead of boosters in this sealed deck game. (And yes, the choice you make also applies to the AI player, of course.)
Notes:
- The code is built so that if a block contains more than one sets with starter packs available, it will prefer to offer two different starter packs rather than two starter packs from the same set. You can choose to use either or both.
- It also looks for starter packs in the same order as the sets are listed in the block definition (blocks.txt) file, so if there are more than two sets in the block that have starter packs, only the first two are offered. In such a case, you can get different starter pack choices by reordering the sets within the block definition line in blocks.txt.
(Addendum: I've updated the starter pack code so that it supports any number of sets and not just 6 or more. If you select two starter packs, with 2 starter packs and 4 boosters you could get more cards than you want in a limited game. But now the code also supports a sealed deck game with just 1 starter pack and, say, 2 or 3 boosters.)
Re: Sealed Deck development / Draft ranking problem
by mcrawford620 » 04 Sep 2012, 19:50
Yeah, for some reason, Ironclaw Orcs aren't included here: http://draft.bestiaire.org/ranking.php which is where I got the rankings from. I did notice that the first time around, and I actually thought I was handling the null pointers correctly. I guess not. Thanks for fixing it.RumbleBBU wrote:Inspecting the draftRankings.get(edition) 286 (supposedly Unlimited/2ED) list, the Ironclaw Orcs don't seem to be included at all.
Theory: Null Pointer Exception occurs when the card to be looked up isn't on the list.
You could also edit the rankings file and just stick Ironclaw Orcs in there somewhere; I have no idea where you would rank them in the Unlimited Set. (Your fix was still needed, obviously, I just meant if you wanted Ironclaw Orcs to get drafted, you could put it in the rankings file.)
- mcrawford620
- Posts: 112
- Joined: 25 Jun 2012, 16:59
- Has thanked: 55 times
- Been thanked: 25 times
Re: Sealed Deck development / Draft ranking problem
by mcrawford620 » 04 Sep 2012, 19:57
Ah, I see, I used to handle those cards correctly, and then I put in the code to adjust rankings for the size of the set. And introduced the bug. Phooey. 

- mcrawford620
- Posts: 112
- Joined: 25 Jun 2012, 16:59
- Has thanked: 55 times
- Been thanked: 25 times
8 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 37 guests