I have an interface with two functions. This interface is being inherited by an abstract class which implements just one of those functions. The other one is left to be implemented by the derived classes of the abstract class.
public interface ICombination
{
bool Check(IReadOnlyList<int> hand,UsersProperties user);
void UpdateHand(UsersProperties user, int combinationType, int powerType);
}
public abstract class ICombinationAnalyzer : ICombination
{
public abstract bool Check(IReadOnlyList<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 });
}
}
Now the problem is that the derived classes implement a lot of variables and those variables are being instantiated the same way each time:
public class StraightFlush : ICombinationAnalyzer
{
public override bool Check(IReadOnlyList<int> hand, UsersProperties user)
{
int _kicker,
_rightCard,
_sumOfHands,
_leftCard;
int[] straight1 = new int[5];
int[] straight = new int[7];
int k = (int)MainPoker.TableCards.FirstCard;
straight[0] = hand[user.RightCard];
straight[1] = hand[user.LeftCard];
for (int j = 2; j < straight.Length; j++)
{
straight[j] = hand[k];
k++;
}
k = (int)MainPoker.TableCards.FirstCard;
for (int j = 0; j < straight1.Length; j++)
{
straight1[j] = hand[k];
k++;
}
int[] a = straight.Where(o => o % 4 == (int)Cards.CardSuits.Club).ToArray();
int[] b = straight.Where(o => o % 4 == (int)Cards.CardSuits.Diamond).ToArray();
int[] c = straight.Where(o => o % 4 == (int)Cards.CardSuits.Heart).ToArray();
int[] d = straight.Where(o => o % 4 == (int)Cards.CardSuits.Spade).ToArray();
int[] st1 = a.Select(o => o / 4).Distinct().ToArray();
int[] st2 = b.Select(o => o / 4).Distinct().ToArray();
int[] st3 = c.Select(o => o / 4).Distinct().ToArray();
int[] st4 = d.Select(o => o / 4).Distinct().ToArray();
int[][] combinedArrays = { st1, st2, st3, st4 };
Array.Sort(straight);
Array.Sort(st1);
Array.Sort(st2);
Array.Sort(st3);
Array.Sort(st4);
if (hand[user.RightCard] / 4 != (int)Cards.CardTypes.Ace &&
hand[user.LeftCard] / 4 != (int)Cards.CardTypes.Ace)
{
if (hand[user.RightCard] / 4 > hand[user.LeftCard] / 4)
{
_kicker = hand[user.RightCard] / 4;
}
else
{
_kicker = hand[user.LeftCard] / 4;
}
}
if (hand[user.RightCard] / 4 == (int)Cards.CardTypes.Ace)
{
_rightCard = 13;
_kicker = 13;
}
else
{
_rightCard = hand[user.RightCard] / 4;
}
if (hand[user.LeftCard] / 4 == (int)Cards.CardTypes.Ace)
{
_leftCard = 13;
_kicker = 13;
}
else
{
_leftCard = hand[user.LeftCard] / 4;
}
_sumOfHands = _rightCard + _leftCard;
const int localType = (int)Hand.Combinations.FourOfAKind;
for (int j = 0; j <= 3; j++)
{
if (straight[j] / 4 == straight[j + 1] / 4 && straight[j] / 4 == straight[j + 2] / 4 &&
straight[j] / 4 == straight[j + 3] / 4)
{
UpdateHand(user, localType, straight[j] / 4 * 4);
return true;
}
if (straight[j] / 4 == (int)Cards.CardTypes.Ace && straight[j + 1] / 4 == (int)Cards.CardTypes.Ace &&
straight[j + 2] / 4 == (int)Cards.CardTypes.Ace && straight[j + 3] / 4 == (int)Cards.CardTypes.Ace)
{
UpdateHand(user, localType, 13 * 4);
return false;
}
}
return false;
}
}
And the second derived class :
public class RoyalFlush : ICombinationAnalyzer
{
public override bool Check(IReadOnlyList<int> hand, UsersProperties user)
{
int _kicker,
_rightCard,
_sumOfHands,
_leftCard;
int[] straight1 = new int[5];
int[] straight = new int[7];
int k = (int) MainPoker.TableCards.FirstCard;
straight[0] = hand[user.RightCard];
straight[1] = hand[user.LeftCard];
for (int j = 2; j < straight.Length; j++)
{
straight[j] = hand[k];
k++;
}
k = (int) MainPoker.TableCards.FirstCard;
for (int j = 0; j < straight1.Length; j++)
{
straight1[j] = hand[k];
k++;
}
int[] a = straight.Where(o => o%4 == (int) Cards.CardSuits.Club).ToArray();
int[] b = straight.Where(o => o%4 == (int) Cards.CardSuits.Diamond).ToArray();
int[] c = straight.Where(o => o%4 == (int) Cards.CardSuits.Heart).ToArray();
int[] d = straight.Where(o => o%4 == (int) Cards.CardSuits.Spade).ToArray();
int[] st1 = a.Select(o => o/4).Distinct().ToArray();
int[] st2 = b.Select(o => o/4).Distinct().ToArray();
int[] st3 = c.Select(o => o/4).Distinct().ToArray();
int[] st4 = d.Select(o => o/4).Distinct().ToArray();
int[][] combinedArrays = {st1, st2, st3, st4};
Array.Sort(straight);
Array.Sort(st1);
Array.Sort(st2);
Array.Sort(st3);
Array.Sort(st4);
if (hand[user.RightCard]/4 != (int) Cards.CardTypes.Ace &&
hand[user.LeftCard]/4 != (int) Cards.CardTypes.Ace)
{
if (hand[user.RightCard]/4 > hand[user.LeftCard]/4)
{
_kicker = hand[user.RightCard]/4;
}
else
{
_kicker = hand[user.LeftCard]/4;
}
}
if (hand[user.RightCard]/4 == (int) Cards.CardTypes.Ace)
{
_rightCard = 13;
_kicker = 13;
}
else
{
_rightCard = hand[user.RightCard]/4;
}
if (hand[user.LeftCard]/4 == (int) Cards.CardTypes.Ace)
{
_leftCard = 13;
_kicker = 13;
}
else
{
_leftCard = hand[user.LeftCard]/4;
}
_sumOfHands = _rightCard + _leftCard;
foreach (var t in combinedArrays.Where(t => t.Length >= 5))
{
if (t[0] + 4 == t[4])
{
UpdateHand(user, (int) Hand.Combinations.StraightFlush, t.Max()/4);
}
if (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)) continue;
UpdateHand(user, (int) Hand.Combinations.RoyalFlush, t.Max()/4);
return true;
}
return false;
}
}
As you can see, all the variables have the exact same declaration and the exact same values. However, they do depend on the input parameter UserProperties
. I can probably declare them somewhere in the abstract class, but I will still have to have a method for it.
Is this the best way to do it? There are more derived classes that declare the same variables, so it's a big mess. In some of the derived classes, _kicker
and sumOfHand
variables are not being used. Any improvements to the declaration of the variables is also appreciated.