(Array Swapping Elements) Game Help

Hi I have some programming homework and I've got the main idea but I am not sure how to swap the numbers in the array.
This was the question.
This game has 9 squares with the numerals 1 through 8 on them, and a 9th square with some special symbol printed. The squares are arranged in 3 rows and 3 columns. For example, an arrangement might look like this:
1 * 3
4 2 6
7 5 8
You can swap the special symbol with the numeral printed on any of its neighbours (the squares immediately to its left or right, above, or below it). For example, starting with the arrangement above, I can restore the “natural” arrangement (below) by swapping the * with the 2, then with the 5,and then with the 8:
1 2 3
4 5 6
7 8 *

The object of the game is to begin with the squares in a random order, and to get them into the “natural” order shown above, using only valid swaps between the special symbol and neighbouring numerals. Valid input is the digits 1-8 and valid moves are the horizontal or vertical squares adjacent to the special symbol. Invalid swaps will not change the order of any squares. Use the project name

Here is my code.

Thanks in advance.
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int random_matrix[3][3]; //create matrix
void Swap(int &x, int &y)
{
int temp;
temp = x;
x = y;
y = temp;

}
bool check(int r) //check function
{
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            if(r==random_matrix[i][j]) //if r is in random matrix
            {
                return true; //return true
            }
        }
    }
    return false; //return false
}

int main()
{
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            random_matrix[i][j]=0; //set array equal to 0 (Initializing array)
        }
    }

    srand ( time(NULL) ); // initialize once only
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            int r=rand() %9+1; //create a random variable from 1-9
            if(check(r)==false) //call method (if false)
            {
                random_matrix[i][j]=r; //use that variable
            }
            else
            {
                while(check(r)==true) //if it is already in array use the while loop
                {
                    r=rand() % 9+1; //create a new number
                   // cout<<"duplicate"<<endl; //shows how many duplicates there are
                }
                random_matrix[i][j]=r; //once a number is found that is unused add it to array
            }

        }
    }

    for(int x=0; x<3; x++) // loop 3 times for three lines
    {
        for(int y=0; y<3; y++) // loop for the three elements on the line
        {
            if (random_matrix[x][y]==9) //if the matrix has a 9
            {
                cout<<'*'; //print out symbol instead
            }
            else
            {
                cout<<random_matrix[x][y];  // display the current element out of the array
            }
        }
        cout<<endl;  // when the inner loop is done, go to a new line
    }

    cout<<"What number do you want to swap?";

    return 0;

}
Help please?
There's no need to create a whole new thread just to post updated code. Just edit your first post in your original thread.

Also, what is your question exactly? In your first thread I showed you an example of how to swap elements of an array. What part is confusing you? The help we can give you is only as good as the information you give us.
In the example you showed me you assign 'temp' to a number you chose but how do i do that with the user choosing the number?
The user has to enter two numbers, since you need a pair of numbers if you want to perform a swap.

You would search the array for the numbers the user has requested to swap. If a number cannot be found in the array, prompt the user to try another number. If both numbers have been found, you know the indices of the numbers, and swapping is trivial.
any help? please
Here's one way of finding a single number.

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
#include <iostream>

int main() {

	const int num_numbers = 3;
	int array[num_numbers] = {0, 5, 10};

	int requested = 5;
	int index = 0;

	bool found = false;
	for (int i = 0; i < num_numbers; ++i) {
		if (array[i] == requested) {
			found = true;
			index = i;
		}
	}

	if (found) {
		std::cout << "The requested number (" << requested << ") found at index " << index << "." << std::endl;
	}
	else {
		std::cout << "The requested number (" << requested << ") is not in the array." << std::endl;
	}

	return 0;
}


You'll still have to find the second requested number, and make sure the whole thing loops over and asks for input again if one of the requested numbers hasn't been found.
Last edited on
Any ideas?
Any help would be appreciated please
You're missing a few functions:

First, you will need to find the number to be moved in the array and convert its position to row and col.
1
2
3
4
5
6
7
8
//  Return row & col of num
bool Find (int matrix[N][N], int num, int &r, int &c)
{   for (r=0; r<N; r++)
        for (c=0; c<N; c++)
            if (matrix[r][c] == num)
                return true;    //  found - r,c valid
    return false;       // not found - r,c not valid
}


Second, you will need to determine if the * is a neighbor of the number selected:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool is_neighbor (int matrix[N][N], int r, int c, int & r1, int & c1)
{   r1 = r - 1;
    c1 = c;
    if (r1 >= 0 && matrix(r1][c1] == STAR)
        return true;    //  cell above is *
    r1 = r + 1;        
    if (r1 < N && matrix[r1][c1] == STAR)
        return true;    //  cell below is * 
    r1 = r;
    c1 = c-1;        
    if (c1 >= 0 && matrix[r1][c1] == STAR)
        return true;    //  cell to left is * 
    c1 = c + 1;        
    if (c1 < N && matrix[r1][c1] == STAR) 
        return true;    //  cell to right is *
    return false;       //  * is not a neighbor, r1,c1 not valid
}            


From line 80 of main:
80
81
82
83
84
85
86
    cout << "What number do you want to swap?";
    cin >> num;
    Find (matrix, num, r, c);   //  Convert num to R & C
    if (is_neighbor (matrix, r, c, r1, c1))
        Swap (matrix[r][c], matrix[r1][c1]);
    return 0;
}

You will want to add a loop to keep asking for moves until you have the desired arrangement. And of course a function to test for the correct arrangement.
Last edited on
closed account (D80DSL3A)
You're a bit off track. Let's backup a bit.
The user won't be entering 2 numbers to swap, he will enter 1 number (say x) and you will check to see if that number is a neighbor of the *.
If x is a neighbor of *, then it's time to "swap" x with the *.

You should keep track of where the * is.
Declare int row9=0, col9=0; and get initial values for them while filling the array with random numbers.
Starting at line 58 in your opening post:
1
2
3
random_matrix[i][j]=r; //once a number is found that is unused add it to array
row9 = i;// save position of the 9
col9 = j;


Later, we will prompt user for a number (x) to swap with the 9.
Write a function bool is9neighbor( int x, int& r, int& c, int row9, int col9 ); to check if x is a neighbor of 9, and if so write the position of x to r,c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// is x a neighbor of the * ?
// if so, write position of x to r,c and return true
bool is9neighbor( int x, int& r, int& c, int row9, int col9 )// discouraging global variables. Pass them
{
    if( col9 > 0 && random_matrix[row9][col9-1] == x )// left neighbor
    {
        r = row9;
        c = col9-1;
        return true;
    }

    // check the other 3 cases

    return false;
}

Try to tighten up your routine for repeating until a condition is met
1
2
3
4
5
6
7
int userEntry;// user enters this value
    int rowSwap, colSwap;// is9neighbor() writes to these
    do
    {
        cout << "Enter number to swap with the *: ";
        cin >> userEntry;
    }while( !is9neighbor( userEntry, rowSwap, colSwap, row9, col9 ) );

If we ever get past that code then rowSwap, colSwap are good, and we can male the "swap".
1
2
3
4
5
6
7
// now we worry about swapping x with the *
 // and update the values for row9, col9
        // "swapping values" is easy in this case. Just overwrite the values, you know both
        random_matrix[row9][col9] = userEntry;// new place for the 9
        random_matrix[rowSwap][colSwap] = 9;// new place for the 9
        row9 = rowSwap;
        col9 = colSwap;

edit: I've seen your post in the minesweeper thread. Great!! I gotta jam (picking up daughters to spend the afternoon doing volunteer work at local humane society) but I'll look forward to checking it out tonight.

Hope above code gives you some ideas for moving forward with the problem.
Last edited on
Hey, thanks for getting back to me! Not even joking I am learning more than you than I am in school. Our teacher doesn't even teach us in class.
Anyways, I got the code to partially work. So when it runs it asks user to input a number and it does this over and over again. I wanted to print out the array after each swap occurs.

So the code is looking like this (in case you wanted to run it on shell)
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int random_matrix[3][3]; //create matrix
int row9=0, col9=0;
void Swap(int &x, int &y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;

}
bool check(int r) //check function
{
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            if(r==random_matrix[i][j]) //if r is in random matrix
            {
                return true; //return true
            }
        }
    }
    return false; //return false
}
bool is9neighbor( int x, int& r, int& c, int row9, int col9 )// discouraging global variables. Pass them
{
    if( col9 > 0 && random_matrix[row9][col9-1] == x )// left neighbor
    {
        r = row9;
        c = col9-1;
        return true;
    }

    // check the other 3 cases

    return false;
}
int main()
{

    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            random_matrix[i][j]=0; //set array equal to 0 (Initializing array)
        }
    }

    srand ( time(NULL) ); // initialize once only
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            int r=rand() %9+1; //create a random variable from 1-9
            if(check(r)==false) //call method (if false)
            {
                random_matrix[i][j]=r; //use that variable
            }
            else
            {
                while(check(r)==true) //if it is already in array use the while loop
                {
                    r=rand() % 9+1; //create a new number
                    // cout<<"duplicate"<<endl; //shows how many duplicates there are
                }
                random_matrix[i][j]=r; //once a number is found that is unused add it to array
                row9 = i;// save position of the 9
                col9 = j;
            }

        }
    }

    for(int x=0; x<3; x++) // loop 3 times for three lines
    {
        for(int y=0; y<3; y++) // loop for the three elements on the line
        {
            if (random_matrix[x][y]==9) //if the matrix has a 9
            {
                cout<<'*'; //print out symbol instead
            }
            else
            {
                cout<<random_matrix[x][y];  // display the current element out of the array
            }
        }
        cout<<endl;  // when the inner loop is done, go to a new line
    }

    int userEntry;// user enters this value
    int rowSwap, colSwap;// is9neighbor() writes to these
    do
    {
        cout << "Enter number to swap with the *: ";
        cin >> userEntry;
    }
    while( !is9neighbor( userEntry, rowSwap, colSwap, row9, col9 ) );


    random_matrix[row9][col9] = userEntry;// new place for the 9
    random_matrix[rowSwap][colSwap] = 9;// new place for the 9
    row9 = rowSwap;
    col9 = colSwap;
    for(int x=0; x<3; x++) // loop 3 times for three lines
    {
        for(int y=0; y<3; y++) // loop for the three elements on the line
        {
            cout<<random_matrix[x][y];  // display the current element out of the array

        }
        cout<<endl;
    }

    return 0;

}
any ideas on fixing the print?
Last edited on
closed account (D80DSL3A)
Yes. I forgot a detail. When saving the position of the 9, one should check that r == 9.
Following line 72 then in your code above make it:
1
2
3
4
5
if( r == 9 )                
{
      row9 = i;// save position of the 9
       col9 = j;
}

Then your code works right. If the user enters the # that is left neighbor of 9 the while loop terminates, the final output occurs and the program ends.
I left the other 3 cases in is9neighbor for you to code.

Other than that, you could probably use a print function. Repeating those loops in main every time can really bloat the code.

I also have something very interesting on the way for your minesweeper thread.
Last edited on
So two more quick questions.
1) For the neighbour condition, should i be checking the user input number correct? (making userEntry a global variable?)
2) After it prints the swapped version it breaks the loop, how do i keep it looping


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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int random_matrix[3][3]; //create matrix
int row9=0, col9=0;
void Swap(int &x, int &y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;

}
bool check(int r) //check function
{
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            if(r==random_matrix[i][j]) //if r is in random matrix
            {
                return true; //return true
            }
        }
    }
    return false; //return false
}
bool is9neighbor( int x, int& r, int& c, int row9, int col9 )// discouraging global variables. Pass them
{
       if( col9 > 0 && random_matrix[row9][col9-1] == x )// left neighbor
    {
        r = row9;
        c = col9-1;
        return true;
    }
    if( row9 > 0 && random_matrix[row9][col9-1] == x )// left neighbor
    {
        r = row9-1;
        c = col9;
        return true;
    }

    // check the other 3 cases

    return false;
}
int main()
{

    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            random_matrix[i][j]=0; //set array equal to 0 (Initializing array)
        }
    }

    srand ( time(NULL) ); // initialize once only
    for(int i=0; i<3; i++) // loop 3 times for three lines
    {
        for(int j=0; j<3; j++) // loop for the three elements on the line
        {
            int r=rand() %9+1; //create a random variable from 1-9
            if(check(r)==false) //call method (if false)
            {
                random_matrix[i][j]=r; //use that variable
            }
            else
            {
                while(check(r)==true) //if it is already in array use the while loop
                {
                    r=rand() % 9+1; //create a new number
                    // cout<<"duplicate"<<endl; //shows how many duplicates there are
                }
                random_matrix[i][j]=r; //once a number is found that is unused add it to array
                if(r==9)
                {
                row9 = i;// save position of the 9
                col9 = j;
                }
            }

        }
    }

    for(int x=0; x<3; x++) // loop 3 times for three lines
    {
        for(int y=0; y<3; y++) // loop for the three elements on the line
        {
            if (random_matrix[x][y]==9) //if the matrix has a 9
            {
                cout<<'*'; //print out symbol instead
            }
            else
            {
                cout<<random_matrix[x][y];  // display the current element out of the array
            }
        }
        cout<<endl;  // when the inner loop is done, go to a new line
    }

    int userEntry;// user enters this value
    int rowSwap, colSwap;// is9neighbor() writes to these
    do
    {
        cout << "Enter number to swap with the *: ";
        cin >> userEntry;
    }
    while( !is9neighbor( userEntry, rowSwap, colSwap, row9, col9 ) );


    random_matrix[row9][col9] = userEntry;// new place for the 9
    random_matrix[rowSwap][colSwap] = 9;// new place for the 9
    row9 = rowSwap;
    col9 = colSwap;

 for(int x=0; x<3; x++) // loop 3 times for three lines
    {
        for(int y=0; y<3; y++) // loop for the three elements on the line
        {
             if (random_matrix[x][y]==9) //if the matrix has a 9
            {
                cout<<'*'; //print out symbol instead
            }
            else
            {
                cout<<random_matrix[x][y];  // display the current element out of the array
            }
        }
        cout<<endl;
    }
    return 0;

}
Last edited on
closed account (D80DSL3A)
1. Yes you should be checking the user entered number, but that is passed as x to is9neighbor. See 1st arg in call. userEntry need not be global.
WE TRY TO AVOID DOING THAT!
edit: I see you already did that with row9 and col9. No need to pass them to is9neighbor function then (or any other function), so you can remove those arguments.

2. Enclose the whole get & process userEntry code in an enclosing while. Your code just does it once.
Here's a quick & dirty way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
while(true)
{
    // code from line 105
    int userEntry;// user enters this value
    int rowSwap, colSwap;// is9neighbor() writes to these
    cout << "Enter -1 to quit\n";
    do
    {
        cout << "Enter number to swap with the *: ";
        cin >> userEntry;
        if( userEntry == -1 ) return 0;// bail!
    } while( !is9neighbor( userEntry, rowSwap, colSwap, row9, col9 ) );

    // make the swap
    random_matrix[row9][col9] = userEntry;// new place for the 9
    random_matrix[rowSwap][colSwap] = 9;// new place for the 9
    row9 = rowSwap;// update 9 position
    col9 = colSwap;
}

About the neighbor test in is9neighbor. They aren't hard. I see you tried one. You changed the 1st condition to if( row9 > 0 &&... which is fine.
If row9 > 0 then the 9 isn't in row 0 so it has a top neighbor, at row9-1, col9. check for x there.
If row9 < 2 it has a bottom neighbor at row9+1, col9
If col9 < 2 it has a right neighbor at row9, col9+1
Last edited on
I am still kind of confused about the function.
I have it looking like this.
(The loop is working by the way thank you.)
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
bool is9neighbor( int x, int& r, int& c, int row9, int col9 )// discouraging global variables. Pass them
{
       if( col9 > 0 && random_matrix[row9][col9-1] == x )// left neighbor
    {
        r = row9;
        c = col9-1;
        return true;
    }
    if( row9 < 2 && random_matrix[row9][col9-1] == x )// above neighbor
    {
        r = row9-1;
        c = col9;
        return true;
    }
     if( row9 > 0 && random_matrix[row9][col9-1] == x )// above neighbor
    {
        r = row9+1;
        c = col9;
        return true;
    }
     if( col9 < 2 && random_matrix[row9][col9-1] == x )// above neighbor
    {
        r = row9;
        c = col9+1;
        return true;
    }


    // check the other 3 cases

    return false;
}
closed account (D80DSL3A)
Glad the loop is working. Please try a bit harder to reason out that code. If I do anything more I'm writing it for you.
The 9, located at row9, col9 may have up to 4 neighbors (if it's dead center in the array) or as little as 2 (corners). The left neighbor is located at:
row9, col9-1 = left neighbor. but if col9 = 0 you can't check that spot, it's not in the array!

See the last 3 lines in my previous post for the locations of the other 3 neighbors. You need to check those locations for x, but only if they're on the board.

edit: We're writing the function for the neighbor check with code explicitly for each of the 4 cases.
When we get a little more comfortable with this stuff we can generalize the code and do the 4 checks in a loop.
I'm doing very similar things in the minesweeper code where I visit all the neighbors of a given space.
I do this when finding all the neighboring mine counts in createFIeld(), and when clearing around a space with no neighboring mines in clearSpace(). So yes, what you learn from this exercise is relevant.
Here's what you need to do the search here like I do in my minesweeper code.
You will need a function to check that a position is in the array, like the one from minesweeper:
bool isInField( int r, int c );// validates position
This will do for here:
1
2
3
4
5
6
bool isInArray( int r, int c )
{
    if( r < 0 || r > 2 ) return false;
    if( c < 0 || c > 2 ) return false;
    return true;
}

Then, is9neighbor may be written like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool is9neighbor( int x, int& rx, int& cx, int row9, int col9 )// discouraging global variables. Pass them
{
    // neighbor positions
    const int r[4] = { row9,   row9,   row9+1, row9-1};// visit order
    const int c[4] = { col9-1, col9+1, col9,   col9 };// left, right, bottom, top

    for( int i=0; i<4; ++i )
    {   
        if( isInArray( r[i],c[i] ) && random_matrix[ r[i] ][ c[i] ] == x )
        {
            rx = r[i];
            cx = c[i];
            return true;
        }
    }

    return false;
}
Last edited on
Ok, that was very silly of me to miss that... I was staring at it for a good hour and the answer was so obvious! Thanks again for all the help. All I have left to do for this program is to make it check for the game completion and it will be done! Anything i should take into account for that?
Topic archived. No new replies allowed.