
[ad_1]
Delegates can be utilized to realize what you are doing however the code right here will almost definitely not ‘simply work’ with what you have already got. In addition, I’ve needed to make a number of assumptions about how issues work / what you’ve described (see assumptions on the finish).
Given your description, I think about the interface your playing cards use to look one thing like this:
interface ICard {
CardKind cardType {get;}
int quantity {get;} // Or whichever quantity kind is suitable
void DoCardAction();
}
You mentioned that participant results may utterly change the motion of your playing cards. A delegate property as a substitute of an interface methodology for the cardboard’s motion would help this alternative.
interface ICard {
CardKind cardType {get;}
int quantity {get;} // Or whichever quantity kind is suitable
Action doCardAction {get; set;} // The delegate
}
Having a card with none motion might be not what you need. To keep away from that, the implementing class would then assign the ‘regular’ motion to this property on initialisation / building, e.g.:
class CardImplementation : ICard {
// and so on...
void CardAction() {/* and so on...*/}
public CardImplementation() {
doCardAction = CardAction;
//and so on...
}
}
With this new delegate-centred interface, modifying the cardboard’s base impact could be changing it with a delegate to a distinct methodology. We also can incorporate one other delegate for modifying the ‘quantity’ values in order that completely different gamers can impact completely different modifications with out the necessity for subclassing.
class PlayerInfluence {
CardKind modifies;
Func<int, int> modifier; // Or Func<X, X> the place X is the information kind of your card's 'quantity'
Action alternativeAction;
public bool CanModify(ICard goal) {
return modifies == goal.cardType;
}
public void ModifyCard(ICard goal) {
// Replace the cardboard's motion if a alternative was provided
goal.doCardAction = alternativeAction ?? goal.doCardAction;
// Augment the goal's quantity property utilizing a perform, if provided
goal.quantity = modifier?.Invoke(goal.quantity) ?? goal.quantity;
}
}
Delegate properties can maintain lambdas, so making a participant with a selected impact is so simple as defining that impact on participant creation. The instance under creates an affect that can modify Peek playing cards by doubling the quantity, however leaving the motion unchanged.
PlayerInfluence peekingCardDoublingInfluence = new PlayerInfluence(CardKind.Peek, (x) => x * 2, null);
To deliver this collectively, the routine for resolving an motion from the stack would look one thing like:
currentEffect = effectStack.Pop(); // Get the subsequent impact
if(presentPlayer.affect.CanModifyCard(currentEffect)) {
presentPlayer.affect.Modify(currentEffect); // Modifiy the impact, if attainable
}
currentEffect.doCardAction(); // Run the impact
(a number of the) Assumptions I’m making:
- your card kind is represented by an enumeration (known as
CardKind
) - you’ve carried out a constructor for
Player
asPlayer(CardKind, Func<int, int>, Action)
- The routine which controls stack decision has entry to the present participant
- Card results are cloned on to the stack, quite than pointing to the identical occasion within the deck, if you’d like the modifications to be one-time-only
- A card’s default motion is an occasion methodology sure to
ICard.doCardAction
when the cardboard is constructed / initialised. - If changing a card’s motion, then
ICard.quantity
just isn’t related to the brand new motion i.e. they’re mutually-exclusive modifications
[ad_2]