-2
\$\begingroup\$

i'm trying to find the winner of a 3x3 TicTacToe game. I user input N which is number of moves, and then N moves like (1,0), (0,2), etc. (X strats the game). At the end of the game the program should return who wins the game (X or 0) or "draw" if there is no winner. I have the following code:

namespace ConsoleApp20;
public class Program
{
    public static string Tictactoe(int[][] moves)
    {
        int[] row = new int[3];
        int[] col = new int[3];
        int diag1 = 0;
        int diag2 = 0;
        const int c1 = 2;
        const int c2 = 3;
        int n = Convert.ToInt32(Console.ReadLine());
        for (int i = 0; i < n; i++)
        {
            int x = moves[i][0];
            int y = moves[i][1];
            var inc = i % 2 == 0 ? 1 : -1;
            row[x] += inc;
            col[y] += inc;
            if (x == y)
            {
                diag1 += inc;
            }

            if (x + y == c1)
            {
                diag2 += inc;
            }

            if (Math.Abs(row[x]) == c2 || Math.Abs(col[y]) == c2 || Math.Abs(diag1) == c2 || Math.Abs(diag2) == c2)
            {
                return i % c1 == 0 ? "X" : "0";
            }
        }

        return moves.Length == 9 ? "Draw" : "Pending";
    }
}

I need a suggestion about how to reduce the cyclomatic complexity of this method from 11 to 10.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Why all the downvotes and no comments? \$\endgroup\$ Commented Nov 6, 2022 at 15:53
  • \$\begingroup\$ @QuasiStellar - I upvoted your comment before reading the code. After reading, I can't revoke the upvote lol. In looking at the code, it doesn't look like it's coded to play like tic tac toe and doesn't function as described in the question description. \$\endgroup\$
    – Chuck
    Commented Nov 6, 2022 at 22:02
  • \$\begingroup\$ Welcome to CodeReview! Can you please share with a sample moves array? \$\endgroup\$ Commented Nov 9, 2022 at 7:36
  • \$\begingroup\$ Which computer science / programming Stack Exchange sites do I post on? \$\endgroup\$
    – BCdotWEB
    Commented Nov 10, 2022 at 14:47

1 Answer 1

0
\$\begingroup\$

Without having a proper context, here are my suggestions.
Where I had made any assumptions I stated them before any suggestions.

Constants

Assumption(s)

  • c2 represents the dimension of the TicTacToe's matrix

Suggestion(s)

  • You should define them on the class-level rather than inside the method
  • You should use better naming than c1 and c2 to express your intents
  • You should use c2 in the arrays declarations as well new int[c2]; to ease the future work if you need to support 2x2 or 4x4 TicTacToe as well

User input

Suggestion(s)

  • User can provide any data textual data via the console interface
  • Please make sure that input is in the right format (use int.TryParse)
  • and between the right range
if (n < lowerLimiter || n > upperLimit) 
   throw new ArgumentOutOfRangeException(...);
  • Depending on the requirements you might need to implement a retry logic which runs until the user provides a valid input

Jagged array

Assumption(s)

  • The first dimension represents the move ordinal
  • The second dimension represents the coordinates (x and y in your case)

Suggestion(s)

  • It seems like that the second dimension of the jagged array will always contain 2 elements
    • It might make sense to use a dedicated structure for that
    • Either by using some built-in ones like Point struct or creating your own
  • Iterating through a jagged array can be done by a foreach
    • I'm uncertain how does N relates to the first dimension of the moves, so this might not be applicable for your use case
foreach (var (move, moveIndex) in moves.Select((array, index) => (array, index)))
{
    var (x, y) = (move[0], move[1]);
    var inc = moveIndex % 2 == 0 ? 1 : -1;
    ...
}

Ternary conditional operator

Suggestion(s)

  • Rather than having guard expression to do an assignment only if certain criteria is met you can use ?: operator here as well to stream-line your code
diag1 = x == y ? diag1 + inc : diag1;
diag2 = x + y == c1 ? diag2 + inc : diag2;
  • Please spend some time to try to find better names than diag1 and diag2

Single return

Suggestion(s)

  • Try to aim for having only a single return
    • Rather than calling a return inside the for/foreach loop use break
int? lastMoveIndex =  null;
foreach (...)
{
    ...
    if (Math.Abs(row[x]) == c2
        || Math.Abs(col[y]) == c2
        || Math.Abs(diag1) == c2
        || Math.Abs(diag2) == c2)
    {
        lastMoveIndex = moveIndex;
        break;
    }
}

return lastMoveIndex.HasValue
        ? lastMoveIndex.Value % c1 == 0 ? "X" : "0"
        : moves.Length == 9 ? "Draw" : "Pending";
\$\endgroup\$
8
  • \$\begingroup\$ For example, if I have to user input like: N=5 and then (1 0) (1 1) (0 2) (2 2) (2 0) each on new line. Those brackets representing moves for X (first) and 0 (second). How can I add them on a matrix if this would be inputed as string arrays separated by " "? \$\endgroup\$ Commented Nov 9, 2022 at 13:04
  • \$\begingroup\$ @DragosBogdan Could you please help me understand what does this (1 0) (1 1) (0 2) (2 2) (2 0) sequence mean? \$\endgroup\$ Commented Nov 9, 2022 at 13:10
  • \$\begingroup\$ These are the positions where X and 0 are placed in a 3x3 matrix, first number is the row, second number is the column. \$\endgroup\$ Commented Nov 9, 2022 at 13:13
  • \$\begingroup\$ @DragosBogdan How do you determine which pair of numbers are representing an X or an 0? \$\endgroup\$ Commented Nov 9, 2022 at 13:24
  • 1
    \$\begingroup\$ stackoverflow.com/questions/74329540/… \$\endgroup\$ Commented Nov 9, 2022 at 16:41

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