
// Rubik's Cube Screensaver
// (C) 2005, Akop Karapetyan
//
// http://www.akop.org
//

#include "Cube.h"

void cubeSolve(int nvCube[6][CUBE_NSQUARES][CUBE_NSQUARES])
{
	for (int i = 0; i < 6; i++)
		for (int j = 0; j < CUBE_NSQUARES; j++)
			for (int k = 0; k < CUBE_NSQUARES; k++)
				nvCube[i][j][k] = i;
}

// nStackID:
//   0: bottom stack (btm-to-top)
//   1: middle stack (btm-to-top)
//   2: top stack    (btm-to-top)
//   3: back slice   (bk-to-frnt)
//   4: middle slice (bk-to-frnt)
//   5: front slice  (bk-to-frnt)
//   6: left slice   (lt-to-rt)
//   7: middle slice (lt-to-rt)
//   8: right slice  (lt-to-rt)
//
void cubeTwist(int nvCube[6][CUBE_NSQUARES][CUBE_NSQUARES], int nStackID, int nCount)
{
	int i, j, c;
	UINT nvFacet[CUBE_NSQUARES], nvSide[CUBE_NSQUARES][CUBE_NSQUARES];

	switch(nStackID)
	{
	case 0:  // bottom stack; bottom-to-top stacks

		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_BOTTOM][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_BOTTOM][i][j] = nvSide[j][CUBE_NSQUARES - i - 1];
		}

		goto btt_common;

	case 2: // top stack; bottom-to-top stacks

		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_TOP][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_TOP][i][j] = nvSide[j][CUBE_NSQUARES - i - 1];
		}

		goto btt_common;

	case 1: // middle stack; bottom-to-top stacks
btt_common:

		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				nvFacet[i] = nvCube[FACE_FRONT][nStackID][i];

			for (i = 0; i < CUBE_NSQUARES; i++)
			{
				nvCube[FACE_FRONT][nStackID][i] = nvCube[FACE_LEFT][nStackID][i];
				nvCube[FACE_LEFT][nStackID][i] = nvCube[FACE_BACK][nStackID][i];
				nvCube[FACE_BACK][nStackID][i] = nvCube[FACE_RIGHT][nStackID][i];
				nvCube[FACE_RIGHT][nStackID][i] = nvFacet[i];
			}
		}
		break;

	case 3:  // back slice; back-to-front slices 

		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_BACK][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_BACK][i][j] = nvSide[j][CUBE_NSQUARES - i - 1];
		}

		goto btf_common;

	case 5:  // front slice; back-to-front slices 
		
		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_FRONT][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_FRONT][i][j] = nvSide[CUBE_NSQUARES - j - 1][i];
		}

		goto btf_common;

	case 4:  // middle slice; back-to-front slices 
btf_common:

		nStackID -= 3;
		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				nvFacet[i] = nvCube[FACE_TOP][nStackID][i];

			for (i = 0; i < CUBE_NSQUARES; i++)
			{
				nvCube[FACE_TOP][nStackID][i] = nvCube[FACE_RIGHT][CUBE_NSQUARES - i - 1][CUBE_NSQUARES - nStackID - 1];
				nvCube[FACE_RIGHT][CUBE_NSQUARES - i - 1][CUBE_NSQUARES - nStackID - 1] = nvCube[FACE_BOTTOM][nStackID][CUBE_NSQUARES - i - 1];
				nvCube[FACE_BOTTOM][nStackID][CUBE_NSQUARES - i - 1] = nvCube[FACE_LEFT][i][nStackID];
				nvCube[FACE_LEFT][i][nStackID] = nvFacet[i];
			}
		}
		break;

	case 6:  // left slice; left-to-right slices 

		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_LEFT][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_LEFT][i][j] = nvSide[j][CUBE_NSQUARES - i - 1];
		}

		goto ltr_common;

	case 8:  // right slice; left-to-right slices 
		
		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvSide[i][j] = nvCube[FACE_RIGHT][i][j];

			for (i = 0; i < CUBE_NSQUARES; i++)
				for (j = 0; j < CUBE_NSQUARES; j++)
					nvCube[FACE_RIGHT][i][j] = nvSide[CUBE_NSQUARES - j - 1][i];
		}

		goto ltr_common;

	case 7:  // middle slice; left-to-right slices 
ltr_common:

		nStackID -= 6;
		for (c = 0; c < nCount; c++)
		{
			for (i = 0; i < CUBE_NSQUARES; i++)
				nvFacet[i] = nvCube[FACE_FRONT][i][nStackID];

			for (i = 0; i < CUBE_NSQUARES; i++)
			{
				nvCube[FACE_FRONT][i][nStackID] = nvCube[FACE_TOP][CUBE_NSQUARES - i - 1][nStackID];
				nvCube[FACE_TOP][CUBE_NSQUARES - i - 1][nStackID] = nvCube[FACE_BACK][CUBE_NSQUARES - i - 1][CUBE_NSQUARES - nStackID - 1];
				nvCube[FACE_BACK][CUBE_NSQUARES - i - 1][CUBE_NSQUARES - nStackID - 1] = nvCube[FACE_BOTTOM][i][nStackID];
				nvCube[FACE_BOTTOM][i][nStackID] = nvFacet[i];
			}
		}
		break;
	}
}
