the 2x2x2 Cube Solver
.................................


CONTENTS:
* COMMAND LINE INTERFACE DOCUMENTATION
* COMPILING
* SOURCE CODE DOCUMENTATION
* CONTACT INFORMATION



COMMAND LINE INTERFACE DOCUMENTATION
....................................


If your cube looks like this:

top
      Y Y
      B O
 O R  W G  Y G  R B
 O G  R Y  B O  W W
      W R
      G B
bottom

then the command-line looks like this:

mcube YYBOOROGWGRYYGBORBWWWRGB

The output is a series of moves which can be deciphered as such:

UL -> top left
UR -> top right
DL -> bottom left
DR -> bottom right
LU -> left up
LD -> left down
RU -> right up
RD -> right down
FC -> front clockwise
FA -> front counterclockwise
BC -> back clockwise (looking from front)
BA -> back counterclockwise (looking from front)



COMPILING
.........


win32: (MS Visual Studio)
  nmake -f makefile.win32
*nix: (GCC g++)
  make

Here's a list of files that should be included:
  cu2.h             -> cube class header
  cu2.cpp           -> cube class
  main.cpp          -> main UI
  Makefile          -> make script for *nix
  makefile.win32    -> make script for win32
  readme.txt        -> docs (this file)



SOURCE CODE DOCUMENTATION
.........................


first thing, remember to
 #include "cu2.h"

Now then, you can instantiate a new cube quite simply like this

cu2 mycube;

It will automatically reset the new cube in the constructor...
Now that you have mycube, you can do things with it;)

mycube.resetcube(); to reset the cube
  (returns nothing)

mycube.scramblecube(); to scramble the cube model
  (returns nothing)

mycube.solvecube(); to solve the cube
  (returns an int which is the same as mycube.erval)

mycube.issolved(); to see if a cube is solved (see definition of solved below)
  (returns a bool true if solved or false if not..

mycube.UL(); - rotate top left
       UR(); - rotate top right
       DL(); - bottom left
       DR(); - etc...
       LU(); - left up
       LD();
       RU();
       RD();
       FC(); - front clockwise
       FA(); - front counterclockwise
       BC();
       BA();
       CL(); - whole cube left
       CR();
       CU();
       CD();
       CC();
       CA();

Also you can rotate slices with these calls:
mycube.slice_l(x); - rotate slice x left
       slice_r(x); - etc...
       slice_u(x);
       slice_d(x);
       slice_c(x);
       slice_a(x);

more things to do:

mycube.cube[x][y][z] = color;
  -  to repaint a face
*mycube.face(x, y, z) = color;
  - another way to repaint a face

face = mycube.cube[x][y][z];
  -  to read an indidual face
face = *mycube.face(x, y, z);
  - another way to read an individual face

if (mycube == yourcube)
  - an overloaded == (and !=) comparison...

numberofcubes = mycube.numcubes
  - to see how many instantiated cubes there are
numberofcubes = mcube::numcubes
  - another way

mycube.domoves(string s); - to execute a series of moves
  - see notes on string format

mycube.dosolution(); - to execute the solution
  (won't do anything until mycube.solvecube() is called)

Other things in the mcube class (take them or leave them):

string shortersolution = mycube.concise(string s);
  - to strip redundant moves from a string
  (there's an optional second parameter, bool b, which, if true, will affect the
  mov[] array as well)

int mycube.erval
  - if there was an error during solvecube() it will be set here

int mycube.shorten
  - set this to one of the shorten constants to define how much solvecube()
  should try to find shorter solutions...

string mycube.solution
  - a formated string containing the solution for the cube (set by solvecube())

int mycube.fx, fy & fz
  - coordinates for a cubelet set by find* functions

To find a given cubelet, use these functions:

mycube.findcorner_c(int a, int b, int c); find given corner with parameters given in clockwise order
       findcorner_a(int a, int b, int c); find corner with parameters in counterclockwise order
       findcorner(int a, int b, int c); just find the given corner (any order)

string formatting functions -
  there are 3 general formatting notations (described in the notes)

string mcube::std_to_metr(string s)
  converts a "standard" string to "metric"
string mcube::metr_to_std(string s)
  converts a "metric" string to "standard"
string mcube::std_to_rel(string s)
  converts a "standard" string to "relative"
string mcube::rel_to_std(string s)
  converts a "relative" string to "standard"
string mcube::metr_to_rel(string s)
  converts a "metric" string to "relative"
string mcube::rel_to_metr(string s)
  converts a "relative" string to "metric"

Constants:

mcube::NEGX = -1
  negative X axis (left)
mcube::POSX = 1
  positive X axis (right)
mcube::NEGY = -2
  negative Y axis (bottom)
mcube::POSY = 2
  positive Y axis (top)
mcube::NEGZ = -3
  negative Z axis (front/near)
mcube::POSZ = 3
  positive Z axis (back/far)

Other miscellaneous class items...

bool mycube.inited - whether the cube has been initialized
  (generally don't need to mess with it.. the constructor, resetcube() and
  scramblecube() will set this to true)

static const char mcube::version - the version of the solver
  if for whatever reason you want to know what version it is...

static const int mcube::N = 2
  the width of the dimensions (e.g., NxNxN).. many of the functions in the
  solver are generalized for any size cube...

void mycube.copytemp(c, t)
  copies the array c into t (where c and t are of size [N+2][N+2][N+2])

and the various macros:

DOMOVES(a, b) - does the sequence of moves (b) and then appends string a with b.
  - for those of you who want it easier when toying with findsolution()...
  (instead of a += "UL.LU."; UL(); LU(); you can just do DOMOVES(a, "UL.LU.");)

GETCORNER_C(a,b,c,x,y,z,f)
  f = findcorner_c(a, b, c); x = fx; y = fy; z = fz
GETCORNER_A(a,b,c,x,y,z,f)
  f = findcorner_a(a, b, c); x = fx; y = fy; z = fz

and finally, for solidarity, the private class members and methods which you
can't access directly:

string findsolution(); - contains the actual solver algorithm - but note, this
  only works when cube[][][] has been specially prepared (arranged to match a
  specific color scheme), which is why it is private (it is used from within
  solvecube(), which has a lot of code to prepare the cube properly).

Notes:
2. overloaded == comparison: this only checks if 2 cubes have the same colors in
   the same position, however if one cube is just the second cube but, say,
   rotated to the left, then the == comparison will return false.
4. formatted strings: the "standard" string notation (used by default) is like
   so: <slice><dir>.
   so for example, "top left, inner back counterclockwise" would look like this:
   "UL.bA."
   the same move in "metric" notation is:
   "4L.3A." (faces DduU=1234, LlrR=1234, FfbB=1234)
   the same move in "relative" notation is:
   "U+.b-." (directions L=+, R=-, D=+, U=-, C=+, A=-)
   also, halfturns ONLY apply to relative or standard strings (in metric it
   would be ambiguous)



CONTACT INFORMATION
...................


Well, I hope that all helped.  If you are still baffled, drop me an email.

 - Eric, root@wrongway.org
