2
\$\begingroup\$

i'm doing a Core for a Tic Tac Toe game.

I have my code with a dynamic size of the board (can be 2x2 to 10x10, if is 7x7 we need a 7 characters in a row to win , if is 4x4 we need 4 etc) , This code works for any matrix with any size and give me a bool state if someone won the game (they can use any character to mark on the matrix, like X or O). This code skips the empty strings ("") and zeros ("0").

The Matrix Validator Code (Where i send the matrix i wanna check)

public class MatrixValidator
    {
        private string[,] Matrix { get; set; }
        private string[] Vector { get; set; }
        public MatrixValidator(string[,] matrix)
        {
            this.Vector = new string[matrix.GetLength(0)];
            this.Matrix = matrix;
        }
        public bool MatrixHasWinner()
        {
            return HorizontalValidator() || VerticalValidator() || MainDiagonalValidator() || SecondDiagonalValidator();
        }
        private bool HorizontalValidator()
        {
            bool Control = false;
            for (int i = 0; i < this.Matrix.GetLength(1); i++)
            {
                Array.Clear(Vector, 0, Vector.Length);
                for (int j = 0; j < this.Matrix.GetLength(0); j++)
                {
                    this.Vector[j] = this.Matrix[i, j];
                }
                if (!ArrayValidator.HasBlank(this.Vector))
                    Control = ArrayValidator.HasSameValues(this.Vector);
            }
            return Control;
        }
        private bool VerticalValidator()
        {
            bool Control = false;
            for (int j = 0; j < this.Matrix.GetLength(0); j++)
            {
                Array.Clear(Vector, 0, Vector.Length);
                for (int i = 0; i < this.Matrix.GetLength(1); i++)
                {
                    this.Vector[i] = this.Matrix[i, j];
                }
                if (!ArrayValidator.HasBlank(this.Vector))
                    Control = ArrayValidator.HasSameValues(this.Vector);
            }
            return Control;
        }
        private bool MainDiagonalValidator()
        {
            bool Control = false;
            Array.Clear(Vector, 0, Vector.Length);
            for (int i = 0; i < this.Matrix.GetLength(0); i++)
            {
                for (int j = 0; j < this.Matrix.GetLength(1); j++)
                {
                    if (i == j)
                        this.Vector[j] = this.Matrix[i, j];
                }
            }
            if (!ArrayValidator.HasBlank(this.Vector))
                Control = ArrayValidator.HasSameValues(this.Vector);
            return Control;
        }
        private bool SecondDiagonalValidator()
        {
            bool Control = false;
            Array.Clear(Vector, 0, Vector.Length);
            for (int i = 0; i < this.Matrix.GetLength(1); i++)
            {
                for (int j = 0; j < this.Matrix.GetLength(0); j++)
                {
                    if (i + j == this.Matrix.GetLength(0) - 1)
                        this.Vector[i] = this.Matrix[i, j];
                }
            }
            if (!ArrayValidator.HasBlank(this.Vector))
                Control = ArrayValidator.HasSameValues(this.Vector);
            return Control;
        }
    }

The Array Validator Code (Where i send the line, array i wanna check)

public static class ArrayValidator
    {
        public static bool HasBlank(string[] vector)
        {
            return (vector.Contains("") || vector.Contains("0"));
        }
        public static bool HasSameValues(string[] vector)
        {
            var v = vector.Distinct().Count();
            if (v == 1)
                return true;
            else
                return false;
        }
    }

Program.cs (The usage of my code)

static void Main(string[] args)
        {
            string[,] matrix = { { "X", "X", "X", "X" }, 
                                 { "O", "", "", "" },
                                 { "", "", "", "" },
                                 { "O", "", "O", "" } };
// X Wins
            MatrixValidator matrixValidator = new MatrixValidator(matrix);
            Console.WriteLine(matrixValidator.MatrixHasWinner());
            Console.ReadKey();
        }

What changes can i do to improve this code? Maybe it is not implemented with SOLID? I need help

\$\endgroup\$
4
\$\begingroup\$

Here some some gentle suggestions for this particular implementation:

  • This isn't really a "validator" as it doesn't validate anything. Maybe consider "evaluator" or something along those lines.
  • When you receive the Matrix, you can store the value of this.Matrix.GetLength(0) and use it instead of calling it multiples times. Since you know the Matrix is always NxN, you know that the first dimension length will always match the second dimension length (in other words, this.Matrix.GetLength(1) == this.Matrix.GetLength(0))
  • You aren't checking to see if the Matrix is actually an NxN matrix. What if the user passed in a 4x3?
  • You are doing quite a bit of copying for no strong benefit. If every item in a row, column or diagonal is the same, then you know there's a win. So, see if a character matches the one next to it. If not, then you know there's no win. If it is a match, check the next one. You don't need to copy that to another array and the do the distinct. If you did that, you'd significantly reduce the lines of code and complexity. Maybe something like: if (matrix[i,j] != matrix[i + 1,j]) return false; Obviously you'll need some bounds checking, etc.
  • Other than MatrixHasWinner, there's literally nothing in your code that suggests this is for a game of tic-tac-toe. You are using very generic names (matrix, vector) and not assigning any context to that. Matrix could be GameBoard. Vector could be Row or Column (though, as I said above, you don't really need it).
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.