Hello everyone, I have having troubles with a Coaca-based program.
I am working on a custom shuffling program for the game Dominion, and while there are many out there already, the thing that I cannot seem to do with any of the ones I tried was limit the number of sets chosen (e.g. tell program I want to use seven sets, only choose 4 of the seven) and things worked out pretty welll up through Guilds, but Adventures is giving me some grieve.
According to the rules, it is stated that Events are not counted as part of the Kingdoms in supply and that if an Event shows up, the card drawing should continue until ten kingdoms are chosen, and it is recommended to have no more than two event cards.
However, right now, there are always 12 or 13, depending on if the Young Witch card is present or not, since the Bane card is usually the eleventh card chosen, when it should rotate between 10 cards, 11 cards, 12 cards, or 13, if Young Witch is present.
How do I fix this problem.
Right now, the code to determine number of rows, since I am using NSTableViews, looks like this.
Yes, I know that with the code currently there will always put in two Events, but I have tried quite a few ways, like nested loops changing between while loop inside a for loop and vice versa to increment a counter for the rows and add number of events to number in supply, just check number of events, and even controlling how many events are placed into the array that contains the cards, after trying to remove events from array if there are more than two All of which have failed.
Also, I have checked via NSLog about whether the cards were indeed event cards or not and things were presented how they should, but if you need to see how the cards are generated and such, here are the following files:
Card (this is used to create card objects)
Cards (this is used to generate an array of Card objects through JSON input)
Ok, going through, I think I figured things out, since I have not yet pushed to github, I will put what I did here.
in the Cards class, I added an array just to hold the event cards, and added something similiar to this in each variation of the method that creates the supply of cards:
if ([card event])
{
[events addObject:card];
}
else
{
[cards addObject:card]; /
}
that slash on line 8 is part of a comment.
in the Rules class, which I did not link to before, I added in the following method:
- (int)events
{
BOOL events = false;
int randValue1 = arc4random_uniform(2);
if (randValue1 == 1)
{
events = true;
}
if (events == true) {
int randValue2 = arc4random_uniform(2)+1;
return randValue2;
}
return 0;
}
This makes sure that anywhere from 0 to two events can be present.
In the Game class, I split up the supply method into two variations, which the root view controller has a conditional statement to call, which look like the following:
- (int) supply:(NSMutableArray*)c bane:(Card *)b
{
/
if (b != nil) {
game = [[NSMutableArray alloc] initWithCapacity:11];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
[game addObject:b];
}
else
{
game = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
}
return (int)game.count;
}
The above deals with only if a Bane card is present.
- (int)supply:(NSMutableArray *)c bane:(Card *)b events:(NSMutableArray *)events
{
rules = [[Rules alloc] init];
int e = [rules events];
NSMutableArray* chosen = [[NSMutableArray alloc] init];
if (e == 2 && b != nil)
{
game = [[NSMutableArray alloc] initWithCapacity:13];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
for (int i = 0; i < 2; i++)
{
int randValue = arc4random_uniform((u_int32_t)[events count]);
if ([chosen containsObject:events[randValue]])
{
}
else
{
[chosen addObject:events[randValue]];
}
}
for (int i = 0; i < [chosen count]; i++)
{
[game addObject:chosen[i]];
}
[game addObject:b];
}
else if (e == 1 && b != nil)
{
game = [[NSMutableArray alloc] initWithCapacity:12];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
int randValue = arc4random_uniform((u_int32_t)[events count]);
[chosen addObject:events[randValue]];
[game addObject:chosen[0]];
[game addObject:b];
}
else if (e == 2 && b == nil)
{
game = [[NSMutableArray alloc] initWithCapacity:12];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
for (int i = 0; i < 2; i++)
{
int randValue = arc4random_uniform((u_int32_t)[events count]);
if ([chosen containsObject:events[randValue]])
{
}
else
{
[chosen addObject:events[randValue]];
}
}
for (int i = 0; i < [chosen count]; i++)
{
[game addObject:chosen[i]];
}
}
else if (e == 1 && b == nil)
{
game = [[NSMutableArray alloc] initWithCapacity:11];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
int randValue = arc4random_uniform((u_int32_t)[events count]);
[chosen addObject:events[randValue]];
[game addObject:chosen[0]];
}
else
{
game = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0; i < 10; i++)
{
[game addObject:c[i]];
}
}
return (int)game.count;
}
The above method is used if event cards can be present, in the event that event cards may be present.
In the root view controller, I made the array that holds user selection available to all methods in the root view controller's class and the method to determine method rows now looks like this:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
bane = [rules bane:cards]; /
if ([chosen containsObject:@"Adventures"])
{
Cards* other = [[Cards alloc] initWithSupply:[json supply]]; /
NSMutableArray* events = [other events];
return [supply supply:cards bane:bane events:events];
}
return [supply supply:cards bane:bane];
}
I had to create a cards object so that I could retrieve events, because the cards variable makes a call to the shuffle class, which does not return event cards.
So far, I have not seen all 13 cards show up, but it at least does not always display 12 or 13 cards.