15 Square Puzzle

I have a great deal of trouble trying to figure out how to use bool move according to this assignment: http://www.cs.hunter.cuny.edu/~saad/courses/c++/hw/hw8.pdf
I can do it without the bools with voids move up/right/left/down.
I understand that with the characters, the space swaps with the number in that direction.
And with a digit it has to see if n is around it in order to swap.
I just don't understand how to call it to do the math.
I don't even think I'm actually calling the pass-by-reference constructor right.
Here is puzzle.cpp that I attempted.
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
139
#include <iostream>
#include <string>
#include <cstdlib>
#include <time.h>
#include "puzzle.h"
using std::cin;
using std::endl;

Puzzle::Puzzle(){
     int a[4][4]=
        {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,' '}
        };
int counter=1;
for(int i =0; i < 4; i++)
    for(int j =0; j < 4; j++)
    {a[i][j] = counter;
    counter++;
    }
    i,j=3;
    correct=15;
}
Puzzle::Puzzle(const string& s){
int a[4][4]=
        {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,' '}
        };
        a[3][3] = 0;
        i,j=3;
        correct=15;
    int counter = 1;
    for(int i =0; i < 4; i++)
    for(int j =0; j < 4; j++)
    {
        a[i][j] = counter;
        counter++;
    }
    char c;
    for(int beg=0;beg<s.length();beg++){
        c=s[beg];
        move(c);
    }
}  // pass by reference to avoid copy

void Puzzle::scramble(int n)
{
srand(time(0));
    for(int k=0;k<n;k++)
    {
        int ran=rand()%4+1;
        char cha;
        if(ran==1)
        {
            cha='l';
            move(cha);
        }
        if(ran==2)
        {
            cha='u';
            move(cha);
        }
        if(ran==3)
        {
            cha='r';
            move(cha);
        }
        if(ran==4)
        {
            cha='d';
            move(cha);
        }
    }
}

bool Puzzle::move(char c)
    {
        if(c!='l' || c!='r' || c!='u' || c!='d')
            {return -1;}
        if(c=='u'){
           	int vP = i;
            if(vP + 1 < 4 && vP >= 0)
            {
            return 1;
            }return -1;
        }
        if(c=='d'){
            int vP = i;
            if(vP + 1 <= 4 && vP > 0)
            {
            return 1;
            }return -1;
        }
        if(c=='l'){
            int hP = j;
            if(hP + 1 < 4 && hP >= 0)
            {
            return 1;
            }return -1;
        }
        if(c=='r'){
           	int hP = j;
            if(hP + 1 <= 4 && hP > 0)
            {
            a[i][j] = a[i][j - 1];
            a[i][j - 1] = 0;
            j -= 1;
            return a[i][j-1];
            }return -1;
        }
    }
bool Puzzle::move(int n)
{

}
void Puzzle::display()
{

    int counter = 1;
    for(int i =0; i < 4; i++)
    {   cout<<"        ";
        for(int j =0; j < 4; j++)
        {   a[i][j] = counter;
            counter++;
            a[3][3]=0;
            cout << "  " << a[i][j];
        }
    cout <<endl<<endl;
    }

}




My test main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
#include "puzzle.cpp"

int main(){
string s;
Puzzle test;
cin>>s;
test=s;
cout<<"  ";
test.scramble(55);
cout<<endl<<endl;
test.display();
}

This is my code without the bools that supposedly works. In case someone can tell me that I can actually use this for some parts of the assignment.
(I can't get the 0 to become a ' ' though. Tried if a[i][j]=0 cout ' ' but that didn't work. Turned everything into 0.)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <iostream>
#include <cstdlib>
#include <ctime>
using std::time;
using std::cout;
using std::cin;
using std::endl;
using std::rand;
using std::srand;


const int arraySize = 4;
int a[ arraySize ] [ arraySize ] =
        {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,0}
        };

int b  [ arraySize ] [ arraySize ] =
        {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,0}
        };

int i = 3; // row Position
int j = 3; // column Position

void moveUp()
{
	int vP = i;
	if(vP + 1 < 4 && vP >= 0){

	a[i][j] = a[i + 1][j];
	a[i + 1][j] = 0;
	i += 1;
	}
}
void moveDown()
{
	int vP = i;
	if(vP + 1 <= 4 && vP > 0){

	a[i][j] = a[i - 1][j];
	a[i - 1][j] = 0;
	i -= 1;
	}
}
void moveRight()
{
	int hP = j;
	if(hP + 1 <= 4 && hP > 0){

	a[i][j] = a[i][j - 1];
	a[i][j - 1] = 0;
	j -= 1;
	}
}
void moveLeft()
{
	int hP = j;
	if(hP + 1 < 4 && hP >= 0){

	a[i][j] = a[i][j + 1];
	a[i][j + 1] = 0;
	j += 1;
	}
}

int solved()
{
int correct;

for(int i = 0; i < arraySize; i++){
	for(int j = 0; j < arraySize; j++){
if(a[i][j] == b[i][j])
correct = 1;
else
return -1;
	}
}
return 1;
}
void scramble(int n)
{
	for(int i = 0; i < n; i++)
	{
	int a = 1 + rand() % 4;
	switch(a)
	{
	case 1:
	moveUp();
	break;

	case 2:
	moveDown();
	break;

	case 3:
	moveRight();

	break;

	case 4:
	moveLeft();
	break;
	}
}
}
int main()
{
	srand(time(0));
	int n=0;
    for(int i = 0; i < arraySize; i++){
	for(int j = 0; j < arraySize; j++)
	cout << "  " << a[i][j];
	cout << endl << endl;
	}

	cout << "Enter how many times scrambled(more than one for higher chance of scrambling): ";
	cin >> n;
	scramble(n);
	if(solved()==-1)
    {
	bool quit(false);

	do
	{
	for(int i = 0; i < arraySize; i++){
	for(int j = 0; j < arraySize; j++)
	cout << "  " << a[i][j];
	cout << endl << endl;
	}

	char a;
	cout << "Move adjacent number: w - Up, s - Down, a - Left, d - Right" << endl;
	cin >> a;
	switch(a)
	{
	case 'W':
	case 'w':
	moveUp();
	break;

	case 's':
	case 'S':
	moveDown();
	break;

	case 'D':
	case 'd':
	moveRight();

	break;

	case 'a':
	case 'A':
	moveLeft();
	break;

	default:
	cout << "Wrong" << endl;
	break;

	}

	if(solved() == 1){
	cout << "Solved." << endl;

	quit = true;
	}
	system("cls");
	}while(quit == false);
}else
for(int i = 0; i < arraySize; i++){
	for(int j = 0; j < arraySize; j++)
	cout << "  " << a[i][j];
	cout << endl << endl;
}
cout << "Did not scramble. Run program again.";


	return 0;
}


Thank you for reading.
Last edited on
Any hints will be awesome. I don't understand how to call a bool function to do the math because I only know that bools can only return true false so i don't understand how I can call it for both the string and scramble.

When I attempt to try any of the math I used in my second program and update the arrary, the assignment program crashes.
Last edited on
The move (with char parameter) is the heart of this game.

The way I read it is you have 1 function called Move which accepts a char parameter for the direction, and returns a boolean to indicate to the calling function if the move was successful or not. I notice you have seperate functions to perform your move.

Take a look at this simple example of the boolean part.

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

#include <iostream>
using namespace std;

bool Move(char direction);

int main()
{
	char direction;

	// direction would hold l, r, u or d

	if (Move(direction))
	{
		// we get here then move was successful
	}
	else
	{
		// we couldnt move.. invalid?
	}

	return 0;
}


bool Move( char direction )
{

	switch (direction)
	{
		case	'l':
			// left code, we attempt a move left, if we can
			// we move and finally return true;
		break;
		case	'r':
			// right code
		break;
		case	'u':
			// up code
		break;
		case	'd':
			// down code
		break;
		default:
			return false;
	}

	return false;	// if we get here we couldnt move
}


It seems my bool move char doesn't read my array so it crashes each time it runs the function.
I'm supposed to put the math in the bool , right? It should update the array every time the character is l u r d? But the bool doesn't read the Puzzle array that I initialize.
Last edited on

The bool is simply used to determine if the Move function was successful, i.e. if you passed 'u' for up and it couldn't move up then the move function would return false, otherwise it would perform the move and return true.

So like this then?
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
Puzzle::Puzzle(const string& s){
int a[4][4]=
        {
        {1,2,3,4},
        {5,6,7,8},
        {9,10,11,12},
        {13,14,15,' '}
        };
    int counter = 1;
    for(int i =0; i < 4; i++)
    for(int j =0; j < 4; j++)
    {
        a[i][j] = counter;
        counter++;
        a[3][3]=0;
    }
        i,j=3;
        correct=15;
    char direction;
    for(int beg=0;beg<s.length();beg++)
    {
        direction=s[beg];
        move(direction);
        if(move(direction))
        {
            if(direction='l')
            {

            }
            else if(direction='r')
            {

            }
            else if(direction='u')
            {

            }
            else if(direction='d')
            {

            }
        }
    }
}  // pass by reference to avoid copy


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
bool Puzzle::move(char direction)
{
	switch (direction)
	{
		case'l':
		    if( j+1<=4 && j>0 )
            {
		    return true;
		    }
            //lleft code
		break;
		case'r':
		    if( j+1<4 && j>=0 )
            {
		    return true;
            }
			// right code
		break;
		case'u':
		    if( i+1<4 && i>=0)
            {
		    return true;
            }
			// up code
		break;
		case'd':
		    if( i+1<=4 && i>0)
            {
            return true;
            }
		    // down code
		break;
		default:
			return false;
	}

	return false;
}


My update method crashes the assignment program. I'm not sure why.
I intended to copy the voids into the if statements to get them to move but it doesn't perform the move. Ah my logic is terrible.
Last edited on

Well, your move code could look something like 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

bool Puzzle::move(char c)
{
	switch (c)
	{
		case	'l':
			if (j + 1 < 4 && j >= 0)
			{

				a[i][j] = a[i][j + 1];
				a[i][j + 1] = 0;
				j += 1;
			}
		break;
		case	'r':
			if (j + 1 <= 4 && j > 0)
			{

				a[i][j] = a[i][j - 1];
				a[i][j - 1] = 0;
				j -= 1;
				return true;
			}
		break;
		case	'u':
			if (i + 1 < 4 && i >= 0)
			{
				a[i][j] = a[i + 1][j];
				a[i + 1][j] = 0;
				i += 1;
				return true;
			}
		break;
		case	'd':
			if (i + 1 <= 4 && i > 0)
			{

				a[i][j] = a[i - 1][j];
				a[i - 1][j] = 0;
				i -= 1;
				return true;
			}
		break;
		default:
			return false;	// invalid direction
	}

	// if we get here we were an invalid move
	return false;

}


In the main it would look something like:

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 "puzzle.h"


int main()
{

	Puzzle game;

	char direction;

	// here i assume direction has one of the
	// valid directions l, r, u, d

	if (game.move(direction))
	{
		// we were successful when moving
	}
	else
	{
		// invalid move.
	}


	return 0;
}
I have tried that and it still crashes or it never performs the task. How odd.
I would input 'l', 'u', 'd' it would output Nope as in was invalid.
But when I would input 'r', the exe would crash.
Last edited on
Topic archived. No new replies allowed.