Search code examples
c#array-indexing

2D array 3x9 matrix get the index of the next two elements of the current index and check if it is equal to 0


I am a total newbie to programming and i have been following some tutorials on array related to housie ticket generator.The point where I am stuck is that, I have to check each rows and each rows of the 3x9 matrix should not have more the two empty cells or it cannot have more then two cells filled next to each other.I am putting random numbers on the arrays and trying to validate the rules but,the program crashes. Can someone please give me an idea.?

This is what i've tried.

for(int columnIndex=0;columnIndex<=6;columnIndex++)
          {
              if(game[i,columnIndex+2]!=0)
              {
                  return -1;
              }
          }

And this is the whole code

using System;

namespace HelloWorld
{
  class Program
  {
      public static void Main (String[] args)
        {
            for(int times=0;times<2;times++)
            {
                startGame();
                Console.WriteLine("******************************************************************");
            }
            
        }

         private static void startGame()
        {
            int[,] game = new int[3, 9];
            int occupancyLimit = 15;

            while (occupancyLimit > 0)
            {
                int i = getRandomNumber(3);
                int j = getRandomNumber(9);
                //Console.Write(i);
                //Console.Write(j);
                // Console.Write(game[i,j]+" ");
                int data = validateAndReturnNumber(i, j, game);
            
                if (data>0)
                {
                    game[i, j] = data;
                    occupancyLimit--;
                    //Console.WriteLine(game[i,j]);
                }

            }
         for (int i = 0; i < game.GetLength(0); i++)
        {
            for (int j = 0; j < game.GetLength(1); j++)
            {
                Console.Write(game[i,j] + "\t");
            }
            Console.WriteLine();
        }
           
        } 

     
        private static  int validateAndReturnNumber(int i, int j, int[,] game)
        {
            //do not override existing elements in array
            if (game[i,j] != 0)
            {
                return -1;
            }
            //column cannot have more then two elements
            int columncounter = 0;
            for(int c=0;c<3;c++)
            {
                if(game[c,j]!=0)
                {
                    columncounter++;
                }
            }
            if(columncounter>=2)
            {
                return -1;
            }
/*
            //rows cannot have more then two cells filled in and 
            //rows cannot have more then two empty cells
          for(int columnIndex=0;columnIndex<=6;columnIndex++)
          {
              if(game[i,columnIndex+2]!=0)
              {
                  return -1;
              }
          }
     */      
            // rows cannot have more then 5 elements
            int rowcounter = 0;
            for(int r=0;r<9;r++)
            {     
                if(game[i,r]!=0)
                {       
                    rowcounter++;
                }
                
            }
            //Applying, rows cannot have more then 5 elements
            if(rowcounter>=5)
            {
                return -1;
            }

            //return getRandomNumberForColumn(j);
            int data = 0;
            Boolean isValueSet = false;
            do
            {
                data = getRandomNumberForColumn(j);
                isValueSet = isValueExistsInCol(game, i, j, data);
            } while (isValueSet);
            return data;
        }

        private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
        {
            Boolean status = false;
            for(int k=0;k<3;k++)
            {
                if(game[k,j]==data)
                {
                    status = true;
                    break;
                }
            }
            return status;
        }

        private static int getRandomNumberForColumn(int high)
        {
          if(high==0)
            {
                high = 10;

            }
            else
            {
                high=(high + 1) * 10;
            }
            int low = high - 9;
            Random random = new Random();
            return random.Next(high-low)+low;
        }

        private static int getRandomNumber(int max)
        {
            Random random = new Random();
            int num=random.Next(max);
            return (num);
            
        }
    }
}

Solution

  • Why your for loop does not work:

    for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
    {
      if (game[i, columnIndex + 2] != 0)
      {
        return -1;
      }
    }
    

    This loop does not take j into account. It is testing for previous numbers added, as soon as one previous number fails this test, it will fail indefinitely. This creates an infinite loop. This loop also fails if a number is placed in any position past 1, while it needs to fill 5 positions to succeed. This is mathematically impossible.

    This: 'should not have more the two empty cells or it cannot have more then two cells' is also mathematically impossible. a row of 9 cannot have less than 2 full and less than 2 empty at the same time.

    I think you are after 2 empty or full consecutively in a row. For that testing for two empty in a row cannot be achieved as it starts empty, and you are testing it before you fill it. Fortunately this is a redundant test that will always be true based on all of the other test cases.

    No more than 2 full in a row is possible, but can also lead to impossible scenarios. I have added a check that resets the scenario if it has not found the solution after 1000 guesses.

    using System;
    
    namespace HelloWorld
    {
        class Program
        {
            public static void Main(String[] args)
            {
                for (int times = 0; times < 2; times++)
                {
                    startGame();
                    // Console.WriteLine("******************************************************************");
                }
    
            }
    
            private static void startGame()
            {
                int iCount = 0;
                int[,] game = new int[3, 9];
                int occupancyLimit = 15;
    
                while (occupancyLimit > 0)
                {
                    int i = getRandomNumber(3);
                    int j = getRandomNumber(9);
                    //Console.Write(i);
                    //Console.Write(j);
                    // Console.Write(game[i,j]+" ");
                    int data = validateAndReturnNumber(i, j, game);
    
                    if (data > 0)
                    {
                        game[i, j] = data;
                        occupancyLimit--;
                        //Console.WriteLine(game[i,j]);
                    }
                    else
                    {
                        iCount++;
                        //Console.WriteLine(iCount);
                        //printGame(game);
    
                        // If X many fails, retry
                        if(iCount > 1000)
                        {
                            iCount = 0;
                            game = new int[3, 9];
                            occupancyLimit = 15;
                        }
                    }
    
                    // If you want to check for zeros you would need to do it here. And use while(true) above
                    /*
                    if( //Check for zeros)
                    {
                        break; // Ends While loop
                    }
                    else
                    {
                        // Reset and try again
                        iCount = 0;
                        game = new int[3, 9];
                        occupancyLimit = 15;
                    }
                    */
                }
    
                printGame(game);
            }
    
    
            private static void printGame(int[,] game)
            {
                for (int i = 0; i < game.GetLength(0); i++)
                {
                    for (int j = 0; j < game.GetLength(1); j++)
                    {
                        Console.Write(game[i, j] + "\t");
                    }
                    Console.WriteLine();
                }
                Console.WriteLine("******************************************************************");
            }
    
    
            private static int validateAndReturnNumber(int i, int j, int[,] game)
            {
                //do not override existing elements in array
                if (game[i, j] != 0)
                {
                    return -1;
                }
                //column cannot have more then two elements
                int columncounter = 0;
                for (int c = 0; c < 3; c++)
                {
                    if (game[c, j] != 0)
                    {
                        columncounter++;
                    }
                }
                if (columncounter >= 2)
                {
                    return -1;
                }
    
                if(
                    (j != 0 && j != 1 && game[i, j - 2] != 0 && game[i, j - 1] != 0) || // 12X 
                    (j != 0 && j != 8 && game[i, j - 1] != 0 && game[i, j + 1] != 0) || // 1X3
                    (j != 7 && j != 8 && game[i, j + 1] != 0 && game[i, j + 2] != 0)    // X23
                   )
                {
                    return -1;
                }
    
                //for (int columnIndex = 0; columnIndex <= 6; columnIndex++)
                //{
                //    if (game[i, columnIndex + 2] != 0)
                //    {
                //        return -1;
                //    }
                //}
    
                // rows cannot have more then 5 elements
                int rowcounter = 0;
                for (int r = 0; r < 9; r++)
                {
                    if (game[i, r] != 0)
                    {
                        rowcounter++;
                    }
    
                }
                //Applying, rows cannot have more then 5 elements
                if (rowcounter >= 5)
                {
                    return -1;
                }
    
                //return getRandomNumberForColumn(j);
                int data = 0;
                Boolean isValueSet = false;
                do
                {
                    data = getRandomNumberForColumn(j);
                    isValueSet = isValueExistsInCol(game, i, j, data);
                } while (isValueSet);
                return data;
            }
    
            private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
            {
                Boolean status = false;
                for (int k = 0; k < 3; k++)
                {
                    if (game[k, j] == data)
                    {
                        status = true;
                        break;
                    }
                }
                return status;
            }
    
            private static int getRandomNumberForColumn(int high)
            {
                if (high == 0)
                {
                    high = 10;
    
                }
                else
                {
                    high = (high + 1) * 10;
                }
                int low = high - 9;
                Random random = new Random();
                return random.Next(high - low) + low;
            }
    
            private static int getRandomNumber(int max)
            {
                Random random = new Random();
                int num = random.Next(max);
                return (num);
    
            }
        }
    }
    

    Cheers!