1. ## Need some help...

My code manage to build without errors, but it crashes when I try to run it. Anybody can give me some help?

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <malloc.h>

void rubikdesign(int **rubikm);
void switchrowncolumn(int **rubikm, int r);
void rotateupperleft(int **rubikm);
void rotatelowerleft(int **rubikm);
void rotatemidclock(int **rubikm);
void rotatemidanticlock(int **rubikm);
void complete(int **rubikcc);

int main(void)
{
int i,j, **rubik, **rubikc, n;
char choice, mode;

rubikdesign(rubik);
complete(rubikc);

for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}

printf("Select the mode of solution:\n\n");
printf("1. Manual Mode\n");
printf("2. Automated Mode\n\n");
scanf("%c", &mode);

if(mode == '1')
{
do
{
for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}
printf("Manual Mode\n");
printf("Transform Operations\n");

printf("n0 = Switch rows for the nth column from the left, where n = 1,2,3,4\n");
printf(" 7 = Rotate Upper row left one step\n");
printf(" 1 = Rotate Lower row left one step\n");
printf(" 2 = Rotate the mid four 'squares/numbers' Clockwise one step\n");
printf(" 8 = Rotate the mid four 'squares/numbers' Anti-Clockwise one step\n");

printf("Enter Transform Operation (one at a time): ");
scanf("%c", &choice);

switch (choice)
{
case  'n':
printf("Enter column that will switch rows(n=1,2,3,4): ");
scanf("%d", &n);
switchrowncolumn(rubik, n);
break;
case  '7':
rotateupperleft(rubik);
break;
case  '1':
rotatelowerleft(rubik);
break;
case  '2':
rotatemidclock(rubik);
break;
case '8':
rotatemidanticlock(rubik);
break;
default:
printf("Invalid choice\n");
break;
}
} while(**rubik != (**rubikc));
}

else if(mode == '2')
{
return 0;
}

/*Free memory for each row*/
for(i=0;i<2;i++)
{
free(rubik[i]);
}

free(rubik);

return 0;
}

void rubikdesign(int **rubikm)
{
int i;

/*Memory allocation for row*/
rubikm = (int**)malloc(2*sizeof(int*));

/*Memory allocation for coloumn*/
for(i=0; i < 4; i++)
{
rubikm[i] = (int*)malloc(4*sizeof(int));
}

rubikm[0][0] = 4;
rubikm[0][1] = 7;
rubikm[0][2] = 1;
rubikm[0][3] = 6;
rubikm[1][0] = 2;
rubikm[1][1] = 3;
rubikm[1][2] = 8;
rubikm[1][3] = 5;

}

void switchrowncolumn(int **rubikm, int r)
{
int temp;

temp = rubikm[0][r];
rubikm[0][r] = rubikm[1][r];
rubikm[1][r] = temp;
}

void rotateupperleft(int **rubikm)
{
int temp;

temp = rubikm[0][0];
rubikm[0][0] = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[0][3];
rubikm[0][3] = temp;

}

void rotatelowerleft(int **rubikm)
{
int temp;

temp = rubikm[1][0];
rubikm[1][0] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[1][3];
rubikm[1][3] = temp;
}

void rotatemidclock(int **rubikm)
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[0][2];
rubikm[0][2] = temp;

}

void rotatemidanticlock(int **rubikm)
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[1][2];
rubikm[1][2] = rubikm[1][1];
rubikm[1][1] = temp;
}

void complete(int **rubikcc)
{
rubikcc[0][0] = 1;
rubikcc[0][1] = 2;
rubikcc[0][2] = 3;
rubikcc[0][3] = 4;
rubikcc[1][0] = 5;
rubikcc[1][1] = 6;
rubikcc[1][2] = 7;
rubikcc[1][3] = 8;
}```

2. First off, don't include malloc.h; stdlib.h is what you need to include to use malloc(). Also, you shouldn't cast the return value of malloc() as it's unnecessary.

Code:
```	/*Memory allocation for row*/
rubikm = (int**)malloc(2*sizeof(int*));```
You are allocating space for an array of integer pointers. This array is of size 2.
Code:
```	/*Memory allocation for coloumn*/
for(i=0; i < 4; i++)
{
rubikm[i] = (int*)malloc(4*sizeof(int));
}```
The array you allocated is of size 2, yet you are iterating through it as if it were size 4.

Also, rubikm will not be returned back to the calling function. It may be difficult for you to understand since you are using a double pointer, but you are essentially doing this:
Code:
```void foo(int x)
{
x = 5;
}

int main(void)
{
int x;
foo(x);
printf("x = %d\n", x);  // x does not equal 5 here since it was passed by value
}```
You are passing the double pointer by value, so the memory that you allocate in the function is lost since the caller's pointer will not point to that memory.

3. ## So to solve the problem....

Can anybody give me some pointers on how to pass back and forth between 2-d pointers?

4. Originally Posted by darkconvoy
Can anybody give me some pointers on how to pass back and forth between 2-d pointers?
How about returning the same pointer that you passed to the function, as in
Code:
`rubik = rubikdesign(rubik);`

5. ## New problem

This set of code has some problems passing back and forth the 2D pointer through the functions [The program says incompatible pointer type]:

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void rubikdesign(int **rubikm);
void switchrowncolumn(int **rubikm, int r);
void rotateupperleft(int **rubikm);
void rotatelowerleft(int **rubikm);
void rotatemidclock(int **rubikm);
void rotatemidanticlock(int **rubikm);
void complete(int **rubikcc);

int main(void)
{
int i,j, **rubik, **rubikc, n;
char choice, mode;

rubikdesign(&rubik);
complete(&rubikc);

for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}

printf("Select the mode of solution:\n\n");
printf("1. Manual Mode\n");
printf("2. Automated Mode\n\n");
scanf("%c", &mode);

if(mode == '1')
{
do
{
for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}
printf("Manual Mode\n");
printf("Transform Operations\n");

printf(" 0 = Switch rows for the nth column from the left, where n = 1,2,3,4\n");
printf(" 7 = Rotate Upper row left one step\n");
printf(" 1 = Rotate Lower row left one step\n");
printf(" 2 = Rotate the mid four 'squares/numbers' Clockwise one step\n");
printf(" 8 = Rotate the mid four 'squares/numbers' Anti-Clockwise one step\n");

printf("Enter Transform Operation (one at a time): ");
scanf("%c", &choice);

switch (choice)
{
case  '0':
printf("Enter nth column that will switch rows(n=1,2,3,4): ");
scanf("%d", &n);
switchrowncolumn(&rubik, n);
break;
case  '7':
rotateupperleft(&rubik);
break;
case  '1':
rotatelowerleft(&rubik);
break;
case  '2':
rotatemidclock(&rubik);
break;
case '8':
rotatemidanticlock(&rubik);
break;
default:
printf("Invalid choice\n");
break;
}
} while(**rubik != (**rubikc));
}

else if(mode == '2')
{
return 0;
}

/*Free memory for each row*/
for(i=0;i<2;i++)
{
free(rubik[i]);
}

free(rubik);

return 0;
}

void rubikdesign(int **rubikm)
{
int i;

/*Memory allocation for row*/
rubikm = (int**)malloc(2 * sizeof(int*));

/*Memory allocation for coloumn*/
for(i=0; i < 2; i++)
{
rubikm[i] = (int*)malloc(4*sizeof(int));
}

rubikm[0][0] = 4;
rubikm[0][1] = 7;
rubikm[0][2] = 1;
rubikm[0][3] = 6;
rubikm[1][0] = 2;
rubikm[1][1] = 3;
rubikm[1][2] = 8;
rubikm[1][3] = 5;

}

void switchrowncolumn(int **rubikm, int r)
{
int temp;

temp = rubikm[0][r-1];
rubikm[0][r-1] = rubikm[1][r-1];
rubikm[1][r-1] = temp;
}

void rotateupperleft(int **rubikm)
{
int temp;

temp = rubikm[0][0];
rubikm[0][0] = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[0][3];
rubikm[0][3] = temp;

}

void rotatelowerleft(int **rubikm)
{
int temp;

temp = rubikm[1][0];
rubikm[1][0] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[1][3];
rubikm[1][3] = temp;
}

void rotatemidclock(int **rubikm)
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[0][2];
rubikm[0][2] = temp;

}

void rotatemidanticlock(int **rubikm)
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[1][2];
rubikm[1][2] = rubikm[1][1];
rubikm[1][1] = temp;
}

void complete(int **rubikcc)
{
rubikcc[0][0] = 1;
rubikcc[0][1] = 2;
rubikcc[0][2] = 3;
rubikcc[0][3] = 4;
rubikcc[1][0] = 5;
rubikcc[1][1] = 6;
rubikcc[1][2] = 7;
rubikcc[1][3] = 8;
}```

6. ## Help me anyone..??

Can anyone help me with my code?

7. The program is for a Rubik's puzzle of some kind, but not for a Rubik's cube?

Tell us what the heck you're trying to do here.

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void rubikdesign(int **);

void switchrowncolumn(int **, int r);
void rotateupperleft(int **);
void rotatelowerleft(int **);
void rotatemidclock(int **);
void rotatemidanticlock(int **);
void complete(int **);

int main(void)
{
int i,j, **rubik, **rubikc, n;
char choice, mode;

/*   *rubik = malloc(2 * sizeof(int*));
for(i = 0; i < 4; i++)
rubik[i] = malloc(4 * sizeof(int));
*/

rubikdesign(rubik);
complete(rubikc);

for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}

printf("\n\n\nSelect the mode of solution:\n\n");
printf("1. Manual Mode\n");
printf("2. Automated Mode\n\n");
scanf("%c", &mode);

if(mode == '1')
{
do
{
for(i=0; i<2; i++)
{
for(j=0; j<4; j++)
{
printf("%d", rubik[i][j]);
}
printf("\n");
}
printf("Manual Mode\n");
printf("Transform Operations\n");

printf(" 0 = Switch rows for the nth column from the left, where n = 1,2,3,4\n");
printf(" 7 = Rotate Upper row left one step\n");
printf(" 1 = Rotate Lower row left one step\n");
printf(" 2 = Rotate the mid four 'squares/numbers' Clockwise one step\n");
printf(" 8 = Rotate the mid four 'squares/numbers' Anti-Clockwise one step\n");

printf("Enter Transform Operation (one at a time): ");
scanf("%c", &choice);

switch (choice)
{
case  '0':
printf("Enter nth column that will switch rows(n=1,2,3,4): ");
scanf("%d", &n);
switchrowncolumn(rubik, n);
break;
case  '7':
rotateupperleft(rubik);
break;
case  '1':
rotatelowerleft(rubik);
break;
case  '2':
rotatemidclock(rubik);
break;
case '8':
rotatemidanticlock(rubik);
break;
default:
printf("Invalid choice\n");
break;
}
} while(**rubik != (**rubikc));  //you can't do this. You have to
} //either compare element by element, or work out something else.

else if(mode == '2')
{
return 0;   //I don't understand this return
}

/*Free memory for each row*/
for(i=0;i<2;i++)
{
free(rubik[i]);
}

free(rubik);

return 0;
}

void rubikdesign(int **rubikm)
{
int i;

/*Memory allocation for row*/
*rubikm = malloc(2 * sizeof(int*));

/*Memory allocation for coloumn*/
for(i=0; i < 2; i++)
{
rubikm[i] = malloc(4*sizeof(int));
}

rubikm[0][0] = 4;
rubikm[0][1] = 7;
rubikm[0][2] = 1;
rubikm[0][3] = 6;
rubikm[1][0] = 2;
rubikm[1][1] = 3;
rubikm[1][2] = 8;
rubikm[1][3] = 5;

}
/* if you want to work with rows and columns, you have to pass into the
function all dimension sizes, except for the first one.
*/
void switchrowncolumn(int *rubikm[4], int r)
{
int temp;

temp = rubikm[0][r-1];
rubikm[0][r-1] = rubikm[1][r-1];
rubikm[1][r-1] = temp;
}

void rotateupperleft(int *rubikm[4])
{
int temp;

temp = rubikm[0][0];
rubikm[0][0] = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[0][3];
rubikm[0][3] = temp;

}

void rotatelowerleft(int *rubikm[4])
{
int temp;

temp = rubikm[1][0];
rubikm[1][0] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[1][3];
rubikm[1][3] = temp;
}

void rotatemidclock(int *rubikm[4])
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[1][1];
rubikm[1][1] = rubikm[1][2];
rubikm[1][2] = rubikm[0][2];
rubikm[0][2] = temp;

}

void rotatemidanticlock(int *rubikm[4])
{
int temp;

temp = rubikm[0][1];
rubikm[0][1] = rubikm[0][2];
rubikm[0][2] = rubikm[1][2];
rubikm[1][2] = rubikm[1][1];
rubikm[1][1] = temp;
}

/* You never malloc'd any memory for rubikcc ! */
void complete(int *rubikcc[4])
{
rubikcc[0][0] = 1;
rubikcc[0][1] = 2;
rubikcc[0][2] = 3;
rubikcc[0][3] = 4;
rubikcc[1][0] = 5;
rubikcc[1][1] = 6;
rubikcc[1][2] = 7;
rubikcc[1][3] = 8;
}```
In rubikdesign() I can pass in a **pointer, just as a **pointer, because the array hasn't been malloc'd yet. Rows and columns are not a concern yet.

8. ## The purpose of my code..

The code creates one 2 rows and 4 columns rubik cube which can be solved by using one of the five different function (refer to the functions between rubikdesign() and complete()).

9. I've only seen the traditional 4 X 4 X 6 sided original Rubik's cube, so I was curious.

the code just creates a simple 2 x 4 rubic cube in 2D

11. ## New problem...

Ok, I manage to get the code working now, but now I have a new problem. I want to create an automatic mode so that the rubik cube can solve itself and shows the sequence of the operations used. Any ideas?

12. Do you know the rules to follow to always solve the puzzle, from any position, yourself?

If so, put down the steps into pseudo code, and try then making that pseudo code, into a working function(s).

If you don't know the steps to solve the puzzle yourself, then search for a thread called "Rubik's cube Algorithm", and see my program there.

That could be the skeleton to your Rubik's cube program.

I found it, so I thought I'd just post it:
Code:
```/* Will solve via brute force, the 8 tile 2D "rubik's cube" puzzle, when finished

Status: just started 7/11/08
*/

#include <stdio.h>

void copyB(int);
int move1(int);
int move2(int);
int move3(int);

void showB(int);
int isSolved(int);

int b[2][4][20];    //b is shorthand for the board
int t[1][4];        //t is a temporary holding row
int line[20];       //the line of moves that are played

int main(void)  {
int i, r, row, c, col, move, deep, depth, solved, reset, gar;
// test right shift
/*   b[0][0][0] = 2; b[0][1][0] = 3; b[0][2][0] = 4; b[0][3][0] = 1;
b[1][0][0] = 7; b[1][1][0] = 6; b[1][2][0] = 5; b[1][3][0] = 8;
*/
// test row swap
/*   b[0][0][0] = 8; b[0][1][0] = 7; b[0][2][0] = 6; b[0][3][0] = 5;
b[1][0][0] = 1; b[1][1][0] = 2; b[1][2][0] = 3; b[1][3][0] = 4;
*/
// test Rotate 4 inner tiles
/*   b[0][0][0] = 1; b[0][1][0] = 3; b[0][2][0] = 6; b[0][3][0] = 4;
b[1][0][0] = 8; b[1][1][0] = 2; b[1][2][0] = 7; b[1][3][0] = 5;
*/
// test depth of 2, solution 1 + 2
/*   b[0][0][0] = 7; b[0][1][0] = 6; b[0][2][0] = 5; b[0][3][0] = 8;
b[1][0][0] = 2; b[1][1][0] = 3; b[1][2][0] = 4; b[1][3][0] = 1;
*/
//test depth of 2, solution 2 + 3  no depth=2 solution found for 1+3
b[0][0][0] = 8; b[0][1][0] = 2; b[0][2][0] = 7; b[0][3][0] = 5;
b[1][0][0] = 1; b[1][1][0] = 3; b[1][2][0] = 6; b[1][3][0] = 4;

//test depth of , solution
/*   b[0][0][0] = ; b[0][1][0] = 2; b[0][2][0] = 1; b[0][3][0] = 4;
b[1][0][0] = 8; b[1][1][0] = 7; b[1][2][0] = 6; b[1][3][0] = 5;
*/
printf("\n Starting position:\n");
showB(0);
//getch();
depth = deep = solved = reset = 0;

do  {
move = 1; depth = 2;

while(1)  {   // this is the main loop, for now
++deep;
if(move == 1)
solved = move1(deep);
else if(move == 2)
solved = move2(deep);
else
solved = move3(deep);

if(solved)
break;

if(reset)  {    //depth was reset, move needs to reset to 1 again
move = 1;
reset = 0;
continue;
}

if(deep >= depth)  {
line[deep-1] = 0;
deep = depth - 1;
if(++move > 3) {
deep -= 1;
move = line[deep] + 1;
if(move > 1)
reset = 1;
}
}
}

}while(!solved);

printf("\n\n\t Press Enter to Quit\n ");
gar = getchar(); gar++;
return 0;
}
void copyB(int d)  {  //copy the old board position, into the new depth
int r, c, temp;

for(r = 0; r < 2; r++)
for(c = 0; c < 4; c++)
b[r][c][d] = b[r][c][d-1];
}
int move1(int d)  {  //shifts all numbers one column to the right &  wraps
int r, c, solved, temp;
solved = 0;
printf("\n Right shift:");
copyB(d);
//showB(d);
//++d;

for(r = 0; r < 2; r++)  {
temp = b[r][3][d];
for(c = 2; c >-1 ; c--)
b[r][c+1][d] = b[r][c][d];
b[r][0][d] = temp;
}

showB(d);
line[d-1] = 1;
solved = isSolved(d);

return solved;
}
int move2(int d)  { //swaps rows
int r, c, solved;
solved = 0;
printf("\n Swap rows:");
copyB(d);
//showB(d);

for(c = 0; c < 4; c++)  {
t[0][c] = b[0][c][d];
b[0][c][d] = b[1][c][d];
b[1][c][d] = t[0][c];
}

showB(d);
line[d-1] = 2;
solved = isSolved(d);

return solved;
}
int move3(int d) { //turns the 4 inner tiles, clockwise
int r, c, solved, temp;
solved = 0;
printf("\n Rotate 4 inner tiles:");
copyB(d);
//showB(d);

temp = b[0][1][d];
b[0][1][d] = b[1][1][d];
b[1][1][d] = b[1][2][d];
b[1][2][d] = b[0][2][d];
b[0][2][d] = temp;

showB(d);
line[d-1] = 3;
solved = isSolved(d);

return solved;
}
void showB(int d)   {
int r, c, tab;
printf("\n");
for(tab = 0; tab < d; tab++)
putchar('\t');
for(r = 0; r < 2; r++) {
for(c = 0; c < 4; c++)
printf(" %d", b[r][c][d]);
putchar('\n');
for(tab = 0; tab < d; tab++)
putchar('\t');
}
}
int isSolved(int d)  {
int i, gar;
int done = 0;
if(b[0][0][d]==1 && b[0][1][d]==2 && b[0][2][d]==3 && b[0][3][d]==4)
if(b[1][0][d]==8 && b[1][1][d]==7 && b[1][2][d]==6 && b[1][3][d]==5)  {
done = 1;
printf("\n\n\t\t It's solved!");
showB(d);
printf("\t Line: ");
for(i = 0; i < d; i++)
printf(" %d", line[i]);

//printf("\n\t Press Enter to Continue");
//gar = getchar(); ++gar;
}

return done;
}

This shows a very basic graphic of the various depths and the moves being made, to a
depth of 2 ply. The leftmost board being the starting board, and is at depth 0. The next board column to the right is depth 1. Going right one more board width, the boards for depth = 2 are shown (if the search went that far), etc.

So it's the search tree, with the root on the far left, and the leaves to the right side.

Starting
board:
nnnn
nnnn
Description of move 1 at depth 1:
nnnn
nnnn
Description of move 1 at depth 2:
nnnn
nnnn
Description of move 2 at depth 2:
nnnn
nnnn
Description of move 3 at depth 2:
nnnn
nnnn
Description of move 2 at depth 1:
nnnn
nnnn

etc.

I'm a hobby programmer, so you may very well find something you like better. I'd suggest this as a good starting off point or food for thought, rather than a hard and fast "this is the way it should be done" kind of thing.

There are several ways to search through a tree, this is just one that felt right (DFS), in this instance, to me.

The above program handles 2 ply searches, but not 3 or more. The part after

Code:
if(solved)
break;
needs to be adjusted to handle multiple "back ups" in ply. After moves of 1, 3, 3, you need to back up 2 ply, for instance, not just one. That makes your next move 2.

The program prints the board array now, but even more helpful is getting it to print the line of moves as it goes through it's search.

If you change the lines array to print < deep right after the if(solved) break, line of code, then you can get a better reference for debugging the DFS.

The moves should be:
1
11
111
112
113
12
121
122
123
13
131
132
133
2
21
211
212
213
22
221
222
223
23
231
232
233

Which will solve this position:
b[0][0][0] = 8; b[0][1][0] = 3; b[0][2][0] = 2; b[0][3][0] = 5;
b[1][0][0] = 1; b[1][1][0] = 6; b[1][2][0] = 7; b[1][3][0] = 4;

Since this is a student's project, I'm going to refrain from posting any more code on this.

Original starting position of:

2684
1375

the first solution found for it was: 3 3 1 3 1 1 1```