2D Array function matching 3 characters

I'm working on an assignment that is asking to take a 3X10 2D array and determine if there are three matching ('T') characters either vertically, and/or diagonal up, and/or diagonal down. if conditions are satisfied returns true, if not returns false.


I'm assuming I will need three separate loops to check each condition. I think I might be close on the vertical condition, but not sure where to start on the diagonal conditions. Any help would be appreciated.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  bool connectThree (char grid [3][10])
{
	
	for (int column = 0; column < 10; column++) {
		
		if (grid[0][column] && grid[1][column] && grid[2][column] == 'T')
			return true;
						
	}
		
	return false;
}





int main()
{
	char grid[3][10] =  {{'T', 'F', 'T', 'T', 'F', 'F', 'T', 'F', 'F', 'F'},
			     {'F', 'F', 'F', 'T', 'F', 'T', 'F', 'T', 'F', 'T'},
		             {'T', 'F', 'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F'}};

	cout << connectThree(grid) << endl;

	
	system("PAUSE");
	return 0;
}
Last edited on
Hello roundtwo,

It is a small thing, but consider this:
1
2
3
4
5
6
char grid[3][10]
{ 
    { 'T', 'F', 'T', 'T', 'F', 'F', 'T', 'F', 'F', 'F' },
    { 'F', 'F', 'F', 'T', 'F', 'T', 'F', 'T', 'F', 'T' },
    { 'T', 'F', 'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F' } 
};

A slightly better visual representation of the array that can make it easier to work with. But there is nothing wrong with what you did.

Based on the array the diagonal loop would have to start with checking (0, 0), (1, 1), (2, 2) and if false the next check would be (0, 1), (1, 2), (2, 3) and so on. Also make sure that you do not end up trying trying to check (2, 10) or (2, 11) which would be past the end of the array.

And the last loop would start at (2, 9), (1, 8) and (0, 7) and work backwards.

You may or not be able to do these in just 1 for loop.

Also consider searching for some of the more recent post on "Tic Tac Toe". You may not find an exact bit of code that will work, but it might give you some ideas as there is more than 1 way to do this tyoe of code.

Andy
do not assume :)
you only need one loop. (ok, this is really 2 nested loops because 2-d, unless you feel like collapsing it to 1-d, which isnt helpful here).

for each character in the grid (this is the nested loops!), is it a T? If so, check each condition from that letter. If ANY of the conditions are true, you found it. This is where you thought you needed a loop for each condition, but instead, you loop once and check 3 things each time. Its less code.

you need to be SURE that you DO NOT go out of bounds. One way to do that is to put a 2-d pad of 'f's around the real data. If you do that, you only need to iterate the inner array, not the whole thing, so for each letter in the original group. Can you figure out the loops for that? It now can go 'out of bounds' of the original into the padded areas safely. Or you can instead check everything. Note that 2-d arrays, if you go out of bounds a little, is often LEGAL but INCORRECT. For example grid[2][12] is legal. Its just not right! (grid[2][12] is really grid[3][2]!).

assuming you dealt with out of bounds issues:

across: grid[x][y]==grid[x][y+1] && grid[x][y]==grid[x][y+2]; //its already a T because you don't check if it was F, as per my above note on calling the tests when it is a T. so 3 Fs won't be true, because you didn't check that, right?

down: grid[x][y] == grid[x+1][y] && grid[x][y] == grid[x+2][y];

diagonal down:
grid[x][y] == grid[x+1][y+1] && grid[x][y]==grid[x+2][y+2];

see the patterns?
Last edited on
Hello roundtwo,

I did consider using 1 for loop to check everything as jonnin said, but I thought first it might be better to get an understanding of doing it individually before you jump into something more advanced.

So I came up with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <iomanip>
#include <string>
#include <limits>

constexpr int MAXROWS{ 3 }, MAXCOLS{ 10 };

bool connectThree(char grid[][MAXCOLS])
{
    for (int column = 0; column < 10; column++)
    {
        if (grid[0][column] == 'T' && grid[1][column] == 'T' && grid[2][column] == 'T')
            return true;
    }

    for (int col = 0, row = 0; col < MAXCOLS - 3; col ++)
    {  
        if (grid[row][col] == 'T' && grid[row + 1][col + 1] == 'T' && grid[row + 2][col + 2] == 'T')
            return true;
    }

    return false;
}

int main()
{
    char grid[MAXROWS][MAXCOLS]  // <--- This grid will return false.
    {
        { 'T', 'F', 'T', 'T', 'F', 'F', 'T', 'F', 'F', 'F' },
        { 'F', 'F', 'F', 'T', 'F', 'T', 'F', 'T', 'F', 'T' },
        { 'T', 'F', 'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F' } 
    };
    //char grid[MAXROWS][MAXCOLS]  // <--- For Testing vertical.   // <--- This grid will return true.
    //{
    //    { 'T', 'F', 'T', 'T', 'F', 'F', 'T', 'F', 'F', 'F' },
    //    { 'F', 'F', 'F', 'T', 'F', 'T', 'T', 'T', 'F', 'T' },
    //    { 'T', 'F', 'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F' }
    //};
    //char grid[MAXROWS][MAXCOLS]  // <--- For Testing diagional.   // <--- This grid will return true.
    //{
    //    { 'T', 'F', 'T', 'T', 'F', 'F', 'T', 'F', 'F', 'F' },
    //    { 'F', 'F', 'F', 'T', 'F', 'T', 'F', 'T', 'F', 'T' },
    //    { 'T', 'F', 'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F' }
    //};

    std::cout << "\n " << std::boolalpha << connectThree(grid) << '\n';

    // <--- Keeps console window open when running in debug mode on Visual Studio. Or a good way to pause the program.
    // The next line may not be needed. If you have to press enter to see the prompt it is not needed.
    //std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
    std::cout << "\n\n Press Enter to continue: ";
    std::cin.get();

    return 0;  // <--- Not required, but makes a good break point.
}

I changed line 13 because what is on either side of "&&" need bo be an individual check. With what you have it would look like this (true && true && grid[2][column] == 'T'). Only the last bit can be true or false. The first 2 (grid[0][column]) returns whatever is stored at that index and since either "F" or "T" has an ASCII value > 0 it is evaluated to true. The only way this could be false is if "\0" is stored at that index.

In "main" the 2 grids that are commented are just an easy way to set up different tests with out changing the original grid.

The bit of code at the end is a replacement I use instead of "system("pause");", which you should avoid using "system" anything. It is not 100% save.

Putting a comment on line 51 is because there is not formatted input in the program right now. This may or will need to be uncommented later.

As a note: You do not always need the extra blank line like in your original code lines 5 and 8 and lines 13 - 16. Not important just something to consider.

Andy
Topic archived. No new replies allowed.