I have implemented some sort of the strategy pattern using an abstract class and an interface:
public interface ICombination
{
void Check(int[] hand, UsersProperties user);
void UpdateHand(UsersProperties user, int combinationType, int powerType);
}
public abstract class ICombinationAnalyzer : CardVariables, ICombination
{
public abstract void Check(int[] hand, UsersProperties user);
public void UpdateHand(UsersProperties user, int combinationType, int powerType)
{
user.Type = combinationType;
user.Power = powerType + user.Type*100;
MainPoker.Win.Add(new Hand {Power = user.Power, Current = user.Type});
}
protected ICombinationAnalyzer(UsersProperties user, IReadOnlyList<int> hand) : base(user, hand)
{
}
}
CardVariables
is just a class where I keep some variables used in the calculates down below. I don't think there's point in showing it here.
There are a few derived methods I'm not going to show entirely here because they are quite similar to one another.
public class RoyalFlush : ICombinationAnalyzer
{
public RoyalFlush(UsersProperties user, IReadOnlyList<int> hand) : base(user, hand)
{
}
public override void Check(int[] hand, UsersProperties user)
{
const int localType = (int) Hand.Combinations.RoyalFlush;
foreach (
var t in
CombinedArrays.Where(t => t.Length >= 5)
.Where(
t =>
t[0] == (int) Cards.CardTypes.Ace && t.Contains((int) Cards.CardTypes.Ten) &&
t.Contains((int) Cards.CardTypes.Jack) && t.Contains((int) Cards.CardTypes.Queen) &&
t.Contains((int) Cards.CardTypes.King)))
{
UpdateHand(user, localType, t.Max()/4);
}
}
}
And here's one more:
public class Straight : ICombinationAnalyzer
{
public Straight(UsersProperties user, IReadOnlyList<int> hand) : base(user, hand)
{
}
public override void Check(int[] hand, UsersProperties user)
{
const int localType = (int) Hand.Combinations.Straight;
int[] op = Straight.Select(o => o/4).Distinct().ToArray();
for (int j = 0; j < op.Length - 4; j++)
{
if (op[j] + 1 == op[j + 1] && op[j] + 2 == op[j + 2] && op[j] + 3 == op[j + 3] && op[j] + 4 == op[j + 4])
{
UpdateHand(user, localType, op.Max() - 4 == op[j] ? op.Max() : op[j + 4]);
}
if (op[j] != (int) Cards.CardTypes.Ace || op[j + 1] != (int) Cards.CardTypes.Ten ||
op[j + 2] != (int) Cards.CardTypes.Jack || op[j + 3] != (int) Cards.CardTypes.Queen ||
op[j + 4] != (int) Cards.CardTypes.King) continue;
UpdateHand(user, localType, 13);
}
}
}
Now the problem is where I'm actually implementing the strategy pattern:
List<SwitchCombination> listCombinations = new List<SwitchCombination>();
var switchCombination = new SwitchCombination( new HighCard(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new PairFromTable(user,_reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new PairInHand(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new PairHandTable(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new TwoPairFromTable(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new TwoPairHandPairTablePair(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new TwoPairHandTable(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new TwoPairTwoDifferent(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new ThreeOfAKind(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.Straight(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.Flush(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.FullHouse(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.FourOfAKind(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.StraightFlush(user, _reserve));
listCombinations.Add(switchCombination);
switchCombination = new SwitchCombination(new Combinations.RoyalFlush(user, _reserve));
listCombinations.Add(switchCombination);
foreach (var listCombination in listCombinations)
{
listCombination.CheckCombination(user, _reserve);
}
It's my first time ever doing this pattern and I'm not sure if it can be made any better but i know that if I'm writing something similar a couple times there's probably a better way of doing it. I created list of those Combinations so i can iterate through them this way I avoid typing
switchCombinations.CheckCombination(user, _reserve);
all the time.
However, I can't seem to find a way to reduce the overall size of that. As I said earlier, it's my first time implementing this pattern and I'm not sure if it's even effective or if that's the right way to go.
EDIT : Added the SwitchCombination
class :
internal class SwitchCombination
{
private readonly ICombinationAnalyzer _combinationAnalyzer;
public SwitchCombination(ICombinationAnalyzer combination)
{
_combinationAnalyzer = combination;
}
public void CheckCombination(UsersProperties inputUser, int[] inputHand)
{
_combinationAnalyzer.Check(inputHand, inputUser);
}
}