Program 1

This program prompts the user for next boards and creates the database of board pairs.

#include <iostream.h>

#include <stdlib.h>

#include <fstream.h>

//Define the state structure

struct state { int b[9]; };

//Output file that contains start boards and defined next boards

ofstream fout("create.dat");

//Number of Boards to be Questioned

int maxNumberBoards;

int totalDefined = 0;

//Array of states that are prompted to user

state s[1000];

//when displaying the boards, 0=nothing, 1=X 2=O

char sym[3] = {' ','X','O'};

//When choosing the placement of the mark, this array translates

//the number from the numberpad to the board array number

int NUMBERPAD[10] = {0,6,7,8,3,4,5,0,1,2};

//Permutations on the board

void rotate(int);

void flipHoriz(int);

void flipVert(int);

void flipLLUR(int);

void flipULLR(int);

//Checks if there are any boards that are exactly equal to INT

int anySimilar(int);

//Checks if board at location INT is exactly equal to INT

int equals(int, int);

//Checks if there are any other boards that match INT (w/permutations)

int anyOthers(int);

//Checks if the board INT is done (win by either party)

int checkdone(int);

//Checks if INT is equal to INT (w/rotations)

int completeEquality(int,int);

/******************************************************************/

int main() {

cout << "Number of boards to question:";

cin >> maxNumberBoards;

srand(maxNumberBoards); //Seed random with # board input

//Prompt for maxNumberBoards boards

for(int i = 0; i < maxNumberBoards; i++)

{ int numberX, numberO;

do {

//Initialize the board to all empty spaces

for(int b_init = 0; b_init < 9; b_init++)

{s[i].b[b_init] = 0;}

//Randomly choose the number of X's and O's

numberX = rand() % 4;

numberO = numberX - rand() % 2;

if (numberX == 4 && numberO == 4)

{numberO = 3;}

//Place the X's on the board

for(int Xloop = 0; Xloop < numberX; Xloop++)

{int pos = rand() % 9; //pick a pos

while (s[i].b[pos] != 0) //until it is

{pos = rand() % 9;} //an open space

s[i].b[pos] = 1;} //mark it

//Place the O's on the board

for(int Oloop = 0; Oloop < numberO; Oloop++)

{int pos = rand() % 9; //pick a pos

while (s[i].b[pos] != 0) //until it is

{pos = rand() % 9;} //an open space

s[i].b[pos] = 2;} //mark it

} while (anyOthers(i) == 1 || checkdone(i) == 1);

//Keep trying to generate random boards until a completly unique

//board is generated.

//Display the generated board

cout << "Board #:" << i << endl;

cout << sym[s[i].b[0]] << '|';

cout << sym[s[i].b[1]] << '|';

cout << sym[s[i].b[2]] << endl;

cout << "-+-+-" << endl;

cout << sym[s[i].b[3]] << '|';

cout << sym[s[i].b[4]] << '|';

cout << sym[s[i].b[5]] << endl;

cout << "-+-+-" << endl;

cout << sym[s[i].b[6]] << '|';

cout << sym[s[i].b[7]] << '|';

cout << sym[s[i].b[8]] << endl;

int place; //The number hit on the numberpad

int numType; //The type of mark that is to be put down

//Prompt for the placement of the mark, and also determine mark type

cout << "Placement of ";

if (numberX == numberO || numberO == -1)

{cout << "*X*";

numType = 1; }

else

{cout << "*O*";

numType = 2; }

cin >> place;

int boardsDefined = 0; //Number of actual boards defined

boardsDefined++; //regular board

//Copy the board 8 times for the permutations

for(int k = 0; k < 9; k++)

{s[900].b[k] = s[i].b[k];

s[901].b[k] = s[i].b[k];

s[902].b[k] = s[i].b[k];

s[903].b[k] = s[i].b[k];

s[904].b[k] = s[i].b[k];

s[905].b[k] = s[i].b[k];

s[906].b[k] = s[i].b[k];

s[907].b[k] = s[i].b[k];}

//The 8 permutations

rotate(900);

rotate(901); rotate(901);

rotate(902); rotate(902); rotate(902);

flipHoriz(903);

flipVert(904);

flipLLUR(905);

flipULLR(906);

//Check the 8 permutations, if each is unique, add it to total

for(int ck = 900; ck < 907; ck++)

{ if (anySimilar(ck) == -1)

{boardsDefined++;} }

fout << boardsDefined << '#';

totalDefined = totalDefined + boardsDefined;

//Output starting board

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ':';

//Copy starting board to temporary spot 900

for(int j = 0; j < 9; j++)

{s[900].b[j] = s[i].b[j];}

//Check for Horizontal Symetry in the board

int HorizSym = -1;

flipHoriz(900);

if (equals(900,i) == 1)

HorizSym = 1;

flipHoriz(900);

//Check for Vertical Symetry in the board

int VertSym = -1;

flipVert(900);

if (equals(900,i) == 1)

VertSym = 1;

flipVert(900);

//Check for Lower-Left Upper-Right Symetry

int LLURSym = -1;

flipLLUR(900);

if (equals(900,i) == 1)

LLURSym = 1;

flipLLUR(900);

//Check for Upper-Left Lower-Right Symetry

int ULLRSym = -1;

flipULLR(900);

if (equals(900,i) == 1)

ULLRSym = 1;

flipULLR(900);

//Place the mark on the board

s[i].b[NUMBERPAD[place]] = numType;

//Output the marked board

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ',';

//If the board had Horizontal Symetry, generate Symetrical board

if (HorizSym == 1)

{ flipHoriz(i);

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ',';

flipHoriz(i); }

//If the board had Vertical Symetry, generate Symetrical board

if (VertSym == 1)

{ flipVert(i);

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ',';

flipVert(i); }

if (LLURSym == 1)

{ flipLLUR(i);

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ',';

flipLLUR(i); }

if (ULLRSym == 1)

{ flipULLR(i);

fout << s[i].b[0] << s[i].b[1] << s[i].b[2];

fout << s[i].b[3] << s[i].b[4] << s[i].b[5];

fout << s[i].b[6] << s[i].b[7] << s[i].b[8] << ',';

flipULLR(i); }

//Write the terminal symbols

fout << "//" << endl;

//Remove the mark from the board so that future boards may check

//against it for uniqueness

s[i].b[NUMBERPAD[place]] = 0;

 

} //end of asking for a bunch of boards loop

fout.close(); //close the output file

 

//Results

cout << "Defined a total of " << totalDefined << " boards ";

cout << "from " << maxNumberBoards << endl;

} //end main()

/**********************************************************************/

//Checks if state w is a terminal board, due to win. 1=done, 0=not-done

int checkdone(int w) {

if (s[w].b[0] != 0 && s[w].b[0] == s[w].b[1] && s[w].b[1] == s[w].b[2])

{return 1;}

if (s[w].b[3] != 0 && s[w].b[3] == s[w].b[4] && s[w].b[4] == s[w].b[5])

{return 1;}

if (s[w].b[6] != 0 && s[w].b[6] == s[w].b[7] && s[w].b[7] == s[w].b[8])

{return 1;}

if (s[w].b[0] != 0 && s[w].b[0] == s[w].b[3] && s[w].b[3] == s[w].b[6])

{return 1;}

if (s[w].b[1] != 0 && s[w].b[1] == s[w].b[4] && s[w].b[4] == s[w].b[7])

{return 1;}

if (s[w].b[2] != 0 && s[w].b[2] == s[w].b[5] && s[w].b[5] == s[w].b[8])

{return 1;}

if (s[w].b[0] != 0 && s[w].b[0] == s[w].b[4] && s[w].b[4] == s[w].b[8])

{return 1;}

if (s[w].b[6] != 0 && s[w].b[6] == s[w].b[4] && s[w].b[4] == s[w].b[2])

{return 1;}

return 0;

}

//Rotate state w by 90 degrees clockwise

void rotate(int w) {

int b0 = s[w].b[0]; int b1 = s[w].b[1]; int b2 = s[w].b[2];

int b3 = s[w].b[3]; int b4 = s[w].b[4]; int b5 = s[w].b[5];

int b6 = s[w].b[6]; int b7 = s[w].b[7]; int b8 = s[w].b[8];

s[w].b[0] = b6; s[w].b[1] = b3; s[w].b[2] = b0;

s[w].b[3] = b7; s[w].b[4] = b4; s[w].b[5] = b1;

s[w].b[6] = b8; s[w].b[7] = b5; s[w].b[8] = b2; }

//Flip state w about the Upper-Left to Lower-Right line

void flipULLR(int w) {

int b0 = s[w].b[0]; int b1 = s[w].b[1]; int b2 = s[w].b[2];

int b3 = s[w].b[3]; int b4 = s[w].b[4]; int b5 = s[w].b[5];

int b6 = s[w].b[6]; int b7 = s[w].b[7]; int b8 = s[w].b[8];

s[w].b[0] = b0; s[w].b[1] = b3; s[w].b[2] = b6;

s[w].b[3] = b1; s[w].b[4] = b4; s[w].b[5] = b7;

s[w].b[6] = b2; s[w].b[7] = b5; s[w].b[8] = b8; }

//Flip state w about the Lower-Left to upper-Right line

void flipLLUR(int w) {

int b0 = s[w].b[0]; int b1 = s[w].b[1]; int b2 = s[w].b[2];

int b3 = s[w].b[3]; int b4 = s[w].b[4]; int b5 = s[w].b[5];

int b6 = s[w].b[6]; int b7 = s[w].b[7]; int b8 = s[w].b[8];

s[w].b[0] = b8; s[w].b[1] = b5; s[w].b[2] = b2;

s[w].b[3] = b7; s[w].b[4] = b4; s[w].b[5] = b1;

s[w].b[6] = b6; s[w].b[7] = b3; s[w].b[8] = b0; }

//Flip state w about the Vertical Line

void flipVert(int w) {

int b0 = s[w].b[0]; int b1 = s[w].b[1]; int b2 = s[w].b[2];

int b3 = s[w].b[3]; int b4 = s[w].b[4]; int b5 = s[w].b[5];

int b6 = s[w].b[6]; int b7 = s[w].b[7]; int b8 = s[w].b[8];

s[w].b[0] = b2; s[w].b[1] = b1; s[w].b[2] = b0;

s[w].b[3] = b5; s[w].b[4] = b4; s[w].b[5] = b3;

s[w].b[6] = b8; s[w].b[7] = b7; s[w].b[8] = b6; }

//Flip state w about the Horizontal

void flipHoriz(int w) {

int b0 = s[w].b[0]; int b1 = s[w].b[1]; int b2 = s[w].b[2];

int b3 = s[w].b[3]; int b4 = s[w].b[4]; int b5 = s[w].b[5];

int b6 = s[w].b[6]; int b7 = s[w].b[7]; int b8 = s[w].b[8];

s[w].b[0] = b6; s[w].b[1] = b7; s[w].b[2] = b8;

s[w].b[3] = b3; s[w].b[4] = b4; s[w].b[5] = b5;

s[w].b[6] = b0; s[w].b[7] = b1; s[w].b[8] = b2; }

//Check if there are any other boards like s1 (w/permutations)

int anyOthers(int s1) {

for(int i = 0; i < s1; i++)

{if (completeEquality(s1,i) == 1)

{return 1;}}

return -1;}

//Check if there are any similar boards to s1, (w/o permutations)

int anySimilar(int s1) {

for(int i = 0; i < s1; i++)

{if (equals(s1,i) == 1)

{return 1;} }

return -1;}

//Checks if board s1 equals board s2 exactly

int equals(int s1, int s2) {

for(int i = 0; i < 9; i++)

{if (s[s1].b[i] != s[s2].b[i])

return -1;}

return 1;}

//Checks if s1 and s2 are equal (with permutations)

int completeEquality(int s1, int s2) {

if (equals(s1,s2) == 1) //First check if they're

return 1; //exactly equal

for(int i = 0; i < 4; i++) //Then rotate the board

{rotate(s1); //and check if the rotations

if (equals(s1,s2) == 1) //are equal to s2

return 1;}

flipHoriz(s1); //Flip it horizontally

if (equals(s1,s2) == 1) //and check to see if it

return 1; //equals s2

flipHoriz(s1);

flipVert(s1);

if (equals(s1,s2) == 1)

return 1;

flipVert(s1);

flipLLUR(s1);

if (equals(s1,s2) == 1)

return 1;

flipLLUR(s1);

flipULLR(s1);

if (equals(s1,s2) == 1)

return 1;

flipULLR(s1);

return -1;}