Bigdata Coding And Problem Solving in PC

Algorithms Development

C++ Programs

Brute Force: Dynamic Permutation

For contact: daxianfu@hotmail.com
Jump to Knight's Tours

Section 1: Print 92 Eight-Queens

Section 2: Walk-through a Maze

Section 3: Simulate Tortoise and Hare Race

Section 4: Simulate TicTac games

Section 5: Play Hanoi Towers game

Section 6: Print commercial styled calendar (1776-2775)

Section 7: Breaking Enigma Message

Section 8: Computer-assisted Poker Playing

Section 9: Print 1441 solutions for a difficult sudoku puzzle

Section 10: Print 6 million Knight's Tours

#include <iostream> 
#include <iomanip>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <fstream>
#include <sstream>
#include <cstdio>
#include <conio.h>
using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::ifstream;
using std::ofstream;
using std::ostringstream;
using std::ios;
using std::strtok;

Section 1: A Simple Solution to Eight-Queens Puzzle (by dynamic permutation)
string mNum[64], mQueen[92];
string mIndex1[64], mIndex2[64], mIndex3[64];// Explanation in Setup1()

void Show4() // Convert one-dimensional to two-dimensional representation of a 8-queen
{
  int k1, k2, n1, n2;
  string x1, x2, aShow[64], aNum[] = {"0 ","1 ","2 ","3 ","4 ","5 ","6 ","7 ","8 ","9 "};
  char c1[8];
  ifstream InFile("91Queen.txt", ios::in);
  n1 = 91; // n1 can be 0 - 91.
  for (k1 = 0; k1 <= n1; k1++)
      InFile >>  x1; 
  InFile.close();
  x1.copy(c1,8); // Convert string to char
  for (k1 = 0; k1 <= 63; k1++) // Make a mold of a chessboard
        aShow[k1] = "- ";

  for (k1 = 0; k1 <= 7; k1++)
        {
          n1 = int(c1[k1]) - 48;   // Convert char to integer
          aShow[n1] = aNum[k1+ 1]; // Pour data into the mold
  	}
  n1 = -1;
  for (k2 = 1; k2 <= 8; k2++)  
        {
          for (k1 = 1; k1 <= 8; k1++)
               {
               	 n1 = n1 + 1;
               	 cout << aShow[n1];
	       }
          cout << endl;
	}
}

void Check3() // Check for any errors 
{ 
  int k1, k2, k3, n1;
  string x1, x2,x3,aMove[92];
  bool aFilter[64];
  char c1[8];
  ifstream InFile("91Queen.txt", ios::in);
     for (k1 = 0; k1 <= 91; k1++)
          InFile >>  aMove[k1]; 
  InFile.close();
  for (k3 = 0; k3<= 91; k3++) // Does any queen attaches any of the other 7 queens?
        {
	  aMove[k3].copy(c1,8); // First convert 8 queens (8 characters) into char then int
	  for (k2 = 0; k2 <= 63; k2++)
	       aFiler[k2] = false; // aFilter[n] is defaulted to be false
          for (k2 = 0; k2 <= 7; k2++)
               {
                 n1 = int(c1[k2]) - 48; // When there is a queen on a particular square
                 aFilter[n1] = true;    // make the aFilter[n) true
	       }
          for (k2 = 0; k2 <= 63; k2++)
               {
                 if (aFilter[k2] == true) // Use 8 queens' square numbers to retrieve their value.	
                     {
                       x1 = mIndex1[k2]; x2 = mIndex2[k2]; x3 = mIndex3[k2];
                       for (k1 = k2 + 1; k1 <= 63; k1++) // Any queen who shares a value with
       	                    {                            // any other queen means she attacks her.
       	                      if (aFilter[k1] == true)
       	                          {
       	                            if (x1 == mIndex1[k1] || x2 == mIndex2[k1] || x3 == mIndex3[k1])
				    cout << "Mutual attack: in " << k2 << " "	<< k1 << endl;
				  }
       	             
	                     }
		      }
                 }
       	 } 
    
 aMove[91] = aMove[0]; // Set up an error test. Does this loops picks up a duplicit 8 queens
 for (k2 = 0; k2 <= 90; k2++)
       {
       	 x1 = aMove[k2];
       	 for (k1 = k2 + 1; k1 <= 91; k1++)
       	       {
       	       	 if (x1 == aMove[k1]) cout << "Dup in " << k2 << " and " << k1 << endl;
	       }
       } 
}
  
void Move2() // Permutate all possible 8-queen with a filtering. Row by row.
{            
  int k1, k2, k3, k4, n1, n2, aCount = -1, aLen = 7, aStart = 0,aEnd;
  string x1, x2, x3, q1, q2,aMove[568], bMove[568], aShow[64];
  bool aFilter[64];
  char c1[8];
  for (k1 = 0; k1 <= 7; k1++) // Load the first 8 queens on Row 0
      aMove[k1] = mNum[k1];

  for (k4 = 0; k4 <= 6; k4++) // permutate 7 rows (0 - 6)
       {
	 aStart = aStart + 8; aEnd = aStart + 7; // Start with Row 2 (Square 8 to 17)
         for (k3 = 0; k3 <= aLen; k3++)
              {
		q1 = aMove[k3]; q1.copy(c1,k4+1); //Convert string to char and then integer
                for (k2 = aStart; k2 <= aEnd; k2++)
                     aFilter[k2] = true;
                for (k2 = 0; k2 <= k4; k2++)
                     {
		       n1 = int(c1[k2]) - 48; // Use the integers to retrieve their value
                       x1 = mIndex1[n1]; x2 = mIndex2[n1]; x3 = mIndex3[n1];
                       for (k1 = aStart; k1 <= aEnd; k1++)
                            if (x1 == mIndex1[k1] || x2 == mIndex2[k1] || x3 == mIndex3[k1]) 
				aFilter[k1] = false;
                     }
                for (k2 = aStart; k2 <= aEnd; k2++)
                      {
			if (aFilter[k2] == true)
			    {
			     aCount = aCount + 1;            // If a queen does not share any 
                              bMove[aCount] = q1 + mNum[k2]; // value with the next queen, strings
                            }                                // her up
                      }
              }
         aLen = aCount; aCount = -1;
         for (k3 = 0; k3 <= aLen; k3++)
              aMove[k3] = bMove[k3]; // Copy bMove to aMove and string up more queens.
       }
        
  ofstream OutFile("91Queen.txt", ios::out); // Save the 92 8-queens into a textfile.
    for (k1 = 0; k1 <= 91; k1++)
          OutFile << aMove[k1] << endl;
  OutFile.close(); 
  
}
 
void SetUp1()
{ 
  int k1, k2;
  string x1, x2, x3;
  for (k1 = 0; k1 <= 63; k1++)
       mNum[k1] = char(k1+48); 
  // The chessboard has 64 squares. Each square is assigned 3 values.
  // Column, forward diagonal and backward diagonal. Diagonal values are as below
  // abcdefgh  abcdefgh
  // bcdefghi  iabcdefg
  // cdefghij  jiabcdef
  // defghijk  kjiabcde
  // efghijkl  lkjiabcd
  // fghijklm  mlkjiabc
  // ghijklmn  nmlkjiab
  // hijklmno  onmlkjia      
  x1 = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno"; // Column value
  x2 = "abcdefghiabcdefgjiabcdefkjiabcdelkjiabcdmlkjiabcnmlkjiabonmlkjia"; // forward diagonal
  x3 = "abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh"; // backward diagonal
  for (k1 = 0; k1<= 63; k1++)
        {
          mIndex1[k1] = x1.substr(k1,1);
          mIndex2[k1] = x2.substr(k1,1);
          mIndex3[k1] = x3.substr(k1,1);
	}
 }
 
void aMain()
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   SetUp1(); 
   Move2();
   Check3(); 
   Show4();
 }
int main(int argc, char** argv)
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }
							 
Section 2:  Walking through a maze

  # # # # # # # # # # # # 
  # . . . # . . . . . . # 
  . . # . # . # # # # . # 
  # # # . # . . . . # . # 
  # . . . . # # # . # . . 
  # # # # . # . # . # . # 
  # . . # . # . # . # . # 
  # # . # . # . # . # . # 
  # . . . . . . . . # . # 
  # # # # # # . # # # . # 
  # . . . . . . # . . . # 
  # # # # # # # # # # # #
   
  Overview
  The maze is represented by a string array of 143 positions (one dimentional)
  The walls are reprensented by hashes and the path's position, the dots.
  The value are set as follows:
  The wall: 9; the path: 0 and the exit position: -1.
  A position's value increased by 1 when it is stepped on.
  There are four walking directions. 1 represents forward: -1, backward,
  -12, left and 12, right."Place your hand on the wall and begin walking
  forward" means the program sets direction priorities as step(0) = 1,
  step(1) = 12, step(2) = -12, step(3) = -1. A person starts on left side 
  of the maze means his start values 24. The 24 + step(n) yields 4 positions: 
  25(value: 0),12(value: 9), 36(value: 9) and 23(value: 9). The program, 
  through a loop of 0 - 3, picks the position with the smalles value, 25.
  Now his start value is 25. The program ends when he steps on the exit 

ofstream OutFile("MazeTra.txt", ios::out);
int mRate[144] = {0};
string mMaze[144]; // hashes mean wall and dots means path. s means start and e means end.

void Move2a() // The walking through step by step is printed in a text file with the 
              // the folder named Mazetra.txt
 {   
   int k1,k2;
   string x1;
    
   for (k2 = 0; k2 <= 132; k2+= 12)
        {
          x1 = "";
          for (k1 = k2; k1 <= k2 + 11; k1++)  
               x1 = x1 + mMaze[k1] + " ";
	       OutFile  <<"  " << x1 << endl; // Print a snapshots of the maze board
	}
   OutFile << "" << endl;
   
}

void Move3() // Walking through a no exit maze
 {   
   int k1, k2,n1, n2,aStart = 24, bStart = 24,cStart, aMin;
   int  Start1[] = {0,24,59},aStep[] = {1,12,-12,-1};
   string x1;
   
   mMaze[aStart] = "s";  mMaze[59] = "#";
   mRate[aStart] = 0; mRate[59] = 9;
   
   do
     {
       aMin = 9; // Find out the position with the smallest value
       for (k1 = 0; k1 <= 3; k1++)
            {
              n1 = aStart + aStep[k1];
              n2 = mRate[n1];
              if (aMin > n2) 
                  {
          	    aMin = n2; bStart = n1; 
	          }
            }
       aStart = bStart; mRate[aStart] = mRate[aStart] + 1;
       if (mRate[aStart] == 1)
           x1 = "x";
       else if (mRate[aStart] == 2)
            x1 = "y";
       else
            x1 = "z";
       mMaze[aStart] = x1; 
       Move2a();
     } while (aStart != 24);
}

 void Move2(int pStart) // User input: 1 means starts on left side and 2, right side.
 {   
   int k1, k2,n1, n2,aStart, aEnd,bStart, aMin, Start1[] = {0,24,59},aStep[] = {1,12,-12,-1};
   string x1;
   
   aStart = Start1[pStart]; aEnd = 83 - aStart; // If start = 24 then end = 83 - 24
   mMaze[aStart] = "s";  mMaze[aEnd] = "e";     // If start = 59 then end = 83 - 59
   mRate[aStart] = 1; mRate[aEnd] = -1;
   
   while (aStart != aEnd)
        {
	  aMin = 9; 
          for (k1 = 0; k1 <= 3; k1++)
               {
                 n1 = aStart + aStep[k1];
                 n2 = mRate[n1];
                 if (aMin > n2) 
                     {
              	       aMin = n2; bStart = n1; 
		     }
	      }
          aStart = bStart; mRate[aStart] = mRate[aStart] + 1;
         if (mRate[aStart] == 1)
              x1 = "x";
         else if (mRate[aStart] == 2)
             x1 = "y";
         else
             x1 = "z";
          
          mMaze[aStart] = x1; 
          if (aStart != aEnd) break;
              Move2a(); 
        } 
}

 void SetUp1()
 {   
   int k1;
   string x1,x2;
   x1 = "#############...#......#..#.#.####.####.#....#.##....###.#..####.#.#.#.##..#.#.#.#.###.#.#.#.#.##........#.#######.###.##......#...#############";
   for (k1 = 0; k1 <= 143; k1++)
        {
          x2 = x1.substr(k1,1);
          mMaze[k1] = x2;
          if (x2 == "#") mRate[k1] = 9; 
		}
}
		    
  void aMain()
 { 
   int k1,n1;
   string x1,x2;
   string Direc[] = {"","Starting on left", "Starting on right","A maze without an exit"};
   
   SetUp1();
   OutFile << "Walking through the maze" << endl;
   Move2a();
   cout << "Start from left TYPE 1. From right, type 2, a maze without an exit,3: ";
   cin >> n1;
   OutFile << Direc[n1] << endl;
   if (n1 == 2)
      OutFile << "(x means the path was stepped on once while y means twice" << endl;
   if (n1 == 3)
       {
       	OutFile << "(x: the path stepped on once, y: twice, and z: three times." << endl;
       	Move3();
	   }
    else
      Move2(n1); 
   OutFile.close(); 
 }
 
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Section 3
Simulate the Race of Tortoise and Hare
1. Permutate 1 million races
2. Evaluate the fairness of the moves of the tortoise and the hare (each animal wins half races.)
3. Play back easily any race (win, lose and tie)
4. The program makes it easily to do statistical analysis for the 1 million race.
   (e.g. the shortest race and the longest one and the average race length, so on
Tortoise   50% 3 squares forward
           20% 6 squares backward
           30% 1 square forward

Hare       20% 0 square forward
           20% 9 squares forward
           10% 12 squares backward
           30% 1 square forward
           10% 2 squares backward
           10% 4 squares backward
Race course: 70 squares

// Length of race: 10 - 378;
int tIndex[] = {3,3,3,3,3,-6,-6,1,1,1},hIndex[] = {0,0,9,9,-12,1,1,1,-2,-4},mFlip[101];
//int tIndex[] = {3,3,3,3,3,-6,-6,1,1,1},hIndex[] = {0,0,9,9,-12,1,1,1,-2,-2};
string mNum[70];

void PlayBack4() // This is stand-alone function depending on a textfile "Racekk2.txt"
 {   
   int k1,n1,aLen;
   string x1, x2,aWin[] = {"H","T","I"}, bWin;
   char c1[1500];
   cout << "Hare racing tortoise. Who wins? type 0 for hare, 1 for tortoise, 2 for a tie: "; 
   cin >> n1;
   bWin = aWin[n1];                                                  
   ifstream InFile("Racekk2.txt", ios::in);
   for (k1 = 0; k1 <= 999999; k1++)
        {
          getline(InFile,x1);
	  aLen = x1.length() - 71;
	  x2 = x1.substr(aLen,1);
	  if (x2 == bWin) break;
        }
  	  
   aLen = x1.length() / 71; // Race is 70 squares + 1 (finished line)
   n1 = -71;
   for (k1 = 1; k1 <= aLen ; k1++)
         {
           n1 = n1 + 71;
           cout << x1.substr(n1,71) << endl;
 	 } 
}
 
void Race3()
 {   
   int k1,k2, n1,n2, n3,r1, r2,aLen;
   string x1,aRace, bRace,cRace,aMess[3];;
   char c1[999];
      aRace = "                                                                      |";
   aMess[0] = "Tortoise wins!                                                         ";
   aMess[1] = "Hare wins!                                                             ";
   aMess[2] = "It's a tie.                                                            ";
   
   ifstream InFile("Racekk1.txt", ios::in); // Change positions into race course snapshots.
   ofstream OutFile("Racekk2.txt", ios::out);
   for (k2 = 0; k2 <= 999999; k2++)
        {
	  InFile >>  x1;      // A move has 2 ASCII numbers:
	  aLen = x1.length(); // the first is Tortoise' position and the second is Hare's
	  x1.copy(c1,aLen); cRace = ""; // e.g. 25: T is in position 2 and H is in 5
          for (k1 = 0; k1 < aLen; k1+= 2)
               {
                 bRace = aRace;
		 n1 = int(c1[k1]) - 48; n2 = int(c1[k1+1]) - 48;
		 if (n1 != n2)
		     {
		       bRace.replace(n1,1,"T"); bRace.replace(n2,1,"H"); 
		     }
		 else
		     {
		      	if (n1 < 63)
			    n3 = n1; // Race must stay within 70-course
			else
			    n3 = 63;
		      	bRace.replace(n3,7,"OUCH!!!");
		     }
		         cRace = cRace + bRace;  
	      } 
         if (n1 > n2)
             n3 = 0; // Tortoise wins
	 else if (n1 < n2)
             n3 = 1; // Hare wins
	 else
             n3 = 2; // It's a tie
         cRace = cRace + aMess[n3];
         OutFile << cRace << endl;
        }
    OutFile.close();
    InFile.close();
 }
 
 void Race2()
 {   
   int k1,k2,n1 = 0,n2 = 0,n3 = 0,t1, t2,h1, h2; // t1,t2: tortoise; h1,h2: hare
   string aRace;
   
   ofstream OutFile("Racekk1.txt", ios::out);
   for (k2 = 0; k2 <= 999999; k2++) // Pile up position changes
        {
	  t1 = 20; h1 = 20; aRace = ""; // To avoid arrays with minus' index
          while (t1 != 89 && h1 != 89)  // use 20 to represent 1 and 89, square 70
                 {
      	           t2 = rand() % 10; h2 = rand() % 10;
                   t1 = tIndex[t2] + t1; t1 = mFlip[t1]; // When position drops below 1
                   h1 = hIndex[h2] + h1; h1 = mFlip[h1]; // position = 1
                   t2 = t1 - 20; h2 = h1 - 20;
                   aRace = aRace  + mNum[t2] + mNum[h2];
	         }
	      OutFile << aRace << endl;      
	      if (t2 > h2)
		  n1 = n1 + 1;
	      else if (t2 < h2)
		  n2 = n2 + 1;
	      else
		n3 = n3 + 1; //Count the wins and tie
	    }
   OutFile.close();
   
    ofstream aOutFile("RaceSum.txt", ios::out);
    aOutFile << "Simulating a million races of tortoise vs hare."<< endl;
    aOutFile << "Tortoise's Win " << " Hare's Win  " << "Tie" << endl;
    aOutFile << n1 << "          " << n2 << "      " << n3 << endl;
    aOutFile.close();
 }

 void SetUp1()
 {   
   int k1,n1;  
   n1 = 47; //Use ASCCI to represent the positions (1 - 70)
   for (k1 = 0; k1 <= 69; k1++)   
        {
          n1 = n1 + 1; mNum[k1] = char(n1); 
	}
   for (k1 = 0; k1 <= 20; k1++) // If position drops to below 1 then position = 1
        mFlip[k1] = 20; 
   for (k1 = 21; k1 <= 89; k1++)
        mFlip[k1] = k1;      
   for (k1 = 90; k1 <= 99; k1++) // If position rises to above 70 then position = 70     
	mFlip[k1] = 89;
 }
		  
 void aMain()
 { 
   int k1,k2,n1, n2;
   string x1,x2;
   srand(time(0));
   SetUp1();
  // Race2(); // Race2,3 compile a race list
  // Race3(); // They need to run only once.
   PlayBack4(); // Playback4 runs many times.It does not need to run race2,3.
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Section 4: Simulate TicTac games
Using dynamic permutation to solve problems
This program accomplishes 3 tasks
1. Compile a complete list of all possible single moves in the form of text file
   using snapshots of the game board to represent  moves. e.g. "000010000" means 
   player 1 putting  a soldier in Square 4 while player 2 answers with a move in 
   Square 0: "200010000" 
2. Compile a complete list of all games in the forms of snapshots. The shortes game is:
   "000010000 200010000 200011000 200211000 210211000 2100211200 w". w means it is a win.
3. Compile a complete list of all games formatted and in 2-D form. The format is:
   "012 - - - - - - 345 - - - 678 - - - ". The print0ut: 
   012 - - - - - -
   345 - - - - - - 
   678 - - - - - - 
   The first 2 moves of ""000010000 200010000" is displayed:
   012 - - -  2 - -
   345 - 1 -  - 1 - 
   678 - - -  - - - 
4. A human player vs the program live.
   The program uses human's moves to retrieve the program's answering moves in the form of
   snapshot from the snapshot list (a text file) and displays the moves.

Data representation
  1. Game board: a string array[9]
  2. 1 means Player 1 and 2 means Player 2
  3. Use an integer mCheck[23] to reorder the 9 squares by row, column and diagonally. 
     So we can find out quickly and easily a checkmate situation and checkmate.
Permutation
  Human moves first:
  1. A game starts with "000000000"
  2. Permutate to "100000000 010000000 ... 000000001
  3. The program answers these moves with "100020000 010020000 ... 000020001"
  4. When the game moves to round 3, filter out the winning games.
  5. From now on alternate between filtering out and permutation until the game is over.
  Program moves first
  1. A game starts with "000020000"( the dead center of the board) 
The TicTac program is divided in 5 mini-sub-programs
  1. Compilation of all moves' snapshot (human as first mover)
  2. Compilation of all moves' snapshot (human as second mover)
  3. Compilation of all possible games (human as first mover)
  4. Compilation of all possible games (hman as second mover)
  5. Live game playing (human starts by choosing as either first mover or the second)
  The program displays a promt: "Play Tic-tac-toe as first mover type 1 else type 2:"
  The program then print the game board as follows:
  012 - - - - - -
  345 - - - - - - 
  678 - - - - - - 
  The program prints: "To play a game, type a number now:" 4
  It then displays a human's move and the program's return move (square 0)
  012 - - -  2 - -
  345 - 1 -  - 1 - 
  678 - - -  - - - 
  At the end the program diplays: Game's over. You lost (or Game's over. You tied.)
Some return moves are individually decided by the programmer for efficiency purpose.
By design, the program never loses and all games are made to as short as possible.
When the program is the first mover. Its first move is the dead center: square 4.

//Part 1: Player 1: human vs Player 2: computer.
//compiles a list of every move in the form of snapshot (of the game board).
//Processing from bottom up.
int mStart, mEnd, mCheck[] = {0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6};
string mMove[319], nMove[319]; // Total sets of moves. 

 void Move4() // 206 - 318
 { 
   int k1,k2, k3,n1,aCount = -1,bCount, aLen, aKey, bKey;
   int aHole[] = {3,1,2,1,6,6,2,3}; // Programmer decided individual moves
   string x1,x2, x3, aWin,aMove[43], bMove[129],aPosit[9];
   for (k1 = mStart; k1 <= mEnd; k1++)
        {
          x1 = nMove[k1];
          if (x1.substr(9,1) == "c") // if the snapshot's status is "c" then continues
              {
              	aCount = aCount + 1;
              	aMove[aCount] = x1.substr(0,9); 
	      }
       }
    aLen = aCount; aCount = -1; mStart = mEnd + 1; 
   
   for (k2 = 0;k2 <= aLen; k2++)
        {
	  x1 = aMove[k2]; 
	  for (k1 = 0; k1 <= 8; k1++)
	       {
		 x2 = x1;
		 if (x2.substr(k1,1) == "0")
		     {
		       x2.replace(k1,1,"1"); // Permutate player 1's all moves
		       aCount = aCount + 1; 
		       bMove[aCount] = x2; 
		     }
	       } 
       } 
   aLen = aCount; aCount = mEnd; 	
   for (k2 = 0; k2 <= aLen; k2++) // Filter out the duplicates		
        {
          x1 = bMove[k2];
          for (k1 = k2 +1; k1 <= aLen; k1++)
               if (x1 == bMove[k1]) goto aSkip;
          aCount = aCount + 1;
	  mMove[aCount] = x1; 
	  aSkip: k1 = 0;
	}

  mStart = mEnd + 1;	mEnd = aCount; 
  for (k3 = mStart; k3 <= mEnd; k3++)
       {
	 x1 = mMove[k3]; bKey = 9; aWin = "c";
	 for (k2 = 0; k2 <= 8; k2++)
	      {
	        x2 = x1.substr(k2,1);
	        if (x2 == "0") x2 = "";
	        aPosit[k2] = x2;
	      }
	for (k2 = 0; k2 <= 21; k2+= 3)
	     {
	       x1 = ""; 
	       for (k1 = k2; k1 <= k2+ 2; k1++)
	            {
	              n1 = mCheck[k1];
	              x1 = x1 + aPosit[n1];
	              if (aPosit[n1] == "") aKey = n1;
		    }
	      if (x1 == "22") 
		  {
		    aWin = "w";
		    aPosit[aKey] = "2"; goto bSkip; // a 222 lineup ends the game
	          }
	      if (x1 == "11") bKey = aKey; // Block human's checkmate's attemp
	    }
      if (bKey != 9) // There's a checmate situation.
	  {
	    aPosit[bKey] = "2"; goto bSkip;	
	  }
     for (k2 = 0; k2 <= 8; k2++)
	  {
	    if (aPosit[k2] == "")
	        {
	          aPosit[k2] = "2"; break; // No checkmate. It's a draw.
		}
	  }
     bSkip: k1 = 0;
     x1 = "";
     for (k2 = 0; k2 <= 8; k2++)
	  {
	    x2 = aPosit[k2];
	    if (x2 == "") x2 = "0";
	        x1 = x1 + x2;
	  } 
   nMove[k3] = x1 + aWin;
		} 
   ofstream OutFile("Tic318.txt", ios::out); // The total unique move sets(2 moves): 318 

   for (k1 = 0; k1 <= mEnd; k1++)
	{
	  x2 = nMove[k1];
	  if (k1 < 44) x2 = x2 + "c"; // There is no winning games before snapshot 44.
	  x1 = mMove[k1] + " " + x2;
	  OutFile << x1 << endl; // Save all games (move by move) in text file.	
	}	
	    
   OutFile.close(); // The file makes it possible to evaluate the programmer's gamesmanship.
 }

 void Move3() // 44 - 205
 { 
   int k1,k2, k3,n1,aCount = -1, bCount, aLen,aKey, bKey;
   int aHole[] = {3,1,2,1,6,6,2,3};
   string x1,x2, x3, aWin,aMove[175], aPosit[9]; 
   
   for (k3 = mStart;k3 <= mEnd; k3++) // This for-loop permutate the 44 moves
        {
          x1 = nMove[k3].substr(0,9); 
	  for (k2 = 0; k2 <= 8; k2++)
	       {
	       	 x2 = x1;
	       	 if (x2.substr(k2,1) == "0")
	       	     {
	       	       x2.replace(k2,1,"1");
	       	       aCount = aCount + 1; 
	       	       aMove[aCount] = x2;  
	       	       aSkip: k1 = 0;
	    	     }
		} 
	} 

	aLen = aCount; aCount = mEnd; mStart = mEnd + 1; 
	for (k2 = 0; k2 <= aLen; k2++) // This loop filters out the duplicates
	     {
	       x1 = aMove[k2];
	       for (k1 = k2 + 1; k1<= aLen; k1++)
	            if (x1 == aMove[k1]) goto aBottom;
	       aCount = aCount + 1; 
	       mMove[aCount] = x1;
	       aBottom: k1 = 0;
		 }
	mEnd = aCount; aCount = -1;
	
	for (k3 = mStart; k3 <= mEnd; k3++)
	     {
	       x1 = mMove[k3]; bKey = 9; aWin = "c"; 
              // An unfinished game is defaults to "c" meaning continuing
	       for (k2 = 0; k2 <= 8; k2++)
	            {
	              x2 = x1.substr(k2,1);
	              if (x2 == "0") x2 = "";
	              aPosit[k2] = x2;
		    }
	     	for (k2 = 0; k2 <= 21; k2+= 3)
	            {
	              x1 = ""; 
	              for (k1 = k2; k1 <= k2+ 2; k1++)
	                   {
	                   	 n1 = mCheck[k1];
	                   	 x1 = x1 + aPosit[n1];
	                   	 if (aPosit[n1] == "") aKey = n1;
			    }
			    if (x1 == "22") 
                                   // If there is "22" line-up, move to that unit remaining square
				{
				   aPosit[aKey] = "2"; aWin = "w"; // Finish the game with a win.
				   goto bSkip;
				}
				  if (x1 == "11") bKey = aKey;
		    }
			    if (bKey != 9)
			        {
			          aPosit[bKey] = "2"; goto bSkip; 
                                  //If there is a checkmate situation, block it.	
				}
	        aCount = aCount + 1;
	        n1 = aHole[aCount]; aPosit[n1] = "2";
	       bSkip: k1 = 0;
	       x1 = "";
	       for (k2 = 0; k2 <= 8; k2++)
	            {
	              x2 = aPosit[k2];
	              if (x2 == "") x2 = "0";
	              x1 = x1 + x2;
				} 
		   nMove[k3] = x1 + aWin;
		 } 		 	
}

 void Move2() // 9 - 43
 { 
   int k1,k2, k3,n1,aCount = -1, bCount = 8, aKey;
   int aHole[] = {7,5,1,2,0,5,3,3,7,1,3,1,0,1,2,1,2};
   string x1,x2, x3,aMove[35], aPosit[9];
   
   for (k3 = 0;k3 <= 8; k3++) // Permutate 8 moves to 43 moves for player 1.
        {
	  x1 = nMove[k3]; 
	  for (k2 = 0; k2 <= 8; k2++)
	       {
		 x2 = x1;
		 if (x2.substr(k2,1) == "0") // "0" means unoccupied squares
		     {
		       x3 = x2.replace(k2,1,"1");
		       for (k1 = 0; k1 <= aCount; k1++)
		       	    {
		       	      if (x3 == aMove[k1]) goto aSkip; //Filter out any duplicates	
			     }
		      aCount = aCount + 1; bCount = bCount + 1;
		      mMove[bCount] = x3; aMove[aCount] = x3; 
		      aSkip: k1 = 0;
		     }
	       } 
       } 
  mStart = k3; mEnd = bCount;	aCount = -1;
  for (k3 = mStart; k3 <= mEnd; k3++)
       {
	 x1 = mMove[k3];  
	 for (k2 = 0; k2 <= 8; k2++)
	            {
	              x2 = x1.substr(k2,1);
	              if (x2 == "0") x2 = "";
	              aPosit[k2] = x2;
		    }
	  for (k2 = 0; k2 <= 21; k2+= 3) 
                 // Reorder the 9-square game board into 24-square board 
                 // (row, column and diagonal). 3 squares a unit and 8 units in total.
	       {
	         x1 = ""; 
	         for (k1 = k2; k1 <= k2+ 2; k1++)
	              {
	                n1 = mCheck[k1];
	                x1 = x1 + aPosit[n1];
	                if (aPosit[n1] == "") aKey = n1;
		      }
		 if (x1 == "11") // A unit value "11" means there is a checkmate situation.
  		     {
		       aPosit[aKey] = "2"; // Player 2 moves to that square to stop a checkmate
		       goto bSkip;
		      }
		}
	       aCount = aCount + 1;
	       bCount = aHole[aCount]; aPosit[bCount] = "2";
               // If there is no checkmate situation, programmer what square to go
	       bSkip: k1 = 0;
	       x1 = "";
	       for (k2 = 0; k2 <= 8; k2++)
	            {
	              x2 = aPosit[k2];
	              if (x2 == "") x2 = "0";
	              x1 = x1 + x2; // Making up the move - snapshot
		    } 
		   nMove[k3] = x1;
		 } 
        }

void Move1() // 0 - 8 Start the first set of moves by player 1 and the returned moves by player 2
 {   
   int k1, n1;
   string x1,x2;
   x1 = "100000000010000000001000000000100000000010000000001000000000100000000010000000001";
   x2 = "100020000010020000001020000000120000200010000000021000000020100000020010000020001";
   // x1: all possible 9 moves Player 1 can make. And store the moves into mMove[n]
   // x2: the 9 moves Player 2 answers and stores the moves into nMove[n]
   
   n1 = -9;
   for (k1 = 0; k1 <= 8; k1++)  
        {
          n1 = n1 + 9;
          mMove[k1] = x1.substr(n1,9);
          nMove[k1] = x2.substr(n1,9); 
        }
}
		  
 void aMain()
 { 
   int k1,n1;
   string x1;
      
   Move1();
   Move2();
   Move3();	 
   Move4();      
		
}
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

//Part 2: Player 1 Computer vs Player 2 Human. Computer's first move is square 4 (the center)
// This program translates snapshot representation of games to 2-D and formatted 
// representation and save the games into a text file(human as player 2 vs computer 
// as player 1). So anyone can play back all the games easily.
int mIndex[9],nIndex[9], mCheck[] = {0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6};
string mMove[319],nMove[319], mGame[457];

// Display a move for testing purpose
void Show3b(string pGame)
 { 
   int k1,n1, aLen;
   string x1;
   aLen = pGame.length() / 21; // Each set of moves is in length of 21 characters
   n1 = -21;
   for (k1 = 1; k1 <= aLen; k1++)
        {
          n1 = n1 + 21;
          x1 = pGame.substr(n1,21);
          cout << x1 << endl;
          if (k1 % 3 == 0) cout << endl;
 	}
} 
// From snapshots to 2-D and move by move game representation
string AllGames3a(string pMove,string qMove)
 { 
   int k1,k2,n1;
   string x1,x2;
   string aMold = "0 1 2  _ _ _  _ _ _  3 4 5  _ _ _  _ _ _  6 7 8  _ _ _  _ _ _  ";
   for (k1 = 0; k1 <= 8; k1++)
        {
          x1 = pMove.substr(k1,1);
	  if (x1 != "0")
	      { 
	        n1 = mIndex[k1]; 
	     	aMold.replace(n1,1,x1);
	      }	
	}
   for (k1 = 0; k1 <= 8; k1++)
        {
          x1 = qMove.substr(k1,1);
		  if (x1 != "0")
		      { 
		      	n1 = nIndex[k1]; 
		      	aMold.replace(n1,1,x1);
		      }	
	} 	
  return aMold;  
} 

void AllGames3()
 { 
   int k1,k2,n1,aLen;
   string x1,x2, x3, aMove, bMove,aGame,aWin; 
   
   ofstream OutFile("GameA456bx.txt", ios::out);
   for (k2 = 0; k2 <= 456; k2++)
        {
          aMove = mGame[k2]; aWin = "Game's over You tied."; 
          if (aMove.find("w",0) != -1) aWin = "Game's over. You lost";
	  aLen = aMove.length() / 20;
          n1 = -20; aGame = "";
          for (k1 = 1; k1 <= aLen; k1++ )
              {
                n1 = n1 + 20;
                bMove = aMove.substr(n1,20); 
		x1 = bMove.substr(0,9); x2 = bMove.substr(10,9);
		x3 = AllGames3a(x1,x2); 
		aGame = aGame + x3;
	      }
	 aGame = aGame + aWin; 
	 OutFile << aGame << endl;  
       }
  OutFile.close();
} 

string MoveA2a(string pMove)
 {   
   int k1;
   string x1;
   for (k1 = 0; k1 <= 318; k1++)
        if (pMove == mMove[k1]) break;
   x1 = nMove[k1];
   return x1;
 }
 
 void MoveA2()
 {   
   int k1,k2,k3,n1,aCount = -1, bCount = -1,aLen = 8;
   string x1,x2, x3,aMove, bMove, aPosit[9];
   string aGame[457], bGame[457], wGame[457];
   //The first set of moves:
   x1 = "100000000 010000000 001000000 000100000 000010000 000001000 000000100 000000010 000000001 ";
   x2 = "100020000 010020000 001020000 000120000 200010000 000021000 000020100 000020010 000020001 ";
   n1 = -10;
   for (k1 = 0; k1 <= 8; k1++)
        {
          n1 = n1 + 10; aGame[k1] = x1.substr(n1,10) + x2.substr(n1,10);
	}
   
   for (k3 = 10; k3 <= 30; k3+= 20)
        {
	  for (k2 = 0; k2 <= aLen; k2++)
               {
		 aMove = aGame[k2]; 
		 bMove = aMove.substr(k3,10);
                 for (k1 = 0; k1 <= 8; k1++)
                      {
                        x1 = bMove.substr(k1,1);
                        if (x1 == "0")
                            {
                       	      x2 = bMove; 
			      x2.replace(k1,1,"1");
			      x3 = MoveA2a(x2);
			      aCount = aCount + 1;
			      bGame[aCount] = aMove + x2 + x3; 
			     } 
                      } 
               } 
          aLen = aCount; aCount = -1; 
	  for (k2 = 0; k2 <= aLen; k2++) aGame[k2] = bGame[k2];
       } 
	 
   bCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
	  aMove = aGame[k3]; bMove = aMove.substr(50,9); 
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	       {
	         x1 = ""; 
	         for (k1 = k2; k1 <= k2 + 2; k1++)
	              {
	                n1 = mCheck[k1];
	                x1 = x1 + aPosit[n1];
		      }  
		 if (x1 == "222") 
		      {
			bCount = bCount + 1;
			wGame[bCount] = aMove; 
			goto aBottom;
		       }
	       }
	  aCount = aCount + 1;  
	  bGame[aCount] = aMove; 
	  aBottom: k1 = 0;
	} 
		
   aLen = aCount; aCount = -1; 
   for (k2 = 0; k2 <= aLen; k2++)
        {
          aMove = bGame[k2]; bMove = aMove.substr(50,10); 
          for (k1 = 0; k1 <= 8; k1++)
                {
                  x1 = bMove.substr(k1,1);
                  if (x1 == "0")
                      {
                       	 x2 = bMove; 
		         x2.replace(k1,1,"1");
			 x3 = MoveA2a(x2);
			 aCount = aCount + 1;
			 aGame[aCount] = aMove + x2 + x3; 
		      }
                }
       } 
   
   aLen = aCount; aCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
	  aMove = aGame[k3]; bMove = aMove.substr(70,9);
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	       {
	         x1 = ""; 
	         for (k1 = k2; k1 <= k2 + 2; k1++)
	              {
	                n1 = mCheck[k1];
	                x1 = x1 + aPosit[n1];
		       }  
		 if (x1 == "222") 
		     {
		       bCount = bCount + 1; // Computer wins. 
		       wGame[bCount] = aMove;  
		       goto bBottom;
		     }
	       }
	  aCount = aCount + 1;  
	  bGame[aCount] = aMove; 
          bBottom: k1 = 0;
       } 
	
  for (k1 = 0; k1 <= bCount; k1++)
       wGame[k1] = wGame[k1] + "w";
  aLen = aCount; 
   for (k1 = 0; k1 <= aCount; k1++)
        { 
          bCount = bCount + 1; wGame[bCount] = aGame[k1] + "t";	// t means a tie.
        } 
  
  ofstream OutFile("GameB139x.txt", ios::out);
  for (k1 = 0; k1 <= bCount; k1++)
       OutFile << wGame[k1] << endl;
  OutFile.close();	  
}

void SetUp1()
 {   
   int k1, n1;
   string x1;
   ifstream InFile("TicA318.txt", ios::in);
   for (k1 = 0; k1 <= 318; k1++)
        {
          getline(InFile, x1);
          mMove[k1] = x1.substr(0,10); nMove[k1] = x1.substr(10,9) + " ";
	}
   InFile.close();
   // Use this index to transform snapshots to graphical -like display
   string p1[] = {"A","B","C","D","E","F","G","H","I","a","b","c","d","e","f","g","h","i"};
   x1 = "0 1 2  A B C  a b c  3 4 5  D E F  d e f  6 7 8  G H I  g h i  ";
   for (k1 = 0; k1 <= 8; k1++)
         {
           n1 = k1 + 9;
           mIndex[k1] = x1.find(p1[k1],k1);
           nIndex[k1] = x1.find(p1[n1],k1); 
	} 
		 
   ifstream aInFile("GameA456aX.txt", ios::in);
     for (k1 = 0; k1 <= 456; k1++)
          getline(aInFile,mGame[k1]); //Load up all 456 games for play-back
   aInFile.close();
}
		  
 void aMain()
 { 
   int k1,n1;
   string x1;
   SetUp1();
   AllGames3();
   
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Part 3
// This program translates snapshot representation of games to 2-D and formatted 
// representation and save the games into a text file(human as player 1 vs computer
// as player 2). So anyone can play back all the games easily.
int mIndex[9],nIndex[9], mCheck[] = {0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6};
string mMove[319],nMove[319], mGame[457];

// Display a move for testing purpose
void Show3b(string pGame)
 { 
   int k1,n1, aLen;
   string x1;
   aLen = pGame.length() / 21;
   n1 = -21;
   for (k1 = 1; k1 <= aLen; k1++)
        {
          n1 = n1 + 21;
          x1 = pGame.substr(n1,21);
          cout << x1 << endl;
          if (k1 % 3 == 0) cout << endl;
 	}
} 
// From snapshots to 2-D and move by move game representation
string AllGames3a(string pMove,string qMove)
 { 
   int k1,k2,n1;
   string x1,x2;
   string aMold = "0 1 2  _ _ _  _ _ _  3 4 5  _ _ _  _ _ _  6 7 8  _ _ _  _ _ _  ";
   for (k1 = 0; k1 <= 8; k1++)
        {
          x1 = pMove.substr(k1,1);
	  if (x1 != "0")
	      { 
	        n1 = mIndex[k1]; 
	     	aMold.replace(n1,1,x1);
	      }	
	}
   for (k1 = 0; k1 <= 8; k1++)
        {
          x1 = qMove.substr(k1,1);
		  if (x1 != "0")
		      { 
		      	n1 = nIndex[k1]; 
		      	aMold.replace(n1,1,x1);
		      }	
	} 	
  return aMold;  
} 

void AllGames3()
 { 
   int k1,k2,n1,aLen;
   string x1,x2, x3, aMove, bMove,aGame,aWin; 
   
   ofstream OutFile("GameA456bx.txt", ios::out);
   for (k2 = 0; k2 <= 456; k2++)
        {
          aMove = mGame[k2]; aWin = "Game's over You tied."; 
          if (aMove.find("w",0) != -1) aWin = "Game's over. You lost";
	  aLen = aMove.length() / 20;
          n1 = -20; aGame = "";
          for (k1 = 1; k1 <= aLen; k1++ )
              {
                n1 = n1 + 20;
                bMove = aMove.substr(n1,20); 
		x1 = bMove.substr(0,9); x2 = bMove.substr(10,9);
		x3 = AllGames3a(x1,x2); 
		aGame = aGame + x3;
	      }
	 aGame = aGame + aWin; 
	 OutFile << aGame << endl;  
        }
  OutFile.close();
} 

string MoveA2a(string pMove)
 {   
   int k1;
   string x1;
   for (k1 = 0; k1 <= 318; k1++)
        if (pMove == mMove[k1]) break;
   x1 = nMove[k1];
   return x1;
 }
 
 void MoveA2()
 {   
   int k1,k2,k3,n1,aCount = -1, bCount = -1,aLen = 8;
   string x1,x2, x3,aMove, bMove, aPosit[9];
   string aGame[457], bGame[457], wGame[457];
   x1 = "100000000 010000000 001000000 000100000 000010000 000001000 000000100 000000010 000000001 ";
   x2 = "100020000 010020000 001020000 000120000 200010000 000021000 000020100 000020010 000020001 ";
   n1 = -10;
   for (k1 = 0; k1 <= 8; k1++)
        {
          n1 = n1 + 10; aGame[k1] = x1.substr(n1,10) + x2.substr(n1,10);
	}
   
   for (k3 = 10; k3 <= 30; k3+= 20)
        {
	  for (k2 = 0; k2 <= aLen; k2++)
               {
		 aMove = aGame[k2]; 
		 bMove = aMove.substr(k3,10);
                 for (k1 = 0; k1 <= 8; k1++)
                      {
                        x1 = bMove.substr(k1,1);
                        if (x1 == "0")
                            {
                       	      x2 = bMove; 
			      x2.replace(k1,1,"1");
			      x3 = MoveA2a(x2);
			      aCount = aCount + 1;
			      mbGame[aCount] = aMove + x2 + x3; 
			    } 
                      } 
               } 
          aLen = aCount; aCount = -1; 
	      for (k2 = 0; k2 <= aLen; k2++) aGame[k2] = bGame[k2];
	    } //314
	 
   bCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
	  aMove = aGame[k3]; bMove = aMove.substr(50,9); 
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	           {
	             x1 = ""; 
	             for (k1 = k2; k1 <= k2 + 2; k1++)
	                  {
	                    n1 = mCheck[k1];
	                    x1 = x1 + aPosit[n1];
			   }  
		        if (x1 == "222") 
			       {
			         bCount = bCount + 1; // 243
			         wGame[bCount] = aMove; 
				 goto aBottom;
			       }
		       }
		  aCount = aCount + 1;  
		  bGame[aCount] = aMove; 
		  aBottom: k1 = 0;
		} 
		
      aLen = aCount; aCount = -1; 
      for (k2 = 0; k2 <= aLen; k2++)
         {
		   aMove = bGame[k2]; bMove = aMove.substr(50,10); 
           for (k1 = 0; k1 <= 8; k1++)
                {
                  x1 = bMove.substr(k1,1);
                  if (x1 == "0")
                       {
                       	 x2 = bMove; 
			 x2.replace(k1,1,"1");
			 x3 = MoveA2a(x2);
			 aCount = aCount + 1;
			 aGame[aCount] = aMove + x2 + x3; 
		       }
                }
         } 
   
   aLen = aCount; aCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
	  aMove = aGame[k3]; bMove = aMove.substr(70,9);
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	           {
	             x1 = ""; 
	             for (k1 = k2; k1 <= k2 + 2; k1++)
	                  {
	                    n1 = mCheck[k1];
	                    x1 = x1 + aPosit[n1];
			  }  
		        if (x1 == "222") 
			       {
			         bCount = bCount + 1; 
			         wGame[bCount] = aMove;  
				 goto bBottom;
			       }
		       }
		  aCount = aCount + 1;  
		  bGame[aCount] = aMove; 
		  bBottom: k1 = 0;
		} 
	
  for (k1 = 0; k1 <= bCount; k1++)
       wGame[k1] = wGame[k1] + "w";
  aLen = aCount; 
   for (k1 = 0; k1 <= aCount; k1++)
        { 
          bCount = bCount + 1; wGame[bCount] = aGame[k1] + "t";	
        } 
  
  ofstream OutFile("GameB139x.txt", ios::out);
  for (k1 = 0; k1 <= bCount; k1++)
       OutFile << wGame[k1] << endl;
  OutFile.close();	  
}

void SetUp1()
 {   
   int k1, n1;
   string x1;
   ifstream InFile("TicA318.txt", ios::in);
   for (k1 = 0; k1 <= 318; k1++)
        {
          getline(InFile, x1);
          mMove[k1] = x1.substr(0,10); nMove[k1] = x1.substr(10,9) + " ";
	}
   InFile.close();
   
   string p1[] = {"A","B","C","D","E","F","G","H","I","a","b","c","d","e","f","g","h","i"};
   x1 = "0 1 2  A B C  a b c  3 4 5  D E F  d e f  6 7 8  G H I  g h i  ";
   for (k1 = 0; k1 <= 8; k1++)
         {
           n1 = k1 + 9;
           mIndex[k1] = x1.find(p1[k1],k1);
           nIndex[k1] = x1.find(p1[n1],k1); 
	} 
		 
   ifstream aInFile("GameA456aX.txt", ios::in);
     for (k1 = 0; k1 <= 456; k1++)
          getline(aInFile,mGame[k1]); 
   aInFile.close();
   
}
		  
 void aMain()
 { 
   int k1,n1;
   string x1;
   SetUp1();
   AllGames3();
   
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Part 4

int mCheck[] = {0,1,2,3,4,5,6,7,8,0,3,6,1,4,7,2,5,8,0,4,8,2,4,6};
string mMove[153],nMove[153];

string MoveA2a(string pMove)
 {   
   int k1;
   string x1;
   for (k1 = 0; k1 <= 152; k1++)
        if (pMove == mMove[k1]) break;
   x1 = nMove[k1];
   return x1;
}

 void MoveA2()
 {   
   int k1,k2,k3,n1,aCount = -1, bCount = -1,aLen = 7;
   string x1,x2, x3,aMove, bMove, aPosit[9];
   string aGame[140], bGame[140], wGame[140];
   
   for (k1 = 0; k1 <= 7; k1++)
        aGame[k1] = mMove[k1] + nMove[k1]; 
   
   for (k2 = 0; k2 <= aLen; k2++)
         {
		   aMove = aGame[k2]; bMove = aMove.substr(10,10);
           for (k1 = 0; k1 <= 8; k1++)
                {
                  x1 = bMove.substr(k1,1);
                  if (x1 == "0")
                       {
                       	 x2 = bMove; 
			 x2.replace(k1,1,"2");
			 x3 = MoveA2a(x2);
			 aCount = aCount + 1;
			 bGame[aCount] = aMove + x2 + x3; 
		      }
                }
         } 
   
   aLen = aCount; aCount = -1; bCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
	  aMove = bGame[k3]; bMove = aMove.substr(30,9);
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	           {
	             x1 = ""; 
	             for (k1 = k2; k1 <= k2 + 2; k1++)
	                  {
	                    n1 = mCheck[k1];
	                    x1 = x1 + aPosit[n1];
			  }  
		        if (x1 == "111") 
			       {
			         bCount = bCount + 1; //19
			         wGame[bCount] = aMove; 
				 goto aBottom;
			       }
		       }
		  aCount = aCount + 1;  
		  aGame[aCount] = aMove;  
		  aBottom: k1 = 0;
		} 
		
      aLen = aCount; aCount = -1;
      for (k2 = 0; k2 <= aLen; k2++)
         {
		   aMove = aGame[k2]; bMove = aMove.substr(30,10);
           for (k1 = 0; k1 <= 8; k1++)
                {
                  x1 = bMove.substr(k1,1);
                  if (x1 == "0")
                       {
                       	 x2 = bMove; 
			 x2.replace(k1,1,"2");
			 x3 = MoveA2a(x2);
			 aCount = aCount + 1;
			 bGame[aCount] = aMove + x2 + x3; 
		       }
                }
         }  
   
   aLen = aCount; aCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
		  aMove = bGame[k3]; bMove = aMove.substr(50,9);
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	           {
	             x1 = ""; 
	             for (k1 = k2; k1 <= k2 + 2; k1++)
	                  {
	                    n1 = mCheck[k1];
	                    x1 = x1 + aPosit[n1];
			  }  
		        if (x1 == "111") 
			       {
			         bCount = bCount + 1; // 123
			         wGame[bCount] = aMove; 
				 goto bBottom;
			       }
		       }
		  aCount = aCount + 1;  
		  aGame[aCount] = aMove;  
		  bBottom: k1 = 0;
		} 
	
	aLen = aCount; aCount = -1;	
	for (k2 = 0; k2 <= aLen; k2++)
         {
		   aMove = aGame[k2]; bMove = aMove.substr(50,10);
           for (k1 = 0; k1 <= 8; k1++)
                {
                  x1 = bMove.substr(k1,1);
                  if (x1 == "0")
                       {
                       	 x2 = bMove; 
			 x2.replace(k1,1,"2");
			 x3 = MoveA2a(x2);
			 aCount = aCount + 1;
			 bGame[aCount] = aMove + x2 + x3; 
		      }
                }
         }  	
	
	aLen = aCount; aCount = -1;
   for (k3 = 0; k3 <= aLen; k3++)
        {
		  aMove = bGame[k3]; bMove = aMove.substr(70,9);
          for (k2 = 0; k2 <= 8; k2++)
               aPosit[k2] = bMove.substr(k2,1);
          for (k2 = 0; k2 <= 21; k2+= 3)
	       {
	         x1 = ""; 
	         for (k1 = k2; k1 <= k2 + 2; k1++)
	              {
	                n1 = mCheck[k1];
	                x1 = x1 + aPosit[n1];
		      }  
		 if (x1 == "111") 
		     {
		       bCount = bCount + 1; //131 
		       wGame[bCount] = aMove; 
		       goto cBottom;
		     }
	     }
	aCount = aCount + 1;  
	aGame[aCount] = aMove;  
	cBottom: k1 = 0;
      } 
		
  aLen = bCount;
  for (k1 = 0; k1 <= aLen; k1++)
       wGame[k1] = wGame[k1] + "w";
  aLen = aCount; 
   for (k1 = 0; k1 <= aLen; k1++)
        { 
          bCount = bCount + 1; wGame[bCount] = aGame[k1] + "t";	
        }
  
  ofstream OutFile("GameB139x.txt", ios::out);
  for (k1 = 0; k1 <= bCount; k1++)
       OutFile << wGame[k1] << endl;
  OutFile.close();		 
}

void SetUp1()
 {   
   int k1,k2;
   string x1,x2;
   ifstream InFile("TicB152.txt", ios::in);
   for (k1 = 0; k1 <= 152; k1++)
        {
          getline(InFile, x1);
          mMove[k1] = x1.substr(0,10); nMove[k1] = x1.substr(10,9) + " ";
		}
   InFile.close();
}
		  
 void aMain()
 { 
   int k1,n1;
   string x1;
   SetUp1();
   MoveA2();
   
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Part 5

//Tic game: human vs computer. Computer does not lose (win or tie)
//Playing game is actually a search and find operation based on 
// 2 text files formed database. 
int mIndex[9],nIndex[9], mPlayer;
string mMove[319],nMove[319];

void Play3b(string pMove, string qMove)
 { 
   int k1,n1;
   string x1;
   string aMold = "0 1 2  _ _ _  _ _ _  3 4 5  _ _ _  _ _ _  6 7 8  _ _ _  _ _ _  ";
   // This k1 loop transforms a snapshot, e.g. "200010000" and "200010001" into
   // "0 1 2  2 _ _  _ _ _  3 4 5  _ 1 _  _ _ _  6 7 8  _ _ _  _ _ 1  ";
   // then separate into:

   // 012 2 _ _   2 _ _
   // 345 _ 1 _   _ 1 _
   // 678 _ _ _   _ _ 1  each line is 21 characters in length: 1 means player 1 and so is 2.

   for (k1 = 0; k1 <= 8; k1++)
         {
           x1 = pMove.substr(k1,1);
           if (x1 != "0")
               {
               	 n1 = mIndex[k1];
               	 aMold.replace(n1,1,x1);
	       }
	 }
  for (k1 = 0; k1 <= 8; k1++)
       {
         x1 = qMove.substr(k1,1);
         if (x1 != "0")
             {
               n1 = nIndex[k1];
               aMold.replace(n1,1,x1);
	     }
      }	 
  
  n1 = -21;
  for (k1 = 0; k1 <= 42; k1+= 21)    
       cout << aMold.substr(k1,21) << endl;
  cout << endl;	   
 }

string Play3a(string pMove)
 { 
   int k1;
   string x1;
   for (k1 = 0; k1 <= 152; k1++)
        if (pMove == mMove[k1]) break;
   // Using human's move as the key to retrieve the computer's answering move
    
   return nMove[k1];
 }
 
  void Play3()
 { 
   int k1,n1,Move1[] = {0,2};
   string x1, bMove,aWin;
   string aMove = "000010000"; // When the computer is player 1, its first move is square 4
   
   Play3b("000010000","000000000");
   for (k1 = 0; k1 <= 3; k1++)
        {
          cout << "Make a move now: ";
          cin >> n1;
          aMove.replace(n1,1,"2"); 
          x1 = Play3a(aMove); 
	  bMove = x1.substr(0,9); aWin = x1.substr(9,1);
	  Play3b(aMove,bMove);
          if (aWin == "w") break;
          aMove = bMove;	
	}  
	if (aWin == "w")
	    cout << "Game's over. You lost";
	else
	   cout << "Game's over. You tied"; 	   
} 

void Play2b(string pMove, string qMove)
 { 
   int k1,n1;
   string x1;
   string aMold = "0 1 2  _ _ _  _ _ _  3 4 5  _ _ _  _ _ _  6 7 8  _ _ _  _ _ _  ";
   for (k1 = 0; k1 <= 8; k1++)
         {
           x1 = pMove.substr(k1,1);
           if (x1 != "0")
               {
               	 n1 = mIndex[k1];
               	 aMold.replace(n1,1,x1);
	       }
	}
  for (k1 = 0; k1 <= 8; k1++)
         {
           x1 = qMove.substr(k1,1);
           if (x1 != "0")
               {
               	 n1 = nIndex[k1];
               	 aMold.replace(n1,1,x1);
	       }
	}	 
  
  n1 = -21;
  for (k1 = 0; k1 <= 42; k1+= 21)    
       cout << aMold.substr(k1,21) << endl;
  cout << endl;	   
}

string Play2a(string pMove)
 { 
   int k1;
   string x1;
   for (k1 = 0; k1 <= 318; k1++)
        if (pMove == mMove[k1]) break;
        
   return nMove[k1];
 }
 
  void Play2()
 { 
   int k1,n1;
   string x1, bMove,aWin;
   string aMove = "000000000";
   
   Play2b("000000000","000000000");
   for (k1 = 0; k1 <= 3; k1++)
        {
          cout << "Make a move now: ";
          cin >> n1;
          aMove.replace(n1,1,"1");
          x1 = Play2a(aMove); 
	  bMove = x1.substr(0,9); aWin = x1.substr(9,1);
	  Play2b(aMove,bMove);
          if (aWin == "w") break; // Game's over
          aMove = bMove;	
	}  
  if (aWin == "w")
     cout << "Game's over. You lost";
  else
    cout << "Game's over. You tied"; 
} 
 
 void SetUp1()
 {   
   int k1,n1;
   string x1;
   // To transform a snapshot into a string that can be displayed almost like graphical
   // we set up 2 sets of indexes (one for player 1 and another for player 2.
   // The Upcased letters are for player 1 and the lowcase ones are for player 2.
   // This is the mold "0 1 2  _ _ _  _ _ _  3 4 5  _ _ _  _ _ _  6 7 8  _ _ _  _ _ _  ";
   // e.g. snapshots "000010000" and "200010000": we use locate the position of
   // "1" in square 4  and them using mIndex[n] to get its proper place and replace the underline
   // into "1" For the second snapshot: we use nIndex[n1] to locate the place to replace with
   // "2" and "1"
   string p1[] = {"A","B","C","D","E","F","G","H","I","a","b","c","d","e","f","g","h","i"};
   x1 = "0 1 2  A B C  a b c  3 4 5  D E F  d e f  6 7 8  G H I  g h i  ";
   for (k1 = 0; k1 <= 8; k1++)
         {
           n1 = k1 + 9;
           mIndex[k1] = x1.find(p1[k1],k1);
           nIndex[k1] = x1.find(p1[n1],k1);
	 }  
   if (mPlayer == 1) // Human wants to be the first mover 
       {
	 ifstream InFile("TicA318.txt", ios::in);
         for (k1 = 0; k1 <= 318; k1++)
              {
          	getline(InFile,x1);
          	mMove[k1] = x1.substr(0,9);
          	nMove[k1] = x1.substr(10,10); 
	      }
         InFile.close();
       }
  else
       {
       	 ifstream InFile("TicB152.txt", ios::in); // To be the second mover
         for (k1 = 0; k1 <= 152; k1++)
              {
          	getline(InFile,x1);
          	mMove[k1] = x1.substr(0,9);
          	nMove[k1] = x1.substr(10,10); 
              }
        InFile.close();
      }
} 
 
 void aMain()
 { 
   cout << "Play games now. First Player type 1. Second Player type 2: ";
   cin >> mPlayer;
   SetUp1();
   if (mPlayer == 1)
       Play2();
   else
      Play3();
   }
 
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Section 5
Hanoi Towers (1 to 9 disks only)
Overview:
   In the Hanoi Towers game, we move disks within 3 stacks. There are only 3 possible
move types: 12,13,23 (12 means: a disk from Stack 1 to Stack 2, so on). We represent
1 with A, 2, B and 3 C. If the disk number, n, is 9, the required move count is:
pow(2,n) - 1 = 511. If n = 3 then pow(2,n) - 1 = 7. The 511 moves are the repetition 
of ABC (ABCABCABC....). All odd numbers smaller than 9 are the substring of 511. 
If the disk number, n, is 8 (an even number, the required move count is:
pow(2,n) - 1 = 255. The 255 moves are the repetition of BAC(13,12,23) All even numbers
smaller than 8 are the substring of the 255.
    Occasionally, we move a disk from A to B. And we see we can not do that
because the A's disk is bigger then the B's. In this case, we reverse the move.
We go B to A, instead of A to B.
  We represent 9 disks with the values of 1 - 9 (from smallest to the biggest).
We represent 3 stacks with a single integer array with the length of 27.
We display disk moves as follows (3 disks): 
S array:  Initial values After loading
  0 3 6     0 0 0           1 0 0
  1 4 7     0 0 0           2 0 0
  2 5 8     0 0 0           3 0 0
  -----     -----           -----
Move Sequence
 M1: 12    M2: 13    M3: 23
 0 0 0     0 0 0     0 0 0
 2 0 0     0 0 0     0 0 1
 3 1 0     3 1 2     3 0 2
 -----     -----     -----
 M4: 12    M5:13(31) M6: 23(32)  M7: 12 Task completed.
 0 0 0     0 0 0     0 0 0       0 1 0
 0 0 1     0 0 0     0 2 0       0 2 0
 0 3 2     1 3 2     1 3 0       0 3 0
 -----     -----     -----       -----
 Array S(0-2) = 000; S(3-5) = 123; S(6-8) = 000; 
Warning: some of the ideas from above are orignally 
from How to Program C++ by Deitel & Deitel T.R.Nieto.

Here is the whole pragram
int mStep[1022], mMove[1022],mStack[27];
string mNum[33];
ofstream OutFile("HanoiGame.txt", ios::out);

void Show4(int pDisk)
{
   int k1,k2, n1,n2;
      
   for (k2 = 0; k2 < pDisk; k2++)
        {
          n1 = k2;	
	  for (k1 = 1; k1 <= 3; k1++)		
               { 
                 n2 = mStack[n1];
                if (n2 == 10) n2 = 0;
       	        cout << n2 << " ";
       	        OutFile << n2 << " ";
       	        n1 = n1 + pDisk;
	       }
          cout << endl;	
          OutFile << endl;	
        }
  cout << endl;OutFile << endl; // You can see the game more clearly in HanoiGame.txt"
}
// Translate the 12, 13 ... into value change in Stack Array
// and export the repeated shows to the function above
void Play3()
{
   int k1,k2, n1,n2,aDisk,bDisk,aEnd,aStep,bStep,aPick,bPick,aSwap[24];
   string x1,x2, aMove;
   
   cout << "To play Hanoi Towers, enter disk number (2 to 9): ";
   cin >> aDisk;
   
   bDisk = aDisk -1; aEnd = pow(2,aDisk) - 2;
   for (k1 = 0; k1 <= 26; k1++) mStack[k1] = 10; // Initiate value 10 to the array (empty array
   for (k1 = 0; k1 < aDisk; k1++) mStack[k1] = k1 + 1;
   cout << "Play Hanoi Towers: Disk Number: " << aDisk << endl;
   OutFile <<   "Play Hanoi Towers: Disk Number: " << aDisk << endl;
   cout << "------" << endl;
   OutFile << "------" << endl;
   
   Show4(aDisk); // Display Hanoi Towers before moving disks
   bStep = ((aDisk  + 1) % 2) * 511; // Odd numbered Disks: 0 to 510 moves
                                     // Even numbered Disks: 510 to 1021
   for (k2 = 0; k2 <= aEnd; k2++)		
        {
          aStep = mMove[k2 + bStep]; 
          n1 = (aStep / 10 - 1) * aDisk; 
		  n2 = (aStep % 10 - 1) * aDisk; // Separate 12 to Stack 1 and Stack 2 etc.
		  aPick = n1 + bDisk; bPick = n2 + bDisk;  
          for (k1 = n1; k1 <= n1 + bDisk; k1++)
               if (mStack[k1] != 10) break;
		  aPick = k1;  // Pick up a disk to move		       
	      for (k1 = n2 + bDisk; k1 >= n2; k1--)
               if (mStack[k1] == 10) break;
		  bPick = k1; // Pick up a location 
		  mStack[bPick] = mStack[aPick]; mStack[aPick] = 10; 
		  // Drop a value (a disk) to the location. Reset the location to 10 (empty)  
	      Show4(aDisk); 
        }  
	 OutFile.close();
	 cout << "Go to 'HanoiGame.txt' for more detailed display." << endl;
  }

void Move2()
{
   int k1,k2, k3,n1,n2,aCount = -1,aStep,aPick,bPick,aSwap[24],aStack[27];
   aSwap[12] = 21; aSwap[13] = 31; aSwap[23] = 32; // When can not move 1 to 2 then reverse
  // This loop reverses the moves which can not be done. 
  // Can not move a bigger disk to on top of smaller one
  for (k3 = 0; k3 <= 511; k3+= 511) // Make a move list
       {
       	  for (k2 = 0; k2 <= 8; k2++) aStack[k2] = k2 + 1;
          for (k2 = 9; k2 <= 26; k2++) aStack[k2] = 10;
       	  for (k2 = k3; k2 <= k3 + 510; k2++)		
               {
                 aStep = mStep[k2];
                 n1 = (aStep / 10 - 1) * 9; 
		         n2 = (aStep % 10 - 1) * 9;
		         aPick = n1 + 8; bPick = n2 + 8; 
                 for (k1 = n1; k1 <= n1 + 8; k1++)
                      {
                         if (aStack[k1] != 10) // Value 10 means empty location in stack
		             {
			       aPick = k1; break;
			     } 	
		      }
	        for (k1 = n2; k1 <= n2 + 8; k1++)
                      {
                         if (aStack[k1] != 10)
		             {
				bPick = k1; break;
			     } 	
		      }
	             if (aStack[aPick] < aStack[bPick]) 
                     {
       	               if (aStack[bPick] != 10) bPick = bPick -1;
	              }
                 else
                     {
                       n1 = aPick; aPick = bPick; bPick = n1 -1;
                       aStep = aSwap[aStep];
	             }
                 aStack[bPick] = aStack[aPick]; aStack[aPick] = 10;   
	         aCount = aCount + 1;
	         mMove[aCount] = aStep; 
               } 
       }
}

 void SetUp1()
 {   
   int k1,k2, n1; 
   string x1,x2,aStep = "<=G=
Section 6
Example of String Formatting (Print a 4 months in a row commercial styled calendar

Part 1: Print one thousand years' calendar (1776 to 2775)
        Within the 1000 years, there are only 14 unique years (2 groups of 7: 365 days + 366 days
        those years starting on sun, mon .... sat total 7.)
int pMonth[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
string mNum[32],nNum[40], mMonth, mYear[14]; 

void GetYear3()// Make 1000 years' calendar and name it "1776-2775b.txt"
 {   
   int k1,k2, k3,k4,n1,n2;
   string x1,x2, x3,aMonth[13],aWeek,aYear[2776], bYear, cYear[18], aTitle[2776], aLine; 
   char c1[18];
   aMonth[0] = "       JANUARY                FEBRURARY                 MARCH                   APRIL           ";
   aMonth[6] = "         MAY                    JUNE                    JULY                   AUGUST           ";
   aMonth[12] = "      SEPTEMBER                OCTOBER                NOVEMBER                DECEMBER          ";
   aWeek = "Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa    ";
   for (k1 = 1; k1 <= 96; k1++) aLine = aLine + " ";	
   x2 = aLine.substr(0,37) + "Calendar Year of "; 
   for (k1 = 1776; k1 <= 2775; k1++)
         {
           ostringstream convert; 
	   convert << k1; x1 = convert.str();
	   aTitle[k1] = x2 + x1 + aLine.substr(0,38); // Title Year
	 }
		 
   ifstream InFile("1776-2775a1.txt", ios::in);
   for (k1 = 1776; k1 <= 2775; k1++) //Load up 1000 unformetted years
        InFile >> aYear[k1];
   InFile.close();
   
   ofstream OutFile("1776-2775b.txt", ios::out);
   for (k4 = 1776; k4 <= 2775; k4++)
         {
	   bYear = aYear[k4]; 
           n2 = -1;
           for (k3 = 0; k3 <= 336; k3+= 168) // A calendar is laid out in 3 parts and 4 columns
                {
         	  x1 = bYear.substr(k3,168);
		  for (k2 = 0; k2 <= 35; k2+= 7)
                       {
		         n1 = k2; x2 = "";
                         for (k1 = 1; k1 <= 4; k1++)
                              {
                                x2 = x2 + x1.substr(n1,7) + "0"; // "0" separates a month from another
                                n1 = n1 + 42; // A month is 42 characters and six rows
                              } 
			 n2 = n2 + 1; // Row adding up
                         cYear[n2] = x2; 
                       } 
                }

           for (k3 = 0; k3 <= 17; k3++) // Starting formatting work.
                {
		  x1 = cYear[k3]; 
                  x1.copy(c1,32); x2 = "";
                  for (k2 = 0; k2 <= 31; k2++)
                       {
       	                 n1 = int(c1[k2]) - 48;
       	                 x2 = x2 + nNum[n1] + " ";
	               } 
	              cYear[k3] = x2; 
                }
	
           bYear = aTitle[k4] + aLine;
           for (k3 = 0; k3 <= 12; k3+= 6)// String up everything into one single variable
                { 
	          bYear = bYear + aMonth[k3] + aWeek; //Add year, month and week titles
	          for (k2 = k3; k2 <= k3 + 5; k2++)	
                       bYear = bYear + cYear[k2];	          	
		} 
	  OutFile << bYear << endl; // Save 1000 years' calendar into "1776-2775b.txt"
       }
   /*
   ifstream aInFile("1776-2775b.txt", ios::in); //This is how to print out calendars.
   for (k1 = 1776; k1 <= 2775; k1++)
         {
           getline(aInFile,x2); if (k1 == 2024) break;
         }
   aInFile.close();
   ofstream aOutFile("Calen.txt", ios::out);
   n1 = 0;
   for (k1 = 0; k1 <= 25; k1++)
        {
           x1 = x2.substr(n1,96); 
           n1 = n1 + 96;
           aOutFile << x1 << endl;
		}
  aOutFile.close(); */
}

void kYear2() // Make unformatted years
 {   
   int k1,k2, k3,n1,n2, d1,aYear[2776], bYear[2776];
   string x1,x2;
   for (k1 = 1775; k1 <= 2775; k1++)
        aYear[k1] = 1;
   for (k1 = 1776; k1 <= 2775; k1+= 4)
         {
           n1 = 2;
           if ((k1 % 100 == 0) && (k1 % 400 != 0))
               n1 = 1;
           aYear[k1] = n1;
	}
   d1 = 1;
  for (k1 = 2023; k1 >= 1775; k1--)
       d1 = (d1 - aYear[k1] + 7) % 7;
  
  for (k1 = 1776; k1 <= 2775; k1++)     
       {
       	 
       	 d1 = (d1 + aYear[k1 - 1]) % 7;
       	 bYear[k1] = (aYear[k1] - 1) * 7 + d1;
       }
		  
  ofstream OutFile("1776-2775a1.txt", ios::out);	
  for (k1 = 1776; k1 <= 2775; k1++)
       {
       	 n1 = bYear[k1]; // n1's ranges between 0 to 13. 0 to 6 are common years. 7 - 13: the Lead
       	 OutFile << mYear[n1] << endl;
       }
  OutFile.close(); 	   
 }

 void SetUp1()
 {   
   int k1,k2, k3,n1,n2, aCount = -1;
   string x1,x2, aMonth[13], bMonth[13], cMonth,aZero = "00000000000000000000";
   mNum[0] = " ";
   for (k1 = 1; k1 <= 31; k1++)
         {
           x1 = char(k1+48); mNum[k1] = x1;	
           mMonth = mMonth + x1;
	 }
		 
  for (k2 = 0; k2 <= 3; k2++) // Make 32 formatted numbers		 
       {
         x1 = mNum[k2];
         for (k1 = 0; k1 <= 9; k1++)
              {
                x2 = mNum[k1];
                if (k1 == 0) x2 = "0";
                aCount = aCount + 1;
                nNum[aCount] = x1 + x2;
                if (aCount == 31) break;
              }
      }
   nNum[0] = "  ";
   for (k1 = 1; k1 <= 12; k1++)
        {
          n1 = pMonth[k1];
	  aMonth[k1] = mMonth.substr(0,n1);
	}
   n2 = -1;	
   for (k3 = 1; k3 <= 2; k3++) // Get 14 year's types
         {
           for (k2 = 0; k2 <= 6; k2++)
                {
                  n1 = k2; x2 = "";
		  for (k1 = 1; k1 <= 12; k1++)
                       {
                         n1 = (n1 + pMonth[k1-1]) % 7;
                         x1 = aZero.substr(0,n1) + aMonth[k1] + aZero; //Pad months into 42 in length
                         x2 = x2 + x1.substr(0,42);
                       }
                 n2 = n2 + 1;
                 mYear[n2] = x2;     
                }
           pMonth[2] = 29; aMonth[2] = aMonth[2] + "M"; // Process lead years.
           
         } 
  }

Part 2: Make Holiday List
string mNum[32],nNum[32];

void MoldUp4() // First I make a mold of holidays
{
  int k1, k2, n1, n2, bMark[13];
  string x1, aDay, bDay,aFill[13];
  string aMark[] = 
         {"A00","A05","A06","A10","A12","A01","A02","A03","A04","A07","A08","A09","A11"};
  x1 = "New Year: A00 Jan  1.King:     Mon Jan A01Presiden: Mon Feb A02"; 
  x1 = x1 + "Dayligh1: Sun Mar A03Memorial: Mon May A04Junteen:  A05 Jun 19.";   
  x1 = x1 + "Independ: A06 Jul  4.Labor:    Mon Sep A07Columbus: Mon Oct A08"; 
  x1 = x1 + "Dayligh2: Sun Nov A09Veterans: A10 Nov 11.Thanksgi: Thu Nov A11"; 
  x1 = x1 + "Christma: A12 Dec 25. ";
  
  for (k1 = 0; k1 <= 12; k1++)
       bMark[k1] = x1.find(aMark[k1],0);
       
  ifstream InFile("2022-2775a.txt", ios::in); // Month order: sun week, month week
  ofstream OutFile("2022-2775h.txt", ios::out);     
  for (k2 = 2022; k2 <= 2775; k2++)
       {
         getline(InFile,bDay); 
	 aDay = x1;  
         n1 = -3;
         for (k1 = 0; k1 <= 12; k1++)
              {
       	        n1 = n1 + 3;
       	        aFill[k1] = bDay.substr(n1,3);
	      }
         for (k1 = 0; k1 <= 12; k1++)
              {
       	        n1 = bMark[k1];
       	        aDay.replace(n1,3, aFill[k1]); 
	      }
	    OutFile<< aDay << endl;
       }
  OutFile.close();
  InFile.close();
  n1 = -21;
  for (k1 = 1; k1 <= 13; k1++)
        {
          n1 = n1 + 21;
          cout <<  aDay.substr(n1,21) << endl;
	} 
    
}
void Holiday3() // Holiday pileup from 2022 to 2775
{
  int k1, k2, k3, k4,n1, n2, n3, n4;  // "01" means month 1 and day 1: New Year's Day
  string x1, x2, x3, Year1[2776],Year2[504],Year3[2776], aDay[] = {"01","5C","64",":;",";I"};
                  // "012" means month 1, week 2 (monday) and order 3: Martin Day
  string bDay[] = {"012","112","201","414","810","911",":00",":43"};
  string cDay,dDay[2276], aWeek[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
  char c1[3];
  
  ifstream aInFile("1776-2775a1.txt", ios::in);
  for (k1 = 1776; k1 <= 2775; k1++)
       aInFile >>  Year1[k1]; 
  aInFile.close();
  ifstream bInFile("1776-2775a2.txt", ios::in);
  for (k1 = 1776; k1 <= 2775; k1++)
       bInFile >>  Year2[k1]; 
  bInFile.close();
  
  ofstream OutFile("2022-2775a.txt", ios::out); // Make unformatted holiday list (2022-2775)     
  for (k2 = 2022; k2 <= 2775; k2++)
       {
	     x1 = Year1[k2]; cDay = "";
         for (k1 = 0; k1 <= 4; k1++)
              {
	        x2 = aDay[k1]; 
	        x3 = x2.substr(0,1);
		x3.copy(c1,1); n1 = int(c1[0]) - 48;
                x3 = x2.substr(1,1);
                n2 = n1 * 42;
                n1 = x1.find(x3, n2) % 7;
                cDay = cDay + aWeek[n1];
              } 
         x1 = Year2[k2];    
         for (k1 = 0; k1 <= 7; k1++)
              {
	        x2 = bDay[k1]; x2.copy(c1,3);
                n1 = int(c1[0]) - 48; // ASCII number of Character "0" is 48 and "1" is 49
                n2 = int(c1[1]) - 48;
                n3 = int(c1[2]) - 48;
                n4 = n1 * 42 + n2 * 6 + n3;
                x2 = x1.substr(n4,1);
                if (x2 == "0")  x2 = x1.substr(n4 -1,1);
                x2.copy(c1,1);
                n1 = int(c1[0]) - 48;
                cDay = cDay + nNum[n1];
              } 
         OutFile << cDay << endl;
       }
 // 2022 holiday list: SatSunMonFriSun17 21 13 30  5 10  6 24 
 // New Year: Sat; Junteen: Sun; Independence: Mon; Veterans: Fri; Christmas: Sun
 // Martin Jan 17; Presidents Feb 21; ... Thanksgiving: Nov 24
}

void LineUp2()
{
  int k1, k2, k3,k4,n1, n2;
  string x1, x2, Year1[2776], Year2[504], Year3[2776];
  ifstream InFile("1776-2775a1.txt", ios::in);
           for (k1 = 1776; k1 <= 2775; k1++)
           InFile >> Year1[k1];
  InFile.close();
  
// Change conventioned order of month into week by week  month order.
// Order of months now is: sun,mon,..sat
  ofstream OutFile("1776-2775a2.txt", ios::out);
  for (k4 = 1776; k4<= 2775; k4++)
        {
	   x1 = Year1[k4];
          for (k3 = 0; k3<= 503; k3++)
               Year2[k3] = x1.substr(k3,1);
          n1 = -42; x1 = "";
          for (k3 = 1; k3<= 12; k3++)
                {
		  n1 = n1 + 42;
                  for (k2 = n1; k2<= n1 + 6; k2++)
                        {
			  n2 = k2;
                          for (k1 = n2; k1<= n2 + 35; k1+= 7) 
                                {
				   x2 = Year2[k1];
                                   if (k1 == n2 && x2 == "0") x2 = "";
                                   x1 = x1 + x2;
                                }
                          if (x1.length() % 6  != 0) x1 = x1 + "0";
                        }
                }
          OutFile << x1 << endl;
        }
  OutFile.close();
}

 void SetUp1()
 {   
   int k1,k2,n1;
   string x1,x2;
   for (k1 = 0; k1 <= 31; k1++)
        mNum[k1] = char(k1+48);
   n1 = -1;
   for (k2 = 0; k2 <= 3; k2++)
         {
           x1 = mNum[k2];
           if (k2 == 0) x1 = " ";
           for (k1 = 0; k1 <= 9; k1++)
                 {
                 	n1 = n1 + 1;
                 	nNum[n1] = x1 + mNum[k1] + " ";
                 	if (n1 == 31) k1 = 10;
				 }
		 }   
 }
		  
 void aMain()
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   SetUp1();
   LineUp2();
   Holiday3();
   MoldUp4();
 }

Part 3: Print 2 months' calendar //For vacation planning
        (If starting date < 16: previous month + the date's month, else the date's
     //  month + next month
string mNum[32],nNum[32],mYear[2776],nYear[2776],mDay[2776];

void P2Months() 
 {
   int k1,k2,n1, n2, aCount = -1, aYear, Year1, Year2,aMonth,Month1,Month2,aDay;
   string x1,x2, d1; 
   string m1[] = {"Jan","Feb","Mar","Apr","May","Jun","July","Aug","Sep","Oct","Nov","Dec"};
   string w1 = "Su Mo Tu We Th Fr Sa    Su Mo Tu We Th Fr Sa   "; 
   char c1[96];
   cout << "To print 2-month side-by-side calendar,enter a date mm/dd/yyyy: ";
   cin >> x1;
   x2 = x1.substr(6,4); aYear = atoi(x2.c_str()); 
   x2 = x1.substr(0,2); aMonth = atoi(x2.c_str()) -1; 
   x2 = x1.substr(3,2); aDay = atoi(x2.c_str()); 
   Year1 = aYear; Year2 = aYear;
   if (aMonth == 0 && aDay < 16)
       Year1 = aYear - 1;
   else if (aMonth == 11 && aDay > 15)
       Year2 = aYear + 1;
       
   Month1 = aMonth; Month2 = aMonth;   
   if (aDay < 16)
       Month1 = (aMonth + 11) % 12;
   else if (aDay > 15)
       Month2 = (aMonth + 1) % 12;
   
    ostringstream cvt1;   cvt1 << Year1; x1 = cvt1.str();
    ostringstream cvt2;   cvt2 << Year2; x2 = cvt2.str();
    d1 = "       " + m1[Month1] + " " + x1;
    d1 =  d1 + "               " + m1[Month2] + " " + x2;
    
   x1 = nYear[Year1]; x2 = nYear[Year2];
   n1 = Month1 * 42; x1 = x1.substr(n1,42);
   n1 = Month2 * 42; x2 = x2.substr(n1,42);
   x1 = x1 + x2; x2 = "";
   
   n1 = 0; n2 = 42;
   for (k1 = 1; k1 <= 6; k1++)
        {
          x2 = x2 + x1.substr(n1,7) + "0" + x1.substr(n2,7) + "0";	
          n1 = n1 + 7; n2 = n2 + 7; 
        } 
    cout << d1 << endl;
	cout << w1 << endl;
	x2.copy(c1,96); n1 = -1;
	for (k2 = 0; k2 <= 80; k2+= 16)
	     { x1 = "";
		   for (k1 = k2; k1 <= k2 + 15; k1++)
	            {
	      	      n1 = n1 + 1;
	      	      n2 = int(c1[n1]) - 48;
	      	      x1 = x1 + nNum[n2] + " ";
	      	    } cout << x1 << endl;
	     }  
 }

void PrintCalen()
 {   
   int k1,n1, n2;
   string x1,x2, aYear, bYear, aDay;
   cout << "Enter the number for the year to print a calendar:  ";
   cin >> aYear;
   n1 = atoi(aYear.c_str());
   bYear = mYear[n1];
   x1 = aYear + "Cal.txt";
   ofstream aOutFile(x1.c_str(), ios::out);
   n2 = -96;
   for (k1 = 0; k1 <= 25; k1++)
         {
           n2 = n2 + 96;
           aOutFile << bYear.substr(n2,96) << endl;
	 }
   aOutFile.close()		 ;
   
   cout << "Print a holiday list (2022 to 2775)? Type 1 for yes and -1 for no ";
   cin >> n2;
   if (n2 == 1) 
       {
       	 aDay = mDay[n1];
       	 x1 = aYear + " Holidays.txt";
       	 ofstream bOutFile(x1.c_str(), ios::out);
       	 bOutFile << "  Holidays of " + aYear << endl;
         n2 = -21;
         for (k1 = 0; k1 <= 12; k1++)
               {
               	n2 = n2 + 21;
               	bOutFile << aDay.substr(n2,21) << endl;
	       }
         bOutFile.close();	
      }
 }

 void SetUp1()
 {   
   int k1,k2, n1,n2,aCount = -1;
   string x1,x2;
   for (k1 = 0; k1 <= 31; k1++)
        mNum[k1] = char(k1+48);
   for (k2 = 0; k2 <= 3; k2++)		 
         {
           x1 = mNum[k2];
           if (k2 == 0) x1 = " ";
           for (k1 = 0; k1 <= 9; k1++)
                {
                  x2 = mNum[k1];
                  if (k1 == 0) x2 = "0";
                  aCount = aCount + 1;
                  nNum[aCount] = x1 + x2;
                  if (aCount == 31) break;
                }
		 }
  nNum[0] = "  ";    
        
   ifstream aInFile("1776-2775b.txt", ios::in);
   for (k1 = 1776; k1 <= 2775;k1++)
        getline(aInFile,mYear[k1]);
   aInFile.close();
   ifstream bInFile("1776-2775a1.txt", ios::in);
   for (k1 = 1776; k1 <= 2775;k1++)
        bInFile >> nYear[k1];
   bInFile.close();
   
   ifstream cInFile("2022-2775h.txt", ios::in);
   for (k1 = 2022; k1 <= 2775;k1++)
        getline(cInFile,mDay[k1]);
   cInFile.close();
 }

Section 7

Simulateing Enigma in encoding, and decoding functions, and breaking Enigma code
string mNum[95]; //Use all non-functioning Windows supported keys to do the job.
string mName = "Text1.txt"; // I use the full text of Declaration of Independence. 
string mKey = "Allons! Enfants de la Patrie"; //Use this sentence to encode and decode text.
//int mLen = 23, nLen = 24, nKey[26]; // The length of the key

void Break4() // Use the frequency count to retrieve the key
{
 int k1, k2, k3, n1, n2, aCount,aLen, aText[50000], bText[50000], aFilter[96] = {0},aKey;
 string x1, x2, aError = "~`*{[}]/";
 char c1[50000];
 for (k1 = 0; k1 <= 94; k1++) // Make 95 string equivalence of the Arabic
      mNum[k1] = char(k1+32); 
 ifstream InFile("TextB.txt", ios::in); // TextB.txt is the encoded text of the Declaration
  getline(InFile,x1);
  InFile.close(); 
  aLen = x1.length() - 1; // The character count
  x1.copy(c1,aLen + 1); //Copy the text into an array of char
  for (k1 = 0; k1 <= aLen;k1++)
       aText[k1] = int(c1[k1]) - 32; //Change the char into Arabic

  for (k3 = 15; k3<= 25; k3++) // Predict the length of the key
        {
	   aCount = 0;
           for (k2 = 0; k2<= aLen; k2++)
                bText[k2] = aText[k2]; // Make a copy of the encoded text, and then trial and error
           for (k2 = 0; k2<= k3 - 1; k2++)
                 {
		   for (k1 = k2; k1<= aLen; k1+= k3) // Flip rows into columns
                        {
		          n1 = bText[k1];
                          aFilter[n1] = aFilter[n1] + 1; // Frequency count 
                        }
                   n1 = 0;
                   for (k1 = 0; k1<= 94; k1++)
                         {
                           if (n1 < aFilter[k1])
			       {
				 n1 = aFilter[k1]; aKey = k1; 	
				} // Assume the highest count is the key
			   aFilter[k1] = 0;		
			 }
                   for (k1 = k2; k1<= aLen; k1+= k3)
			{
			   n1 = bText[k1];
                           bText[k1] = (n1 - aKey + 95) % 95; // Decode column by column
                           if (k2 == 0)
                               {
                               	 n1 = bText[k1];
                               	 n2 = aError.find(mNum[n1], 0); // Count the error characters
                               	 if (n2 != -1)
                               	      {
                               	      	aCount = aCount + 1;
                               	      	if (aCount == 4) goto aSkip; //If count is 4, abort
				      }
			       }
                         }
                 }
            aSkip: k1 = 0;   
            if (aCount < 4) break; // If count < 4, success and exit 
        }

   x2 = "";
   for (k1 = 0; k1<= aLen; k1++)
         {
           n1 = bText[k1];
	   x2 = x2 + mNum[n1]; // String the array into one single variable	
	 }
  ofstream OutFile("TextD.txt", ios::out); //TextD.txt is the decoded text.
  OutFile << x2 << endl;
  OutFile.close(); 
}

void Decode3()
{
  int k1, k2, n1, n2, aLen, aText[50000];
  string x1, x2, bText[50000]; 
  char c1[50000];
  ifstream InFile("TextB.txt", ios::in); // TextB.txt is the encoded text
  getline(InFile,x1);
  InFile.close(); 
  aLen = x1.length() - 1;
  x1.copy(c1,aLen + 1);
  for (k1 = 0; k1 <= aLen;k1++)
        aText[k1] = int(c1[k1]) - 32; 
        
  for (k2 = 0; k2<= mLen; k2++)
        {
	  n1 = nKey[k2];
          for (k1 = k2; k1<= aLen; k1+= nLen)
                {
		  n2 = (aText[k1] - n1 + 95) % 95; //Deduct the key Arabic
                  bText[k1] = mNum[n2];
                }
        }

 x2 = "";
 for (k1 = 0; k1<= aLen; k1++)
 x2 = x2 + bText[k1];
 ofstream OutFile("TextC.txt", ios::out); //TextC.txt is the decoded text matching TextA.txt
  OutFile << x2 << endl;
  OutFile.close();
}

void Code2() 
{
 int k1, k2, n1, n2, aLen, aText[50000];
 string x1, x2, bText[50000]; 
 char c1[50000];
 ifstream InFile("TextA.txt", ios::in); // TextA.txt is the plain text
 getline(InFile,x1);
 InFile.close(); 
 aLen = x1.length() -1;
 x1.copy(c1,aLen + 1);
 for (k1 = 0; k1<= aLen; k1++)
      aText[k1] = int(c1[k1]) - 32; //Change string into Arabic
       
 for (k2 = 0; k2<= mLen; k2++)
       {
	 n1 = nKey[k2];
         for (k1 = k2; k1<= aLen; k1+= nLen) 
               {
               	 n2 = (aText[k1] + n1) % 95; // Add the key to the Arabic
               	 bText[k1] = mNum[n2]; // Change the Arabic to chacters.
	       }
       }
    
 x2 = "";
 for (k1 = 0; k1<= aLen; k1++)
      x2 = x2 + bText[k1];
 ofstream OutFile("TextB.txt", ios::out); //TextB.txt is the coded text.
  OutFile << x2 << endl;
  OutFile.close(); 
}

 void Load1()
 {   
   int k1, n1, n2,aLen;
   string x1, x2, aText, bText;
   char c1[26];
   for (k1 = 0; k1 <= 94; k1++)
        mNum[k1] = char(k1+32); 
      
   mKey.copy(c1,nLen); 
   for (k1 = 0; k1 <= mLen; k1++)
         {
           nKey[k1] = int(c1[k1]) - 31; //Change key into Arabic
	 } 
   ifstream InFile(mName.c_str(), ios::in);
   do
    {
       getline(InFile,x1); // Change the multi-lines text into a single variable
       aText = aText + x1; 
    }  while (!InFile.eof());
   InFile.close(); 

   aLen = aText.length() - 1;
   for (k1 = 0; k1 <= aLen; k1++)
         {
           x1 = aText.substr(k1,1); 
           if (x1 == " " && x2 == " ") goto aSkip;
           if (x1 >= " " && x1 <= "~") // Filter out any character that is not in the keyboard.
                {
                  bText = bText + x1;
		}
	   aSkip: n1 = 0;
	   x2 = x1;
	 } 
		
  ofstream OutFile("TextA.txt", ios::out); // TextA.txt is the plain text.
  OutFile << bText << endl;
  OutFile.close(); 
  }
		  
 void aMain()
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   Load1();
   Code2();
   Decode3();
  Break4(); 
  
 }
int main(int argc, char** argv)
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Section 8: Computer-assisted Poker Playing
C++ program, solving the problem of poker game playing
This program focuses on "recognizing, organizing and creating numerical patterns".
(The problem is listed in a C++ textbook)

Overview
The program is consisted of 3 parts.
Part 1
   Build a database in the form of textfile structured for fast and convenient data
retrieval (Inputing a hand and output a string used as the value of the hand.)
Part 2
   Simulate a million games (A game means a dealer vs 4 players and resulted in 4 bets)
The program sums bets' win or loss on two different game playing. Game Type A: An all
by-chance. Game Type B. The dealer is allowed for 3-card replacement, but the players 
are not. The program decides how the replacement is done.
Part 3
   Computer assisted game playing. The program assumes the role of the dealer while the 
players are human. When the program does better replacement decisions than human,
it wins more bets, vice versa.
Logistics
   The program uses ASCII numbers for coded data representation. 
   52 cards are reprensented as follows:
F: face value: S: suite value
F\S  Arabic        ASCII  
    0  1  2  3    0  1  2  3
    -----------   -------------
0   0 13 26 39    0  =  J  W      39
1   1 14 27 40    1  >  K  X      40
2   2 15 28 41    2  ?  L  Y      41 
3   3 16 29 42    3  @  M  Z      42
4   4 17 30 43    4  A  N  [      43
5   5 18 31 44    5  B  O  \      44
6   6 19 32 45    6  C  P  ]      45
7   7 20 33 46    7  D  Q  ^      46
8   8 21 34 47    8  E  R  _      47
9   9 22 35 48    9  F  S  `      48
10 10 23 36 49    :  G  T  a      49
11 11 24 37 50    ;  H  U  b      59
12 12 25 38 51    <  I  V  c      51
(Notice: the 52 ASCII numbers are consecutive.
 Write arabic on top of the card, and the ASCII on the bottom.)

For the hand's score, use ASCII: d e f g h i j k l m  n  o  p  q
                      Arabic:    0 1 2 3 4 5 6 7 8 9 10 11 12 13
Cards 0 = J W are counted the greatest value: q (13) except in hands which face values are 01234,
they are counted value d (0)
The first hand and score are: 01234lh...... It reads card 0,1,2,3,4, hand type l (8)
within type values h (4). 01235iqigfed 's type: i and within type value: qigfe (13,5,3,2,1). 
The suite value: d (0): This d serves as a tie break when 2 hands have the same face value.

Hand Types
Straight Flush l (8)        40
Four Kind      k (7)       624
Full House     j (6)     3,744
Flush          i (5)     5,108
Straight       h (4)    10,200
Three Kind     g (3)    54,912
Two Pairs      f (2)   123,552
One Pair       e (1) 1,098,240
High Card      d (0) 1,302,540
Total:               2,598,960

Function Explanation:
Part 1 (Build a hand-score database):
A: Permulate all possible hands from 52 cards. Save the hands to a textfile named "2598959";
B: Determine all hands' types (d to l) and add one letter to each hand and save it as "2598959a"
C: Determine all hands' within-type scores and attach the scores to all hands.
D: Structure the 2,598,960 hands into 25989 lines (100 hands per line except last line has 
   only 60 hands);
E: Add a padder line "*********" to signal this is end line.
F: Name the file as "25990f". All hands are arranged in ascending order.

Part 2 (Play a million games): 
A: Open "25990f.txt" and load data into 2 arrays: mHead(n) and mLine(n).
   mHead(n) are 5-letter line head and mLine(n) are the whole line data (hand names and
   their scores). Set up a function to receive a hand and to return a score;
   The search is a dictionary- style 2-step data retrieval. An input hand passes through  
   a 0 to 25990 for loop, comparing the hand with the mHead(n). When the hand is lesser than
   mHead(n), the loop breaks. We store mHead(n-1) into variable x. Then n1 = x.find(hand,0) and
   Score = x.substr(n1,12). The first 5 letters are a hand's name. The 6th letter is hand type.
   And the 7 to 12 letters are the within-type score.
B: Generate one million sets of shuffled 28 cards (The first 25 cards are playing cards
   and the last 3 are replacement cards). The first 5 letters are the dealer's hand.
   Save the data into "Game1M.txt"
C: Open "Game1M.txt" and load data to a variable line by line. Send the dealer's hand into a
   replacement function. The function first retrieves the hand type: if the hand is stronger
   than 3 kind, no replacement. If it is high card and one pair, replace 3 cards. 2 pairs - one
   card and 3 kind - 2 cards. Insert the replaced hand after the original hand. Now we have 
   6 hands and scores per line. Save the 1 million lines data ro "Score1M.txt".
D: Load textfile "Score1M.txt". Each line is formated as below:
   @LMV`egpmf..@CMQWegqkj..07;GPdqonkj.9HO^cdpomki.ABKTUdonihe.8DR\beloki..
   It has 6 hand-scores.
   @LMV`egpmf..   @CMQWegqkj..    07;GPdqonkj.   9HO^cdpomki.   ABKTUdonihe.    8DR\beloki..
   @LMV` egpmf.. @CMQW egqkj..    07;GP dqonkj.  9HO^c dpomki.  ABKTU donihe.   8DR\b eloki..
   dealer pri     dealer post     Player1        P2             P3              P3
   First we compare hand1 against hand 3,4,5,6.
   If H1 > P1 then Win count = Win count + 1: If H1 < P1 then Win count = Win count - 1: 
   Next we compare hand2 against hand3,4,5,6.
   e.g. H1 (egpmf) > dqonkj and  > dpomki and > donihe but < eloki, the Win count is 2

Part 1
string mName[] = {"2598959a.txt","2598959b.txt"};
string mNum[52],nNum[14];

void LineUp13() // Change a file of 2,598,959 lines into one with only 25990 lines.
{
  int k1, k2, n1, n2;
  string x1, x2,aMove[25991];
  ifstream InFile("2598959b.txt", ios::in);
  n1 = 99; 
  for (k2 = 0; k2 <= 25989; k2++)
       {
	 if (k2 == 25989) n1 = 59;
         x2 = "";
         for (k1 = 0; k1 <= n1; k1++)
              {
              	InFile >> x1;
              	x2 = x2 + x1;
	      }
        aMove[k2] = x2;
       }
  InFile.close();
  ofstream OutFile("25990f.txt", ios::out); //Change 2598959 lines to 25989 line
  for (k1 = 0; k1 <= 25989; k1++)
       OutFile << aMove[k1] << endl;
  OutFile << "xxxxxxxxxxxx" << endl;
OutFile.close();
}

// Hand 01234, is the weakest Straight Flush: score 4 4
// and 09:;<  is the strongest one: score 13 q  
void Get8P12(int pFile)
{
 int k1, k2, n1, n2 = 0;
 string x1, aHand, aName, aFace[13], L1 = "l";
 char c1[6]; 
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
   ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	     InFile >> aHand; aHand.copy(c1,6);
	     if (aHand.length() == 6 && aHand.substr(5,1) == L1)
              {	
                for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       aFace[n1] = nNum[n1];
                     }    
                x1 = "";
                for (k1 = 12; k1 >= 0; k1--)
                      {
                      	x1 = x1 + aFace[k1]; aFace[k1] = "";
		      }
                if (x1 == "ponmd")
                    x1 = "q";
                else
                    x1 = x1.substr(0,1); // The card that has the strongest face value
                aHand = aHand + x1 + ".....";
                n2 = n2 + 1;
				
              }     
         OutFile << aHand << endl; //Save non straight flush un-changed.     
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

// For kind 4 hands, we only need the face value of one of kind 4ed card.
void Get7P11(int pFile)
{
 int k1, k2, n1, n2 = 0, bFace[14] = {0};
 string x1, aHand, aName, Ka = "k";
 char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	 InFile >> aHand; aHand.copy(c1,6);
	 if (aHand.length() == 6 && aHand.substr(5,1) == Ka)
              {	
                for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13;
                       bFace[n1] = bFace[n1] + 1;
                     } 
                for (k1 = 13; k1 >= 1; k1--)
                     {
		       if (bFace[k1] == 4) x1 = nNum[k1];
		       bFace[k1] = 0;
                     }
               aHand = aHand + x1 + ".....";
               n2 = n2 + 1;
              }     
         OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

// For Full House hands, we only need the face value of one of the trippled cards
void Get6P10(int pFile)
{
 int k1, k2, n1, n2 = 0, bFace[14] = {0};
 string x1, aHand, aName,j1 = "j";
 char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	 InFile >> aHand; aHand.copy(c1,6);
	 if (aHand.length() == 6 && aHand.substr(5,1) == j1)
              {	
                for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13;
                       bFace[n1] = bFace[n1] + 1;
                     } 
                for (k1 = 13; k1 >= 1; k1--)
                     {
		       if (bFace[k1] == 3) x1 = nNum[k1];
		       bFace[k1] = 0;
                     }
               aHand = aHand + x1 + ".....";
               n2 = n2 + 1;
              }     
         OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

void Get5P9(int pFile)
{ 
  int k1, k2, n1, n2, n3 = 0;
  string x1, aName,aHand, i1 = "i", aFace[14];
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	InFile >> aHand; aHand.copy(c1,6);
	if (aHand.length() == 6 && aHand.substr(5,1) == i1)
              {	
              	for (k1 = 0; k1 <= 4; k1++) 
                     {
			n1 = (int(c1[k1]) - 48);
			n2 = n1 % 13;
                       if (n2 == 0) n2 = 13;
                       aFace[n2] = nNum[n2];
                     } 
                n2 = n1 / 13; 
               // n2 is the suite value of the hand Flush. It serves as tie-breaker.
                x1 = ""; 
                for (k1 = 13; k1 >= 1; k1--)
                     {
		      x1 = x1 + aFace[k1];
		      aFace[k1] = "";
                     }
                aHand = aHand + x1 + nNum[n2];
                n3 = n3 + 1;   
              }     
         OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n3 << endl;
}

// hand 01234 is the weakest and hand 09;;< is the strongest.
void Get4P8(int pFile)
{ 
  int k1, k2, n1, n2 = 0;
  string x1, aName,aHand, h1 = "h", aFace[14];
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in); 
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	 InFile >> aHand; aHand.copy(c1,6);
	 if (aHand.length() == 6 && aHand.substr(5,1) == h1)
              {	
              	for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       aFace[n1] = nNum[n1];
                     } 
                x1 = ""; 
                for (k1 = 13; k1 >= 0; k1--)
                     {
			x1 = x1 + aFace[k1];
		        aFace[k1] = "";
                     }
                if (x1 == "ponmd") // ponmd =  09;;<. q = 13
                    x1 = "q";
                else
                   x1 = x1.substr(0,1);
                aHand = aHand + x1 + ".....";
                n2 = n2 + 1;
	      }     
         OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

//To set a kind 3 hand apart from another kind 3 hand, we need only a trippled card's face value.
void Get3P7(int pFile)
{ 
  int k1, k2, n1, n2 = 0,bFace[14] = {0};
  string x1, aName,aHand, g1 = "g";
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	 InFile >> aHand; aHand.copy(c1,6);
	 if (aHand.length() == 6 && aHand.substr(5,1) == g1)
              {
              	for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13;
                       bFace[n1] = bFace[n1] + 1;
                     } 
                x1 = ""; 
                for (k1 = 13; k1 >= 1; k1--)
                     {
			if (bFace[k1] == 3) x1 = nNum[k1];
			bFace[k1] = 0;
                     }
               aHand = aHand + x1 + ".....";
               n2 = n2 + 1;
	    } 
         OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

void Get2P6(int pFile)
{ 
  int k1, k2, n1, n2 = 0,bFace[14] = {0};
  string x1, x2,aName,aHand, f1 = "f";
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	     InFile >> aHand; aHand.copy(c1,6);
	     if (aHand.length() == 6 && aHand.substr(5,1) == f1)
              {
              	for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13;
                       bFace[n1] = bFace[n1] + 1;
                     } 
                x1 = ""; x2 = "";
                for (k1 = 13; k1 >= 1; k1--)
                     {
		       if (bFace[k1] == 2) x1 = x1 + nNum[k1]; // 2 pairs' face value
		       if (bFace[k1] == 1) x2 = nNum[k1]; // 1 lone card's face value
		       bFace[k1] = 0;
                     }
               aHand = aHand + x1 + x2 + "..."; // Use . padder to standardize score's length.
               n2 = n2 + 1;
	     }
        OutFile << aHand << endl;      
      }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

void Get1P5(int pFile)
{ 
  int k1, k2, n1, n2 = 0,bFace[14] = {0};
  string x1, x2,aName,aHand, e1 = "e";
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in);
  aName = mName[1-pFile];
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	     InFile >> aHand; aHand.copy(c1,6);
	     if (aHand.length() == 6 && aHand.substr(5,1) == e1)
              {
              	for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13;
                       bFace[n1] = bFace[n1] + 1;
                     } 
                x1 = ""; x2 = "";
                for (k1 = 13; k1 >= 1; k1--)
                     {
		       if (bFace[k1] == 2) x1 = nNum[k1]; // The face value of the pair
		       if (bFace[k1] == 1) x2 = x2 + nNum[k1]; // The face value of the lone cards.
		       bFace[k1] = 0;
                     }
               aHand = aHand + x1 + x2 + "..";
               n2 = n2 + 1;
              }
         OutFile << aHand << endl;
       }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

void Get0P4(int pFile)
{ 
  int k1, k2, n1, n2 = 0;
  string x1, aName,aHand, aFace[14],d1 = "d"; // d represents high card type
  char c1[6];
  aName = mName[pFile];
  ifstream InFile(aName.c_str(), ios::in); 
  aName = mName[1-pFile]; If an input file is file 0, then output file is 1. vice versa .
  ofstream OutFile(aName.c_str(), ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
       {
	 InFile >> aHand; aHand.copy(c1,6); //A hand now is length 6. The tail letter is its type
	 if (aHand.substr(5,1) == d1)
	     {   
               for (k1 = 0; k1 <= 4; k1++) 
                     {
		       n1 = (int(c1[k1]) - 48) % 13;
                       if (n1 == 0) n1 = 13; // Card Ace is labeled as the highest value 13.
                       aFace[n1] = nNum[n1];
                     } 
         // Compare 2 high card hands. First see what are their strongest cards,
         //  then the next, and the next. There is no tie- breaker.
               x1 = ""; 
               for (k1 = 13; k1 >= 1; k1--)
                     {
		       x1 = x1 + aFace[k1];
                       aFace[k1] = "";
                     }
               n2 = n2 + 1;
               aHand = aHand + x1 + "."; 
             }
          OutFile << aHand << endl;
       }
  OutFile.close();
  InFile.close();
  cout << n2 << endl;
}

// Arabic 0 to 51 represent the 52 cards. Number % 13 = face value and  n / 13 = suite value.
// Dissemble a hand into 5 cards, get their face and suite value, and determine its type.
void Type3()
{
  int k1, k2, n1, n2,bFace[13] = {0}, aJoint, aPair; 
  string x1, aHand, bSui, aPoint,bStra, aFace[13],aSui = "00000 11111 22222 33333";
  string aStra = "01234 09:;< 12345 23456 34567 45678 56789 6789: 789:; 89:;<";
  char c1[5];
  ifstream InFile("2598959.txt", ios::in);
  ofstream OutFile("2598959a.txt", ios::out);
  for (k2 = 0; k2 <= 2598959; k2++)
        {
	  InFile >> aHand; aHand.copy(c1,5); 
          aPoint = "d"; bSui = "";
          for (k1 = 0; k1 <= 4; k1++)
                {
		  n1 = int(c1[k1]) - 48;
                  n2 = n1 % 13;
                  aFace[n2] = mNum[n2];
                  bFace[n2] = bFace[n2] + 1;
                  n2 = n1 / 13;
                  bSui = bSui + mNum[n2]; 
                }
          bStra = ""; aJoint = 0; aPair = 0;
          for (k1 = 0; k1 <= 12; k1++)
               {
                 bStra = bStra + aFace[k1];
                 if (bFace[k1] > 1) aJoint = aJoint + bFace[k1];
                 if (bFace[k1] == 2) aPair = aPair + 1;
                 aFace[k1] = "";
                 bFace[k1] = 0;
               }
          if (aPair == 2) aJoint = 20;
          if (aStra.find(bStra,0) == -1 || bStra.length() != 5) bStra = "";
          if (aSui.find(bSui,0) == -1) bSui = "";
          if (bStra != "" && bSui != "")
              aPoint = "l";
          else if (aJoint == 4)
                   aPoint = "k";
          else if (aJoint == 5)
                   aPoint = "j";
          else if (bSui != "")
                  aPoint = "i";
         else if (bStra != "")
                  aPoint = "h";
         else if (aJoint == 3)
                  aPoint = "g";
         else if (aJoint == 20)
                  aPoint = "f";
         else if (aJoint == 2)
                  aPoint = "e";
         x1 = aHand + aPoint;
         OutFile << x1 << endl;
        }
   OutFile.close();
   InFile.close();
}

void Hands2() //Generate all possible hands: 0 - 2598959;
{ 
  int k1, k2, k3, k4, k5, aCount = -1;
  string x1, x2, x3, x4, x5;
  ofstream OutFile("2598959.txt", ios::out);
  for (k5 = 0; k5<= 47; k5++)
       {
	 x5 = mNum[k5];
         for (k4 = k5 + 1; k4<= 48; k4++)
              { 
		x4 = x5 + mNum[k4];
                for (k3 = k4 + 1; k3<= 49; k3++)
                     {
		       x3 = x4 + mNum[k3];
                       for (k2 = k3 + 1; k2<= 50; k2++)
                            {
			      x2 = x3 + mNum[k2];
			      for (k1 = k2 + 1; k1<= 51; k1++)
				   {
				     x1 = x2 + mNum[k1];
                                     OutFile << x1 << endl;
                                     aCount = aCount + 1; 
                                    }               
                             }   
                      }                    	  
	          }
        }
  OutFile.close(); 
}

 void SetUp1()
 {   
   int k1;
   string x1,x2; 
   for (k1 = 0; k1 <= 51; k1++)
        mNum[k1] = char(k1+48); // ASCii representing 52 cards (0,1,2 -- a,b,c)
   for (k1 = 0; k1 <= 13; k1++) nNum[k1] = char(k1+100); // for scores: d,e,f,g,h,i,j,k,l
}
		  
 void aMain()
 { 
   SetUp1();
   Hands2(); // Permutate all possible hands
   Type3();  // Code all hands' types
   // Code all hands' within-type scores (from 0 point -- high card to 8 p -- straight flush)
   // Open "2598959a.txt", file 0, add scores and save to "2598959b.txt, file 1"
   // Next open "2598959b.txt" and save data into "2598959a.txt". Alternating the 2 files
   Get0P4(0); //Make 0 point hands (High Cards)
   Get1P5(1); // One pair
   Get2P6(0);
   Get3P7(1);
   Get4P8(0);
   Get5P9(1);
   Get6P10(0);
   Get7P11(1);
   Get8P12(0);
   LineUp13(); // Finally, change "2598959b.txt" a hand per line to 100 hand per line.
               // and save the file to "25990f.txt"
 }
int main(int argc, char** argv)
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }

Part 2
string mNum[52], mHead[25991], mLine[25991];

void SumUp5(int pNum) // Open the textfile with a million games' scores
{
  int k1, k2, n1, n2 = 0;
  string x1, x2, aHand, aIndex[6];  
  ifstream InFile("Score1M.txt", ios::in);
  for (k2 = 0; k2 <= 999999; k2++)
       {
	     InFile >> aHand; 
         x1 = aHand.substr(0,12) + aHand.substr(24,48);
         if (pNum == 1) x1 = aHand.substr(12,60);
         n1 = 5; 
         for (k1 = 0; k1 <= 4; k1++)
              {
               	 aIndex[k1] = x1.substr(n1,7); n1 = n1 + 12;
	      }
         x1 = aIndex[0];
         for (k1 = 1; k1 <= 4; k1++)
               {
	         if (x1 < aIndex[k1]) n2 = n2 - 1;
                 if (x1 > aIndex[k1]) n2 = n2 + 1;
               }
       } 
  x1 = "One million games (4 bets for each game), how many bets the dealer wins?";
  if (pNum == 0)
      cout << "1. Without card replacement for the dealer:" << endl;
  else
      cout << "2. With card replacement for the dealer:" << endl;
  cout << "The count is " << n2 << endl;
}

//Input a hand and output its score.
string Score3a(string pHand)
{
  int k1, n1;
  string x1, x2;
  for (k1 = 0; k1 <= 25990; k1++)
       if (pHand < mHead[k1]) break;
  // Dictionary stype's retrieval. First the line the hand is located, then the hand.
  x1 = mLine[k1 - 1]; 
  n1 = x1.find(pHand,0);
  x2 = x1.substr(n1,12);
  return x2;
}

// Replace 3 cards
string Swap3b(string pHand, string pPart, int pPoint)
{
  int k1, k2, n1, n2;
  string x1, x2, x3, s1[5], aFace[14];  
  char c1[5];
  pHand.copy(c1,5); 
  for (k1 = 0; k1 <= 4; k1++)
        { 
          x1 = pHand.substr(k1,1);
          n1 = (int(c1[k1]) - 48) % 13;	
          if (n1 == 0) n1 = 13;
          aFace[n1] = aFace[n1] + x1; 
        }
  x1 = ""; 
  if (pPoint == 0)
       {
	 for (k1 = 13; k1 >= 1; k1--)
	       if (aFace[k1].length() == 1) x1 = x1 + aFace[k1];
	       x1 = x1.substr(0,2);
       }
  else if (pPoint == 1)
       {
       	 for (k1 = 13; k1 >= 1; k1--)
              if (aFace[k1].length() == 2) x1 = aFace[k1]; 
       }
  else if (pPoint == 2)
       {
	 for (k1 = 13; k1 >= 1; k1--)
              if (aFace[k1].length() == 2) x1 = x1 + aFace[k1];
       }
 else if (pPoint == 3)
       {
       	 for (k1 = 13; k1 >= 1; k1--)
              if (aFace[k1].length() == 3) x1 = aFace[k1];
       }
 n1 = 5 - x1.length(); 
 x2 = x1 + pPart.substr(0,n1); 
 for (k1 = 0; k1 <= 4; k1++)
      s1[k1] = x2.substr(k1,1);
 x3 = ""; 
 for (k2 = 0; k2 <= 4; k2++)
       {
         x1 = s1[k2]; 
         for (k1 = k2 + 1; k1 <= 4; k1++)
              if (x1 > s1[k1])
                 {
		   x2 = x1; x1 = s1[k1]; s1[k1] = x2;
                 }
         x3 = x3 + x1;
       } 
 return x3;
}

// Get one million hands' scores
void Score4()
{
  int k1, k2, n1;
  string x1, x2, x3, aHand;
  ifstream InFile("Game1M.txt", ios::in);
  ofstream OutFile("Score1M.txt", ios::out);
  for (k2 = 0; k2 <= 999999; k2++)
        {
	  InFile >>  x1;  
          n1 = -5; aHand = "";
          for (k1 = 0; k1 <= 5; k1++)
                {
                  n1 = n1 + 5; x2 = x1.substr(n1,5);
                  x3 = Score3a(x2);
                  aHand = aHand + x3;
		}
          OutFile << aHand << endl;
        }
  OutFile.close();
  InFile.close();
}

// Shuffle one million times of the 52 cards and randomly pick 28 cards
void Shuffle3()
{
  int k1, k2, k3, k4, n1, n2,aCount;
  string x1, x2, aHand, bHand,aCard[52], bCard[52], aPart;
  char c1[6];
  ofstream OutFile("Game1M.txt", ios::out);
  for (k4 = 0; k4 <= 999999; k4++) 
        {
	  aHand = "";
          for (k3 = 0; k3<= 51; k3++)
               aCard[k3] = mNum[k3];
          n2 = -1;
          for (k3 = 51; k3>= 24; k3--) 
                {
                  n1 = rand() % (k3+1);
                  n2 = n2 + 1;
                  bCard[n2] = aCard[n1];
                  aCard[n1] = aCard[k3];
		}
          aPart = bCard[25] + bCard[26] + bCard[27];
          aCount = -1;
          for (k3 = 0; k3<= 4; k3++)
               {
		 for (k2 = 0; k2<= 4; k2++)
		      {
			aCount = aCount + 1;
			aCard[k2] = bCard[aCount];	
		      }
                  for (k2 = 0; k2<= 4; k2++)
                        {
			  x1 = aCard[k2];
                          for (k1 = k2 + 1; k1<= 4; k1++)
                               if (x1 > aCard[k1])
                                   {
                                     x2 = x1; x1 = aCard[k1]; aCard[k1] = x2;
				   }
                          aHand = aHand + x1;
                        }
               } 
          bHand = aHand.substr(0,5);
          x1 = Score3a(bHand);
          x2 = x1.copy(c1,6);
          n1 = int(c1[5]) - 100; 
          if (n1 < 4)
              x2 = Swap3b(bHand, aPart, n1);
          else
              x2 = bHand;
          bHand = bHand + x2; 
          x1 = bHand + aHand.substr(5,20);
          OutFile << x1 << endl;
        }
  OutFile.close();
}

void Load2()
{
  int k1;
  string x1;
  ifstream InFile("25990f.txt", ios::in);
  for (k1 = 0; k1 <= 25990; k1++)
      {
      	InFile >> x1;
      	mHead[k1] = x1.substr(0,5);
      	mLine[k1] = x1;
      }
  InFile.close(); 
}

 void SetUp1()
 {   
   int k1;
   for (k1 = 0; k1 <= 51; k1++)
        mNum[k1] = char(k1+48); 
}
		  
 void aMain()
 { 
   SetUp1();
   Load2();
   Shuffle3();
   Score4();
   SumUp5(0);
   SumUp5(1);
 }
int main(int argc, char** argv)
 { 
   aMain(); srand(time(0));
   exit(0);
   system("PAUSE");
   return 0;
 }
// Part 3
string mNum[52],mRate[25991],nRate[25991]; 

//Replace 3 cards
string Swap3b(string pHand, string pCard, int pPoint)
{
  int k1, k2, n1, n2;
  string x1, x2, x3, s1[14], aHand; 
  char c1[5]; 
  pCard = pCard.substr(0,3);
  pHand.copy(c1,5);
  for (k1 = 0; k1 <= 4; k1++)
       {
       	 x1 = pHand.substr(k1,1);
	 n1 = (int(c1[k1]) - 48) % 13; 
	 if (n1 == 0) n1 = 13;
         s1[n1] = s1[n1] + x1;
       }
  x1 = "";  
  for (k1 = 13; k1 >= 1; k1--) 
        {  
          if (s1[k1].length() == 2) x1 = x1 + s1[k1];
		  if (s1[k1].length() == 1) x2 = x2 + s1[k1];
          if (s1[k1].length() == 3) x3 = s1[k1]; 
        } 
 if (pPoint == 0)
     aHand = x2.substr(0,2) + pCard; 
 else if (pPoint == 1)
     aHand = x1 + pCard;
 else if (pPoint == 2)
   aHand = x1 + pCard.substr(0,1);
 else if (pPoint == 3)
   aHand = x3 + pCard.substr(0,2);
 
 for (k1 = 0; k1 <= 4; k1++)
      s1[k1] = aHand.substr(k1,1);
 aHand = ""; 
 for (k2 = 0; k2 <= 4; k2++)
     {
       x1 = s1[k2];
       for (k1 = k2 + 1; k1 <= 4; k1++)
            if (x1 > s1[k1])
                 {
                   x2 = x1; x1 = s1[k1]; s1[k1] = x2;	
		 }
       aHand = aHand + x1;
     } 
  return aHand;
}

string Points3a(string pHand)// Retrieve a hand's score 
{
  int k1, n1;
  string x1, x2;
  for (k1 = 0; k1 <= 25990; k1++)
      if (pHand < mRate[k1]) break;
  x1 =  nRate[k1-1];
  n1 = x1.find(pHand,0);
  x2 = x1.substr(n1,12); 
  return x2;
}

void PlayPoker3()
{
 int k1, k2, n1, n2, rpCard, aPosit[5];
 string x1, x2, x3, x4, aHand, kCard,bHand, aCard, s1[14], cHand[5], aPoint[5];
 char c1[6];
 //cout << "Enter the dealer's 5 cards now: ";
 //cin >> aHand;
 aHand = "6@MYa";
 //aHand = "=JWbc";
 x1 = Points3a(aHand);
 x1.copy(c1,6);
 n1 = int(c1[5]) - 100;
 
 if (n1 < 4)
      {
      	for (k1 = 0; k1 <= 4; k1++)
             { 
               x1 = aHand.substr(k1,1);
	       n2 = (int(c1[k1]) - 48) % 13;
	       if (n2 == 0) n2 = 13;
	       s1[n2] = s1[n2] + x1;
	     }
        x1 = ""; x2 = ""; x3 = "";
        for (k1 = 13; k1 >= 1; k1--)
              {
              	if (s1[k1].length() == 2) x1 = x1 + s1[k1];
                if (s1[k1].length() == 1) x2 = x2 + s1[k1];
                if (s1[k1].length() == 3) x3 = s1[k1];
                s1[k1] = "";
              } 
  if (n1 == 0)
     kCard = x2.substr(0,2);
  else if (n1 == 1)
     kCard = x1.substr(0,2);
  else if (n1 == 2)
     kCard = x2.substr(0,4);
  else if (n1 == 3)
     kCard = x3.substr(0,3);

  n2 = 5 - kCard.length();
  //cout << "keep cards " + kCard + " and add " << n2 << " cards now" << endl;
  //cout << "Input replacement cards now: ";
 //cin >> x1;
  x1 = "]V3";
  aHand = kCard + x1; 
  } 
  for (k1 = 0; k1 <= 4; k1++)
       s1[k1] = aHand.substr(k1,1);
  aHand = ""; 
  for (k2 = 0; k2 <= 4; k2++) 
       {
	 x1 = s1[k2];
         for (k1 = k2 + 1; k1 <= 4; k1++) 
              if (x1 > s1[k1])
                   {
                     x2 = x1; x1 = s1[k1]; s1[k1] = x2;
		   }
        aHand = aHand + x1;
       }
 cout << aHand << endl;

 aHand = ">?@AK";
 //cout << "Enter 4 players' cards (20,separated by a ,): " << endl;
 x1 = "1234>,JWabc,1234C,RW`ac," + aHand;
 n1 = 0; 
 for (k1 = 0; k1 <= 4; k1++)
      {
	x2 = x1.substr(n1,5);
        cHand[k1] = x2;
        x2 = Points3a(x2);
        aPoint[k1] = x2.substr(5,7);
        aPosit[k1] = k1;
        cout << cHand[k1] + " " + aPoint[k1] + " " << aPosit[k1] << endl;
        n1 = n1 + 6;
      } 
 cout << endl;
 for (k2 = 0; k2 <= 4; k2++) 
      {
       x1 = cHand[k2]; x2 = aPoint[k2]; n1 = aPosit[k2];
       for (k1 = k2 + 1; k1 <= 4; k1++)
            if (x2 < aPoint[k1])
                 {
		   x4 = x2; x2 = aPoint[k1]; aPoint[k1] = x4;
                   x3 = x1; x1 = cHand[k1]; cHand[k1] = x3;
                   n2 = n1; n1 = aPosit[k1]; aPosit[k1] = n2;
                 }
       cHand[k2] = x1; aPoint[k2] = x2; aPosit[k2] = n1;
       cout << k2 << " " + cHand[k2] + " " + aPoint[k2] + " " << aPosit[k2] << endl;
      }
  cout << endl; 
  for (k2 = 0; k2 <= 4; k2++) 
      {
        x1 = cHand[k2]; x2 = aPoint[k2]; n1 = aPosit[k2];
        for (k1 = k2 + 1; k1 <= 4; k1++)
             if (x2 == aPoint[k1])
                 cout << aPosit[k2] << " score - ties " << aPosit[k1] << endl;
      }
}

void Load2()
{
 int k1;
 string x1;
 ifstream InFile("25990f.txt", ios::in);
 for (k1 = 0; k1 <= 25990; k1++)
      {
      	InFile >> x1;
      	mRate[k1] = x1.substr(0,5);
      	nRate[k1] = x1; 
	  }
 InFile.close();
}

 void SetUp1()
 {   
   int k1,k2;
   string x1,x2;
   for (k1 = 0; k1 <= 51; k1++)
        mNum[k1] = char(k1+48); 
}
		  
 void aMain()
 { 
   int k1,k2,n1,n2;
   string x1,x2;
   srand(time(0));
   SetUp1();
   Load2();
   PlayPoker3();
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }


Section 9: Print Out 1441 solutions for a difficult sudoku puzzle using BigData
  Coding techniques to develop the algorithm and to do the coding.
  The book: "Programming Sudoku" by Wei-Meng Lee, lists an extremely difficult
  puzzle and its solution. The author does not know if the puzzle has other
  solutions. The two programs, which I list below, independently show that it has
  1441 solutions. The solutions, which Program A prints out, match exactly those
  printed out by Program B.
The puzzle in 1-D form and in-D form(0 represents blanks needing filling.)
000008009050090000009004800002140003006000900400067100005900300000030070800400000
324718659758693412619524837582149763176385924493267185265971348941832576837456291

--- --8 --9 
-5- -9- --- 
--9 --4 8--

--2 14- --3
--6 --- 9--
4-- -67 1-- 

--5 9-- 3--
--- -3- -7-
8-- 4-- ---

                  ALGORITHM
Program A(Column to column solution):
Step 1: Permutating (1-9) Generates a list of 362880 (factorial 1 to 9)
   int k1,k2,k3,n1,n2,aCount = 0,aLen;
   string mNum[] = {"0","1","2","3","4","5","6","7","8","9"};
   string x1,x2, aNum,aMove[40320],bMove[40320];
   ofstream OutFile("362879.txt", ios::out); //Save data in a text file.
   for (k3 = 1; k3 <= 9; k3++)
        {
          aNum = mNum[k3];
          aLen = aCount; aCount = -1;
          for (k2 = 0; k2 <= aLen; k2++)
                {                 
                  aMove[k2] = bMove[k2];
                       for (k2 = 0; k2 <= aLen; k2++)
                            {
                              x1 = aMove[k2];
 		                   for (k1 = 0; k1 <= k3 -1; k1++)
                                    {
                                      x2 = x1;
 				           x2.insert(k1,aNum);
 				           aCount = aCount + 1;
 				           if (k3 != 9) 
 				               bMove[aCount] = x2;
 				           else
 				               OutFile << x2 << endl;
 			                  }
 		                  }
                }
        }

            OutFile.close();   
         // This function works as follows:
            1. Copy bMove[n] to aMove[n]; aMove[0] = "";
            2. Insert "1" to aMove[0] at position 0, bMove[0] = "1";
            3. Copy bMove[n] to aMove[n]; aMove[0] = "1";
            4. Insert "2" to aMove[0] at position 0, and bMove[0] = "21".
               Insert "2" to aMove[0] at position 1, and bMove[1] = "12"
            5. Continue to 3,4,5,6,7,8;
            6. Continue to 9 and then save the list to a textfile.
               The final loop: aMove[40319] = "87654321" becomes
               876543219,876543291,876543921,876549321,876594321
               876954321,879654321,897654321,987654321
  Step 2: Create indices of Filter-in and Filter-0ut(mGet[n] and mCut[n])
           1. Use consecutive ASCII to represent the sudoku-board(an array(0-80)
              convert ASCII into Arabic:
              x1 = ./0 123 456; x1.copy(char c1,9) n1 = int(c1[0]) - 46; n1 = 0
              ./0 123 456
              789 :;< =>?
              @AB CDE FGH

              IJK LMN OPQ
              RST UVW XYZ
              [\] ^_` abc

              def ghi jkl
              mno pqr stu
              vwx yz{ |}~

              --- --8 --9   
              -5- -9- ---
              --9 --4 8--

              --2 14- --3
              --6 --- 9--
              4-- -67 1--

              --5 9-- 3--
              --- -3- -7-
              8-- 4-- ---
         2. Load the above puzzle into an array--nPuz[n] and create a Filter-in array mGet[n]
            n1 = -1;
           for (k2 = 0; k2<= 8; k2++) // Row 0 to Row 8
                {
	          x2 = "";
	          for (k1 = 0; k1<= 8; k1++) // Position of row (0 to 8)
                       {
	                 n1 = n1 + 1;
	                 if (nPuz[n1] != "") 
		             x2 = x2 + mNum[k1] + x1;
                       }
                  mGet[k2] = x2;
                } 
            Row 0 = "5889". Odd numbers represent string positions. Even as values
            "5889" means position 5 and value 8 + position 8 and value 9
            Only those strings (123456789 to 987654321) that have 8 in position 5 and 9
            in position 8 pass through.
            Use 3 indices to represent the values of the 80-cell array (row, column and mini grid)
         x1 = "111111111222222222333333333444444444555555555666666666777777777888888888999999999";
         x2 = "123456789123456789123456789123456789123456789123456789123456789123456789123456789";
         x3 = "111222333111222333111222333444555666444555666444555666777888999777888999777888999";
         for (k1 = 0; k1<= 80; k1++)
              {
		Index1[k1] = x1.substr(k1,1);
                Index2[k1] = x2.substr(k1,1);
                Index3[k1] = x3.substr(k1,1);
              }
        for (k2 = 0; k2<= 80; k2++)
             {          
               if (nPuz[k2] == "")
                   { 
		     x1 = Index1[k2]; x2 = Index2[k2]; x3 = Index3[k2];
                     aMove = "";
                     for (k1 = 0; k1<= 80; k1++)
                          {
		            if (nPuz[k1] != "")
		                {
		                  if (x1 != Index1[k1] && (x2 == Index2[k1] || x3 == Index3[k1]))
		                      {
		                          if (aMove.find(nPuz[k1],0) == -1)
		                              aMove = aMove + nPuz[k1];	
		                       }
                                }
                          }
                     mCut[k2] = aMove; //Filter-out index[n]
                   }
             } 
   //Delete duplicates
   for (k3 = 0; k3<= 72; k3+= 9)
        {
          n1 = k3; n2 = n1 + 8;
          for (k2 = n1; k2<= n2; k2++)
               {
	         if (nPuz[k2] != "")
		     {
		       x1 = nPuz[k2];
                       for (k1 = n1; k1<= n2; k1++)
                             {
                               n3 = mCut[k1].find(x1,0); 
                               if (n3 != -1) mCut[k1].erase(n3,1);
			      }
                     }
              }
       } 
   Each cell controls other 12 cells, e.g: Cell 0 controls the cells below:
   9 10 11
  18 19 21

  27
  36
  45

  54
  63
  72
  --- --8 --9   
  -5- -9- ---
  --9 --4 8--

  --2 14- --3
  --6 --- 9--
  4-- -67 1--

  --5 9-- 3--
  --- -3- -7-
  8-- 4-- ---
  In summary, we start picking strings for row 0. We let strings, that have 8 in position 5
  and 9 in position 8, pass through. We filter out those strings, that have 4 or 5 in position 0,
  or that have 5 in position 1, or (2 or 6 in p3) and etc.
  All these permutations and filter-in and filter-out follow the universal principle:
  Pile up big number of data and then filter them down to small number.

  Step 3: By filter-in and filter-out, we get all the possible row candidate strings:
    First we open that text file that has 362879 strings(123456789 to 987654321).
    We load the 10 strings to each aMove[n] (total 36287)
    We set up 2 gates. mGet[n] gate, that kicks out unqualified
    strings. mCut[n] gate, that also kicks out unqualified strings
    (e.g. for pick up strings for row 0, each string must have 8, 9 in position 5 and 8, 
      and must not, in position 0, have 4 or 5, in position 1, have 4, ... in position 7,
      have 7.)
Here is the program:     
void Row3()
{
  int k1, k2, k3, k4,n1, aPosit[19],aCount = -1, bCount[9], cCount = -1,aLen, aStart, aEnd;
  string x1, x2, aMove[36288], bMove, aGet[19], aCut; 
  char c1[99];
  ifstream InFile("362879.txt", ios::in);
  n1 = -1;
  for (k2 = 0; k2 <= 36287; k2++)
        {
          x1 = "";
          for (k1 = 1; k1 <= 10; k1++)
               {
               	  n1 = n1 + 1;
               	  InFile >> x2;
               	  x1 = x1 + x2;
			   }
		  aMove[k2] = x1;
		}
  InFile.close();
  
  ofstream OutFile("1127r.txt", ios::out);
  for (k4 = 0; k4<= 8; k4++)
      {
	    x1 = mGet[k4]; // Green light gate: row 0 is "5889"
        aLen = x1.length(); x1.copy(c1,aLen); // convert char to arabic
        for (k3 = 0; k3< aLen; k3+= 2)
              {
                aPosit[k3] = int(c1[k3]) - 48; // For row 0: aPosit[n] = 5,8.
                aGet[k3] = x1.substr(k3 + 1,1);// For row 0: aGet[n1] = 8,9.

			  }
        aStart = k4 * 9; aEnd = aStart + 8;
        for (k3 = 0; k3<= 36287; k3++)
              {
			     bMove = aMove[k3];
			     for (k2 = 0; k2 <= 81; k2+= 9) 
			          {
				    x1 = bMove.substr(k2,9); 
                        for (k1 = 0; k1< aLen; k1+= 2)
                              {
                              	n1 = aPosit[k1];
                              	x2 = x1.substr(n1,1); 
                              	if (x2 != aGet[k1]) goto aSkip; // For row 0, if x2 != 8,9, out
							  }
                        n1 = -1;
                        for (k1 = aStart; k1<= aEnd; k1++)
                              {
                              	n1 = n1 + 1;
                              	x2 = x1.substr(n1,1);
                              	if (mCut[k1].find(x2,0) != -1) goto aSkip; 
			      } // For row 0, if mCut[n] has the same number in it, out.
                       aCount = aCount + 1; 
                       OutFile << x1 << endl; //Save the qualified strings to a text file.
                       aSkip: k1 = 0;
                      }
              }
         bCount[k4] = aCount; // The end count for each row-picks. 
      }                         
  for (k4 = 0; k4<= 8; k4++)
      OutFile << bCount[k4] << endl; // Attach the end-count to a file named 1127r.txt
  OutFile.close();           
 }
  The final number: 1127 (for all 9 rows)
  We index those numbers (0 to 8) as follows(Row1: 0 - 499; Row8: 1062 - 1127)
  499
  623
  829
  836
  891
  899
  977
  1061
  1127
 Step 4: We hook up Row0 to Row1 and Row2 and get Section 0 candidates. (String length() = 27);
    And 3 to 4 and 5 to get Section 1 and 6,7 8 to get Section 2.
    String count section to section:17683 + 115 + 1695 = 19495
    How to merge Row0 strings to Row1 strings? 
    Suppose string0 = "123456789" and string1 = "987654321". We load it into an array0[0-8];
    array0[0] = "123"; array0[1] = 123; array0[2] = 123 ... array0[6] = 789 ...array0[8] = 789
    We substring string1 into 9,8,7,6,5,4,3,2,1.
    We line them up:
    123 9 OK here
    123 8 OK here
    123 7 OK here
    456 6 we kick this string out because there are 2 6s
    456 5 we kick this string out because there are 2 5s
    456 4 we kick this string out because there are 2 4s
    789 3
    789 2
    789 1
    All these string manipulations seems to be excessive. But they are basic and frequently
    used processing techniques in what I call Bigdata Coding, a revolutionary theory and practice.
    Any one, who sticks to the conventional coding, would find them quite anoying. But after you
    have used them for several times, you will come to like them. 
 Step 5: We merge Section 0 to Section 1 and then Section 2. We get 1441 solutions.
   Section to Section merge means column check.
   Suppose we have a Section 0 string's positions:
   
00 01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16 17
18 19 20 21 22 23 24 25 26
Suppose we have a section 0 string's value as follow:
1 2 3   4 5 6  7 8 9
4 5 6   7 8 9  1 2 3
7 8 9   1 2 3  4 5 6
We line up the numbers by their columns and index the above string as follow:
Index[0]  = 00 09 18 = 147
Index[1]  = 01 10 19 = 258
Index[2]  = 02 11 20 = 369
Index[3]  = 03 12 21 = 471
Index[4]  = 04 13 22 = 582
Index[5]  = 05 14 23 = 693
Index[6]  = 06 15 24 = 714
Index[7]  = 07 16 25 = 825
Index[8]  = 08 17 26 = 936

Index[9]  = 00 09 18 = 147
Index[10] = 01 10 19 = 258
Index[11] = 02 11 20 = 369
Index[12] = 03 12 21 = 471
Index[13] = 04 13 22 = 582
Index[14] = 05 14 23 = 693
Index[15] = 06 15 24 = 714
Index[16] = 07 16 25 = 825
Index[17] = 08 17 26 = 936

Index[18] = 00 09 18 = 147
Index[19] = 01 10 19 = 258
Index[20] = 02 11 20 = 369
Index[21] = 03 12 21 = 471
Index[22] = 04 13 22 = 582
Index[23] = 05 14 23 = 693
Index[24] = 06 15 24 = 714
Index[25] = 07 16 25 = 825
Index[26] = 08 17 26 = 936

Suppose we have a Section 1 string as follow
9 8 7  6 5 4  3 2 1
6 5 4  3 2 1  9 8 7
1 2 3  9 8 7  3 2 1
We substr the above string and line them up:

0: 147  9
1: 258  8  there are 2 8s. Kick it out 
We merge 1 to 2, we have a string 54 in length
The Index[n] has 6 numbers
Index[0]   = 00 09 18 27 36 45
Index[26]  = 08 17 26 35 44 53

Step 6: Verify the 1441 solutions
  Check 1: a number shows up only once in the same row, same column and min grid.
  Use 3 indices to represent the values of the 80-cell array (row, column and mini grid)
      x1 = "111111111222222222333333333444444444555555555666666666777777777888888888999999999";
      x2 = "123456789123456789123456789123456789123456789123456789123456789123456789123456789";
      x3 = "111222333111222333111222333444555666444555666444555666777888999777888999777888999";
      for (k1 = 0; k1<= 80; k1++)
           {
	     Index1[k1] = x1.substr(k1,1);
             Index2[k1] = x2.substr(k1,1);
             Index3[k1] = x3.substr(k1,1);
           }
     aCount = -1;
     for (k2 = 0; k2<= 80; k2++)
             {          
               x1 = Index1[k2]; x2 = Index2[k2]; x3 = Index3[k2];
                     for (k1 = 0; k1<= 80; k1++)
                          {
		            if (k2 != k1)
		                {
		                  if (x1 == Index1[k1] || x2 == Index2[k1] || x3 == Index3[k1])
		                      {
		                        aCount = aCount + 1;
                                        mCheck[aCount] = k1; 	
		                       }
                                }
                          }
             } 
   Suppose the cell 0, in a solution string is 3:
   aStart = 0 * 20: aEnd = aStart + 19: mCheck[0] to mCheck[19];
   Cell 0 control the following 20 cells
      1  2 3 4 5 6 7 8
   9 10 11
  18 19 20
  27
  36
  45
  54
  64
  72
Suppose the solution is as follows:
324718659
758693412
619524837

582149763
176385924
493267185

265971348
941832576
837456291

Cell 0 = 3
The values of the 20 cells it controls are as follows:
  2 4 7 1 8 6 5 9
7 5 8
6 1 9
5
1
4
2
9
8
No 3 in all the 20 cells. The string is OK.
Check 2: No duplicate solution shows up within the 1441 solutions 
  The solution listed in the book must show up in the 1441 solution2.
Check 3: All solutions must match exactly the puzzle:
  --- --8 --9   
  -5- -9- ---
  --9 --4 8--

  --2 14- --3
  --6 --- 9--
  4-- -67 1--

  --5 9-- 3--
  --- -3- -7-
  8-- 4-- ---
e.g substr(72,1) must be 8 and substr(75,1) must be 4.

Here's the program
string mPuz = "000008009050090000009004800002140003006000900400067100005900300000030070800400000";
string mKey = "324718659758693412619524837582149763176385924493267185265971348941832576837456291";
string mNum[] = {"0","1","2","3","4","5","6","7","8","9"}, nPuz[81], mGet[9], mCut[81];
int mCheck[1620];

void Verify6()
{
  int k1, k2, k3, n1, n2, n3;
  string x1, x2, aMove[1441], aIndex[81]; 
  ifstream InFile("1440.txt", ios::in); 
  for (k1 = 0;k1<= 1440; k1++)
       InFile >> aMove[k1]; 
  InFile.close();
  //aMove[1440] = aMove[1439]; // This is for failure test. Function must pick it up.
  for (k2 = 0; k2<= 1439; k2++) 
        {
	  x1 = aMove[k2];
          for (k1 = k2 + 1; k1<= 1440; k1++)
                if (x1 == aMove[k1]) cout << "Dup error in " << k1 << endl;
        }
  //x1 = aMove[1440]; aMove[1440] = "124359768" + x1.substr(9,72); // Failure test.
 for (k2 = 0; k2<= 1440; k2++)     
       {
	 x1 = aMove[k2];
         for (k1 = 0; k1<= 80; k1++)
              if (nPuz[k1] != "")
                   {
		     x2 = x1.substr(k1,1);
                     if (nPuz[k1] != x2) 
			cout << "Key and puzzle unmatched in " << k2  << endl;
                   }
       } 
 //aMove[1400] = aMove[1400].substr(0,80) + "2"; // Failure test
 for (k3 = 0; k3<= 1440; k3++)
       {
	 x1 = aMove[k3];
         for (k2 = 0; k2<= 80; k2++)
              aIndex[k2] = x1.substr(k2,1);
         for (k2 = 0; k2<= 80; k2++)
               {
		  n1 = k2 * 20; n2 = n1 + 19;
                  x1 = "";
                  for (k1 = n1; k1<= n2; k1++)
                       {
                       	 n3 = mCheck[k1]; x1 = x1 + aIndex[n3];
					   }
                  if (x1.find(aIndex[k2],0) != -1)
                       {
			 cout << "Rule violation in " << k3 << endl;
			 break;
		        }		      
               }
               
       } 
}

void Hook5() //11215
{
  int k1, k2, k3, n1, n2,aCount = -1, Start1[10], End1[9]; 
  string x1, x2, Move1[29494], Move2, Move3[109999], aMove[45793], aFilter[27];
 
ifstream InFile("19495s.txt", ios::in); 
  for (k1 = 0;k1<= 19495; k1++)
       InFile >> Move1[k1];
  for (k1 = 0;k1<= 2; k1++)
        {
          InFile >> n1;	
          Start1[k1 + 1] = n1 + 1; End1[k1] = n1;
	}
  InFile.close();
  Start1[0] = 0;
  
  int aStart, aEnd, bStart, bEnd, bCount;
  aStart = Start1[0]; aEnd = End1[0];
  bStart = Start1[1]; bEnd = End1[1];
  x1 = "";
  for (k3 = bStart; k3<= bEnd; k3++)
       x1 = x1 + Move1[k3];
  n1 = x1.length() - 1;
  for (k3 = 0; k3<= n1; k3++)
       aMove[k3] = x1.substr(k3,1);

  for (k3 = aStart; k3<= aEnd; k3++)
        {
	  Move2 = Move1[k3];
          for (k2 = 0; k2<= 8; k2++)
                {
		   n1 = k2; x1 = "";
                   for (k1 = 1; k1<= 3; k1++)
                         {
                           x1 = x1 + Move2.substr(n1,1);
                           n1 = n1 + 9;
			 }
                  n1 = k2;
                  for (k1 = 1; k1<= 3; k1++)
                        {
			  aFilter[n1] = x1;
                          n1 = n1 + 9;
                        }
                }
         n1 = -27;
         for (k2 = bStart; k2<= bEnd; k2++)
               {
	         n1 = n1 + 27; n2 = n1;
                 for (k1 = 0; k1<= 26; k1++)
                       {
                       	 if (aFilter[k1].find(aMove[n2],0) != -1) goto aSkip;
                       	 n2 = n2 + 1;
		       }
                 aCount = aCount + 1;
                 Move3[aCount] = Move2 + Move1[k2];
                 aSkip: k1 = 0;
               }
        }
  aEnd = aCount; aCount = -1; 
  bStart = Start1[2]; bEnd = End1[2];
  x1 = "";
  for (k3 = bStart; k3<= bEnd; k3++)
       x1 = x1 + Move1[k3];
  n1 = x1.length() -1;
  for (k3 = 0; k3<= n1; k3++)
    aMove[k3] = x1.substr(k3,1);
  ofstream OutFile("1440.txt", ios::out);
  for (k3 = 0; k3<= aEnd; k3++)
        {
	  Move2 = Move3[k3];
          for (k2 = 0; k2<= 8; k2++)
                {
		  n1 = k2; x1 = "";
                  for (k1 = 1; k1<= 6; k1++)
                        {
                          x1 = x1 + Move2.substr(n1,1);
                          n1 = n1 + 9;
			}
                  n1 = k2;
                  for (k1 = 1; k1<= 3; k1++)
                        {
			  aFilter[n1] = x1;
                          n1 = n1 + 9;
                        }
                }
         n1 = -27;
         for (k2 = bStart; k2<= bEnd; k2++)
               {
		 n1 = n1 + 27; n2 = n1;
                 for (k1 = 0; k1<= 26; k1++)
                       {
                       	 if (aFilter[k1].find(aMove[n2],0) != -1) goto bSkip;
                       	 n2 = n2 + 1;
		       }
                 aCount = aCount + 1;
                 x2 = Move2 + Move1[k2];
                 OutFile << x2 << endl;
                  bSkip: k1 = 0;
               } 
        } 
  OutFile.close();
}
void Hook4() //17683 + 115 + 1695 = 19495
{
  int k1, k2, k3, k4, n1, n2, n3,aCount, aLen, Start1[10], End1[9]; 
  string x1, x2, Move1[1128], Move2,Move3[39999], Move4[99999],aMove[9999], aFilter[10];
  ifstream InFile("1127r.txt", ios::in);
  for (k1 = 0;k1<= 1127; k1++)
       InFile >> Move1[k1];
  for (k1 = 0;k1<= 8; k1++)
        {
          InFile >> n1;	
          Start1[k1 + 1] = n1 + 1; End1[k1] = n1;
	}
  Start1[0] = 0;
  InFile.close();
  int aStart, aEnd, bStart, bEnd, bCount = -1, cCount[7];
  ofstream OutFile("19495s.txt", ios::out);
  for (k4 = 0;k4<= 6; k4+= 3)
        {
	  aStart = Start1[k4]; aEnd = End1[k4];
          bStart = Start1[k4 + 1]; bEnd = End1[k4 + 1];
          x1 = "";
          for (k3 = bStart;k3<= bEnd; k3++)
               x1 = x1 + Move1[k3];
          aLen = x1.length() -1;
          for (k3 = 0;k3<= aLen; k3++)
               aMove[k3] = x1.substr(k3,1);
          aCount = -1;
          for (k3 = aStart;k3<= aEnd; k3++)
               {
		Move2 = Move1[k3]; x1 = "";
                for (k2 = 0;k2<= 8; k2+= 3)
                      {
			x1 = Move2.substr(k2,3);
                        for (k1 = k2;k1<= k2 + 2; k1++)
                             aFilter[k1] = x1;
                      }
                n1 = -10;
                for (k2 = bStart;k2<= bEnd; k2++)
                      {
			n1 = n1 + 9; n2 = n1;
                        for (k1 = 0;k1<= 8; k1++)
                              {
				n2 = n2 + 1;
                                if (aFilter[k1].find(aMove[n2], 0) != -1) goto aSkip;
                              }
                        aCount = aCount + 1;
                        Move3[aCount] = Move2 + Move1[k2];
                        aSkip: k1 = 0;
                      }
               } 
  
         bStart = Start1[k4 + 2]; bEnd = End1[k4 + 2];
         x1 = "";
         for (k3 = bStart;k3<= bEnd; k3++)
              x1 = x1 + Move1[k3];
         aLen = x1.length() -1;
         for (k3 = 0;k3<= aLen; k3++)
              aMove[k3] = x1.substr(k3,1);
         aLen = aCount; aCount = -1;
         for (k3 = 0;k3<= aLen; k3++)
               {
		 Move2 = Move3[k3];
                 for (k2 = 0;k2<= 8; k2+= 3) 
                       {
                       	 x1 = Move2.substr(k2,3) + Move2.substr(k2 + 9,3);   
                         for (k1 = k2;k1<= k2 + 2; k1++)
                             aFilter[k1] = x1;
                       }
                 n1 = -10;
                 for (k2 = bStart;k2<= bEnd; k2++)
                       {
			 n1 = n1 + 9; n2 = n1;
                         for (k1 = 0;k1<= 8; k1++)
                               {
                               	 n2 = n2 + 1;
                               	 if (aFilter[k1].find(aMove[n2],0) != -1) goto bSkip;
				}
                        aCount = aCount + 1; bCount = bCount + 1;
                        Move4[aCount] = Move2 + Move1[k2];
                        OutFile << Move4[aCount] << endl;
                        bSkip: k1 = 0;
                       }
               }
           cCount[k4] = bCount;
        } 
   for (k4 = 0;k4<= 6; k4+= 3) 
        OutFile << cCount[k4] << endl;
   OutFile.close();
}

void Row3()
{
  int k1, k2, k3, k4,n1, aPosit[19],aCount = -1, bCount[9], cCount = -1,aLen, aStart, aEnd;
  string x1, x2, aMove[36288], bMove, aGet[19], aCut; 
  char c1[99];
  ifstream InFile("362879.txt", ios::in);
  n1 = -1;
  for (k2 = 0; k2 <= 36287; k2++)
        {
          x1 = "";
          for (k1 = 1; k1 <= 10; k1++)
               {
               	  n1 = n1 + 1;
               	  InFile >> x2;
               	  x1 = x1 + x2;
		}
	  aMove[k2] = x1;
	}
  InFile.close();
  
  ofstream OutFile("1127r.txt", ios::out);
  for (k4 = 0; k4<= 8; k4++)
      {
	x1 = mGet[k4]; 
        aLen = x1.length(); x1.copy(c1,aLen);
        for (k3 = 0; k3< aLen; k3+= 2)
              {
                aPosit[k3] = int(c1[k3]) - 48;
                aGet[k3] = x1.substr(k3 + 1,1); 
	      }
        aStart = k4 * 9; aEnd = aStart + 8;
        for (k3 = 0; k3<= 36287; k3++)
              {
		bMove = aMove[k3];
	       for (k2 = 0; k2 <= 81; k2+= 9) //for (k2 = 0; k2 <= 81; k2+= 9)
		    {
			x1 = bMove.substr(k2,9); 
                        for (k1 = 0; k1< aLen; k1+= 2)
                              {
                              	n1 = aPosit[k1];
                              	x2 = x1.substr(n1,1); 
                              	if (x2 != aGet[k1]) goto aSkip;
			      }
                        n1 = -1;
                        for (k1 = aStart; k1<= aEnd; k1++)
                              {
                              	n1 = n1 + 1;
                              	x2 = x1.substr(n1,1);
                              	if (mCut[k1].find(x2,0) != -1) goto aSkip; 
			      }
                       aCount = aCount + 1; 
                       OutFile << x1 << endl;
                       aSkip: k1 = 0;
                    }
              }
         bCount[k4] = aCount; 
      } 
  for (k4 = 0; k4<= 8; k4++)
      OutFile << bCount[k4] << endl;
  OutFile.close();
}

void Load2()
{
  int k1, k2, k3, n1, n2, n3,aCount, aLen; 
  string x1, x2, x3, aMove, bMove,Index1[81], Index2[81], Index3[81]; 
  n1 = -1;
  for (k2 = 0; k2<= 8; k2++)
        {
	  x2 = "";
	  for (k1 = 0; k1<= 8; k1++)
            {
	     n1 = n1 + 1;
	     x1 = mPuz.substr(n1,1);
	     if (x1 != "0") 
	         {
		   nPuz[n1] = x1;
                     x2 = x2 + mNum[k1] + x1;
                  }
            }
           mGet[k2] = x2;
        }
  x1 = "111111111222222222333333333444444444555555555666666666777777777888888888999999999";
  x2 = "123456789123456789123456789123456789123456789123456789123456789123456789123456789";
  x3 = "111222333111222333111222333444555666444555666444555666777888999777888999777888999";
  for (k1 = 0; k1<= 80; k1++)
        {
	  Index1[k1] = x1.substr(k1,1);
          Index2[k1] = x2.substr(k1,1);
          Index3[k1] = x3.substr(k1,1);
        }
  for (k2 = 0; k2<= 80; k2++)
        {          
          if (nPuz[k2] == "")
              { 
		x1 = Index1[k2]; x2 = Index2[k2]; x3 = Index3[k2];
               aMove = "";
               for (k1 = 0; k1<= 80; k1++)
                    {
		      if (nPuz[k1] != "")
			  {
			    if (x1 != Index1[k1] && (x2 == Index2[k1] || x3 == Index3[k1]))
			        {
				  if (aMove.find(nPuz[k1],0) == -1)
				       {
				         aMove = aMove + nPuz[k1];	
				        }
                                }
                         }
                    }
               mCut[k2] = aMove; 
             }
        } 
 for (k3 = 0; k3<= 72; k3+= 9)
      {
        n1 = k3; n2 = n1 + 8;
        for (k2 = n1; k2<= n2; k2++)
              {
	        if (nPuz[k2] != "")
		    {
		      x1 = nPuz[k2];
                      for (k1 = n1; k1<= n2; k1++)
                             {
                               n3 = mCut[k1].find(x1,0); 
                               if (n3 != -1) mCut[k1].erase(n3,1);
			      }
		    }
              }
      } 
 n1 = -1;
 for (k2 = 0; k2 <= 80; k2++)
       {
	     x1 = Index1[k2]; x2 = Index2[k2]; x3 = Index3[k2];
         for (k1 = 0; k1 <= 80; k1++)
               {
		 if (k2 != k1)
                     if (x1 == Index1[k1] || x2 == Index2[k1] || x3 == Index3[k1])
                          {
                            n1 = n1 + 1;  mCheck[n1] = k1;
			   }
	       }
       }
 }
 
 void SetUp1()
 {   
   int k1,k2,k3,n1,n2,aCount = 0,aLen;
   string x1,x2, aNum,aMove[40320],bMove[40320];
  
   ofstream OutFile("362879.txt", ios::out);
   for (k3 = 1; k3 <= 9; k3++)
         {
           aNum = mNum[k3];
           aLen = aCount; aCount = -1;
           for (k2 = 0; k2 <= aLen; k2++)
                 aMove[k2] = bMove[k2];
           for (k2 = 0; k2 <= aLen; k2++)
                 {
                   x1 = aMove[k2];
		   for (k1 = 0; k1 <= k3 -1; k1++)
                        {
                          x2 = x1;
		          x2.insert(k1,aNum);
		          aCount = aCount + 1;
		          if (k3 != 9) 
			      bMove[aCount] = x2;
			  else
			      OutFile << x2 << endl;
		        }
		 }
         }
  OutFile.close();       
}
		  
 void aMain()
 { 
   SetUp1();
   Load2();
   Row3();
   Hook4();
   Hook5();
   Verify6();
 }
int main(int argc, char** argv)
 { 
   aMain();
   exit(0);
   system("PAUSE");
   return 0;
 }
Prgram B(Row to row solution):
C++ programs that print out all solutions for any sudoku puzzles
using BigData Coding techniques to develop the algorithm and the coding.

000008009050090000009004800002140003006000900400067100005900300000030070800400000
324718659758693412619524837582149763176385924493267185265971348941832576837456291
-----8--9
-5--9----
--9--48--
--214---3
--6---9--
4---671--
--59--3--
----3--7-
8--4-----

                  ALGORITHM
324718659758693412619524837582149763176385924493267185265971348941832576837456291
324 718 659
758 693 412
619 524 837

582 149 763
176 385 924
493 267 185

265 971 348
941 832 576
837 456 291
The group of numbers above represents a sudoku (in completed form in 2-D)
It is valu-based. We can read it as cell 0, value 3, cell 1, value 2. 
Another representation: Position-based, ASCII consecutive characters.
2>ALRaio~/?DKY^dr|.ALRaio~  Value 1 Positions: cell 4,16,19,30,36,51,59,65,80
/?DKY^dr|  Value 2 Positions
.= bStart && n2 <= bEnd) aPosit[n2] = 1;
                                  }
                        } 
                  for (k2 = bStart; k2<= bEnd; k2++)
                        {
			  if (aPosit[k2] == 0)
			      {
				aCount = aCount + 1; bMove[aCount] = x1 + mNum[k2];	
			      }
                        } 
               } 
       } 
 }
  ofstream OutFile("46655.txt", ios::out); // 5184 * 9 -1 = 46655 items of 9-string
  for (k1 = 0; k1 <= aCount; k1++)
       OutFile << bMove[k1] << endl;
  OutFile.close();

Step 3: Filter-in and Filter-out
  
    Arabic          ASCII
---  --8  --9    ---  --3  --6
-5-  -9-  ---    -8-  -;-  ---
--9  --4  8--    --B  --E  F--

--2  14-  --3   --K  LM-  --Q
--6  ---  9--   --T  ---  X--
4--  -67  1--   [--  -_`  a--
 
--5  9--  3--   --f  g--  j--
---  -3-  -7-   ---  -q-  -t-
8--  4--  ---   v--  y--  ---

for valued "1", the string:  .>  mMove[k1]; 
  InFile.close();
  ofstream OutFile("848Column.txt", ios::out);
   for (k3 = 1; k3<= 9; k3++)
        {
	   x1 = mGet[k3];
           aLen = x1.length();
           for (k2 = 0; k2< aLen; k2++)
                aGet[k2] = x1.substr(k2,1);
           x1 = mCut[k3];
           bLen = x1.length();
           for (k2 = 0; k2< bLen; k2++)
                aCut[k2] = x1.substr(k2,1);
           for (k2 = 0; k2<= 46655; k2++)
                 {
		   x1 = mMove[k2];
                   for (k1 = 0; k1< aLen; k1++)
                         if (x1.find(aGet[k1], 0) == -1) goto aSkip;
                   for (k1 = 0; k1< bLen; k1++)
                         if (x1.find(aCut[k1], 0) != -1) goto aSkip; 
		   aCount = aCount + 1;
                   OutFile << x1 << endl;
                   aSkip: k1 = 0;
                  }
          bCount[k3] = aCount;
        }
        
   for (k3 = 1; k3<= 9; k3++)
        OutFile << bCount[k3] << endl;
   OutFile.close();
}
 After filtering, 46655 strings become 848 strings and access index attached at the end.

Step 4: Join colum 1 group to 2,3,4,5,6,7,8
   Suppose x1 = "ABCDEFGHI" and x2 = "123456789"
   Can we join x1 to x2? Yes. Because no single character in x1 is found in x2.
   Suppose x1 = "ABCDEFGH1" and x2 = "123456789"
   Can we join x1 to x2? No. Because one character "1" in x1 is found in x2.
After joining 1 to 2-9. 848 strings of 9 become 1440 strings of 81.
  The 1440 solutions (column by column) must match 100 percent to those made in Program A.
Program B:
string mPuz = "000008009050090000009004800002140003006000900400067100005900300000030070800400000";
string mKey = "324718659758693412619524837582149763176385924493267185265971348941832576837456291";

int mIndex[486], mStart[72], mEnd[72], nIndex[810], nStart[80], nEnd[80];
int pStart[11], pEnd[10];
string mNum[81], mGet[10], mCut[10], nKey[81],nPuz[81], mMove[46656];
string mName[] = {"FileA.txt","FileB.txt"};

void Error8()
{ 
  int k1, k2, k3, n1, n2,aStart, aEnd;
  string x1, x2, aMove[1441], bMove, aIndex[81];
  ifstream InFile("File1.txt", ios::in);
  for (k2 = 0; k2 <= 1440; k2++)
       InFile >> aMove[k2];
  InFile.close();
  //aMove[1440] = aMove[1439];
  for (k2 = 0; k2 <= 1439; k2++)  // Duplicity check
        { 
           x1 = aMove[k2];
           for (k1 = k2+1; k1 <= 1440; k1++)
           if (x1 == aMove[k1]) cout << "Dup in " << k2 << " " << k1 << endl;
        }
  x1 =  aMove[1440].substr(0,72) +  "431875296";
  //aMove[1440] = x1;
  for (k2 = 0; k2 <= 1440; k2++) //Puzzle match check
        {
          x1 = aMove[k2];
          for (k1 = 0; k1 <= 80; k1++)
               {
		 if (nPuz[k1] != "")
		     {
			x2 = x1.substr(k1,1);
		        if (nPuz[k1] != x2) cout << "Puz mis-m" << k2 << " " << k1 << endl;
		     }
               }
        }
   //x1 = aMove[1440]; aMove[1440] = x1.substr(0,77) + "6529"; // Insert bad data
  for (k3 = 0; k3 <= 1440; k3++)  // Rules check
        {
           bMove = aMove[k3];
           for (k2 = 0; k2<= 80; k2++)
                aIndex[k2] = bMove.substr(k2,1);
           for (k2 = 0; k2<= 79; k2++)
                 {
		   x1 = aIndex[k2]; x2 = "";
                   aStart = nStart[k2]; aEnd = nEnd[k2];
                   for (k1 = aStart; k1<= aEnd; k1++)
                         {
			   n1 = nIndex[k1];
                           x2 = x2 + aIndex[n1];
                         }
                   if (x2.find(x1,0) != -1)
                        {
                          cout << "Rule violated: " << k3 << " " << k2 << endl;
                          break;
			}
           
                 }
        }
}

void Decode7() // Convert ASCII to Arabic
{ 
  int k1, k2, k3, n1, n2, aLen = -2, aIndex[81];
  string x1, aMove, bIndex[81];
  char c1[81];
  ifstream aInFile("FileA.txt", ios::in);
  do
    {
       aLen = aLen + 1;
       aInFile >> x1; 
    }  while (!aInFile.eof());
  aInFile.close();
  ifstream InFile("FileA.txt", ios::in);
  ofstream OutFile("File1.txt", ios::out);
  for (k3 = 0; k3 <= aLen; k3++)
        {            
          InFile >> aMove;
	  aMove.copy(c1,81); //Convert string to char and then to integer
          for (k2 = 0; k2 <= 80; k2++)
               aIndex[k2] = int(c1[k2]) - 46;
          n1 = -1;
          for (k2 = 3; k2 <= 11; k2++)    
                {
                   x1 = mNum[k2];
                   for (k1 = 1; k1 <= 9; k1++)
                         {
                	   n1 = n1 + 1;
                	   n2 = aIndex[n1];
                	   bIndex[n2] = x1;
		         }
	        }
          x1 = "";
          for (k2 = 0; k2 <= 80; k2++)
                x1 = x1 + bIndex[k2];
           OutFile << x1 << endl; 
        }
   InFile.close();
   OutFile.close();
   //cout << mKey << endl;
   //cout << x1 << endl;
   //if (mKey == x1) cout << "Both keys are the same" << endl;
}

void Join6(int pLen) //Recursive processing: Open FileA, process, save to FileB, vice versa.
{                    
  int k1, k2, k3, n1, n2, aCount = -1, bCount = 0, aLen, bLen,cLen = -2,aStart, aEnd; 
  string x1, x2, x3,aMove, bMove, cMove, aIndex[10]; 
  aLen = pLen; bLen = aLen - 2;
  n1 = aLen % 2;
  n2 = 1 - n1;
  x1 = mName[n1]; x2 = mName[n2];  
  ifstream InFile(x1.c_str(), ios::in); // Get the length() of the textfile
  do
    {
       cLen = cLen + 1;
       InFile >> x3; 
    }  while (!InFile.eof());
  InFile.close(); 
  ifstream aInFile(x1.c_str(), ios::in);
  ofstream OutFile(x2.c_str(), ios::out);
  aStart = pStart[aLen]; aEnd = pEnd[aLen];
  for (k3 = 0; k3 <= cLen; k3++)
        {      
	  aInFile >> aMove; 
          for (k2 = 0; k2 <= 8; k2++)
               {
                 x1 = ""; n1 = k2;
                 for (k1 = 0; k1 <= bLen; k1++)
                      { 
                         x1 = x1 + aMove.substr(n1,1);
                         n1 = n1 + 9;	
		      }
	        aIndex[k2] = x1;
	      } 
	     for (k2 = aStart; k2 <= aEnd; k2++)
	          {
			    bMove = mMove[k2];
                for (k1 = 0; k1 <= 8; k1++)
                     {
		       x1 = bMove.substr(k1,1);
                       if (aIndex[k1].find(x1,0) != -1) goto aSkip;
                     }
                    aCount = aCount + 1;
                    cMove = aMove + bMove;
                    OutFile << cMove << endl;
                    aSkip: k1 = 0;
                  } 
        }  
  aInFile.close(); 
  OutFile.close(); 
  cout << aCount << endl;  
}

void Join5()
{ 
  int k1, n1, aLen = -2;
  string x1;
  pStart[1] = 0;
  ifstream InFile("Column.txt", ios::in);
  ifstream aInFile("Column.txt", ios::in);
  do
    {
       aLen = aLen + 1;
       InFile >> x1; 
    }  while (!InFile.eof());
  InFile.close(); 
  aLen = aLen - 9;
  
  for (k1 = 0; k1<= aLen; k1++)
       aInFile >> mMove[k1];
      
 for (k1 = 1; k1<= 9; k1++)
        {
          aInFile >> n1; 
          pStart[k1 + 1] = n1 + 1;
          pEnd[k1] = n1;  
        }
  aInFile.close();

  n1 = pEnd[1]; 
  ofstream OutFile("FileA.txt", ios::out);
  for (k1 = 0; k1<= n1; k1++)
       OutFile << mMove[k1] << endl;
  OutFile.close();
 }

void Column4()
{
  int  k1, k2, k3, n1, n2, aCount = -1, bCount[10], aLen, bLen;
  string x1, x2, aGet[10], aCut[81]; 
  ofstream OutFile("Column.txt", ios::out);
         
  for (k3 = 1; k3<= 9; k3++)
        {
	   x1 = mGet[k3];
           aLen = x1.length();
           for (k2 = 0; k2< aLen; k2++)
                aGet[k2] = x1.substr(k2,1);
           x1 = mCut[k3];
           bLen = x1.length();
           for (k2 = 0; k2< bLen; k2++)
                aCut[k2] = x1.substr(k2,1);
           for (k2 = 0; k2<= 46655; k2++)
                 {
		   x1 = mMove[k2];
                   for (k1 = 0; k1< aLen; k1++)
                         if (x1.find(aGet[k1], 0) == -1) goto aSkip;
                   for (k1 = 0; k1< bLen; k1++)
                         if (x1.find(aCut[k1], 0) != -1) goto aSkip; 
		   aCount = aCount + 1;
                   OutFile << x1 << endl;
                   aSkip: k1 = 0;
                  }
          bCount[k3] = aCount;
        }
        
   for (k3 = 1; k3<= 9; k3++)
        OutFile << bCount[k3] << endl;
   OutFile.close();
}
 
void LoadPuz3()
{
  int k1, k2, n1, n2;
  string x1, x2, x3; 
  ifstream InFile("46655M.txt", ios::in);
  // 46655 universal column list. All puzzles have the same column list.
    for (k1 = 0; k1 <= 46655; k1++)
       InFile >>  mMove[k1]; 
  InFile.close();
  for (k1 = 0; k1<= 80; k1++)
        {
	   x1 = mPuz.substr(k1,1);
           if (x1 != "0") nPuz[k1] = x1; 
        }
    
  for (k2 = 1; k2<= 9; k2++)
        {
	   x1 = mNum[k2 +2];
	   x2 = ""; x3 = ""; 
           for (k1 = 0; k1<= 80; k1++)
                 {
                   if (nPuz[k1] == x1) x2 = x2 + mNum[k1];
		      if (nPuz[k1] != x1 && nPuz[k1] != "") x3 = x3 + mNum[k1];
		 }
          mGet[k2] = x2; 
          mCut[k2] = x3;
        }
  /*      
 string aShow[81]; //Display a puzzle in 2-D
 for (k1 = 0; k1 <= 80; k1++)
       {
       	x1 = nPuz[k1];
       	if (x1 == "") x1 = "-";
       	aShow[k1] = x1;
	   }
  n1 = -1;    
 for (k2 = 1; k2 <= 9; k2++)     
       {
       	 for (k1 = 1; k1 <= 9; k1++)
       	       {
       	       	 n1 = n1 + 1;
       	       	 cout << aShow[n1] + " ";
	       }
       	 cout << endl;     
      }
   */  
}
 
void Collum2()
{
  int k1, k2, k3, k4, n1, n2,aCount, aLen, aStart, aEnd,bStart, bEnd, aPosit[81];
  string x1, x2, x3, aMove[99999], bMove[99999]; 
  char c1[10];
  aCount = 8;
  bStart = 0;
  for (k4 = 0; k4 <= 8; k4++)
       bMove[k4] = mNum[k4];

  for (k4 = 0; k4 <= 7; k4++)
       {
         aLen = aCount; aCount = -1;
         bStart = bStart + 9; bEnd = bStart + 8; 
         for (k3 = 0; k3<= aLen; k3++)
              aMove[k3] = bMove[k3]; 
         for (k3 = 0; k3<= aLen; k3++)
               {
	            x1 = aMove[k3]; x1.copy(c1, k4 + 1); 
                  for (k2 = bStart; k2<= bEnd; k2++)
                        aPosit[k2] = 0; 
                  for (k2 = 0; k2<= k4; k2++)
                        {
			              n1 = int(c1[k2]) - 46;
                          aStart = mStart[n1]; aEnd = mEnd[n1];
                          for (k1 = aStart; k1<= aEnd; k1++)
                                  {
				                     n2 = mIndex[k1];
                                     if (n2 >= bStart && n2 <= bEnd) aPosit[n2] = 1;
                                  }
                        } 
                  for (k2 = bStart; k2<= bEnd; k2++)
                        {
			  if (aPosit[k2] == 0)
			      {
				aCount = aCount + 1; bMove[aCount] = x1 + mNum[k2];	
			      }
                        } 
               } 
       } 
 
  ofstream OutFile("46655M.txt", ios::out);
  for (k1 = 0; k1 <= aCount; k1++)
       OutFile << bMove[k1] << endl;
  OutFile.close();
}
 
 void SetUp1()
 { 
   int k1, k2, n1, n2, aCount = -1;
   string x1, x2, x3, aIndex[81], bIndex[81], cIndex[81]; 
   for (k1 = 0; k1 <= 80; k1++)
       	mNum[k1] = char(k1+46);
   //x1: rows; x2: columns; x3: mini-grid
   x1 = "111111111222222222333333333444444444555555555666666666777777777888888888999999999";
   x2 = "123456789123456789123456789123456789123456789123456789123456789123456789123456789";
   x3 = "111222333111222333111222333444555666444555666444555666777888999777888999777888999";
   for (k1 = 0; k1 <= 80; k1++)
      {
      	aIndex[k1] = x1.substr(k1,1);
      	bIndex[k1] = x2.substr(k1,1);
      	cIndex[k1] = x3.substr(k1,1);
      }
   for (k2 = 0; k2 <= 71; k2++)
        {
	      mStart[k2] = aCount + 1;
          x1 = aIndex[k2]; x2 = bIndex[k2]; x3 = cIndex[k2];
          for (k1 = k2 + 1; k1 <= 80; k1++)
               {
	             if (x1 != aIndex[k1] && (x2 == bIndex[k1] || x3 == cIndex[k1]))
	                 {
	                    aCount = aCount + 1;  mIndex[aCount] = k1; 
			 }
               }
            mEnd[k2] = aCount;
         }
 
   aCount = -1;
   for (k2 = 0; k2 <= 79; k2++)
       {
         nStart[k2] = aCount + 1;
         x1 = aIndex[k2]; x2 = bIndex[k2]; x3 = cIndex[k2];
         for (k1 = k2 + 1; k1 <= 80; k1++)
               {
                 if (x1 == aIndex[k1] || x2 == bIndex[k1] || x3 == cIndex[k1])
                      {
                      	aCount = aCount + 1; nIndex[aCount] = k1;
                      }
	       }
         nEnd[k2] = aCount;
       } 
 } 
void aMain()
 { 
   int k1;
   SetUp1();
   Collum2();
   LoadPuz3();
   Column4();
   Join5();
   or (k1 = 2; k1 <= 9; k1++)
      Join6(k1);
   Decode7();
   Error8();
 }
int main(int argc, char** argv)
 { aMain();
   exit(0);
   system("PAUSE");
   return 0; }

Section 10: Print 6 million knight's Tours

Section 10 An example of using dynamic permutation in PC (2 million Closed Tours). Program A: Make a single closed tour. Step 1 SetUp1(): a. Set up a 2-D representation for the chessboard to filter out the out of bounds moves; b. Index each cell's moves: mIndex[n] c. Index each cell's acess point. Cell 0's access point is 2, meaning a knight in that cell can move to other 2 cells (Cell 10 and 17) and Cell 1's access point is 3, meaning a knight in that cell can move to other 3 cells. Step 2 GetTour2(): Put the knight in the first cell (Cell 0). Now the The tour's string is 0: The move is 0 The iteration: a. Change the Cell 0's value from 0 to 99 b. Access the cell 0's moves(10,17: :A) c. Cut one point from both cell 10 and 17's access points. d. For the first move: Pick the cell that has the smallest access point (cell 10). Now the tour's string: 0: (cell 0 and 10) The move is :(10); Spin the for loop for another 62 times. You get a full knight's closed tour: 0:4>O^oe_ndj`Q@1;5?ND39HYhblfU[JPakZiXI8BS]gmcTE6GVL=7FWM<2CR\KA(0 to 17) 1 16 59 22 3 18 49 54 40 23 2 17 58 53 4 19 15 64 41 60 21 48 55 50 24 39 32 63 52 57 20 5 33 14 61 42 47 30 51 56 38 25 36 31 62 43 6 9 13 34 27 46 11 8 29 44 26 37 12 35 28 45 10 7 Here is the program: int mIndex[336], mStart[64], mEnd[64], mRate[64]; string mNum[64]; void GetTour2() { int k1, k2, n1, n2, aCount = -1,aMove, aStart, aEnd, aMin; string x1, aTour,aNum[70]; char c1[64]; aMove = 0; aTour = mNum[aMove]; for (k2 = 2; k2 <= 64; k2++) { mRate[aMove] = 99; aStart = mStart[aMove]; aEnd = mEnd[aMove]; aMin = 99; for (k1 = aStart; k1 <= aEnd; k1++) { n1 = mIndex[k1]; mRate[n1] = mRate[n1] - 1; if (aMin > mRate[n1]) { aMin = mRate[n1]; aMove = n1; } } aTour = aTour + mNum[aMove]; } cout << "Representaion of a Knight's Closed Tour:" << endl; cout << aTour << endl; for (k2 = 0; k2 <= 6; k2++) { x1 = mNum[k2]; if (k2 == 0) x1 = " "; for (k1 = 0; k1 <= 9; k1++) { aCount = aCount + 1; aNum[aCount] = x1 + mNum[k1]; } } aTour.copy(c1,64); string aShow[64]; for (k1 = 0; k1 <= 63; k1++) { n1 = int(c1[k1]) - 48; aShow[n1] = aNum[k1+1]; } cout << endl; aCount = -1; for (k2 = 1; k2 <= 8; k2++) { for (k1 = 1; k1 <= 8; k1++) { aCount = aCount + 1; cout << aShow[aCount] + " "; } cout << endl << endl; } } void SetUp1() { int k1, k2, n1, n2, n3, aCount = -1, aFilter[64], bFilter[120]; int aStep[] = {12,-21,-19,21,-12,-8,19,8}; string x1, x2; char c1[64]; for (k1 = 0; k1 <= 63; k1++) mNum[k1] = char(k1+48); for (k1 = 0; k1 <= 119; k1++) bFilter[k1] = 64; for (k2 = 21; k2 <= 91; k2+= 10) { for (k1 = k2; k1<= k2 + 7; k1++) { aCount = aCount + 1; aFilter[aCount] = k1; bFilter[k1] = aCount; } } aCount = -1; for (k2 = 0; k2<= 63; k2++) { n1 = aFilter[k2]; mStart[k2] = aCount + 1; for (k1 = 0; k1<= 7; k1++) { n2 = n1 + aStep[k1]; n3 = bFilter[n2]; if (n3 != 64) { aCount = aCount + 1; mIndex[aCount] = n3; } } mEnd[k2] = aCount; } x1 = "2344443234666643468888644688886446888864468888643466664323444432"; x1.copy(c1,64); for (k1 = 0; k1<= 63;k1++) mRate[k1] = int(c1[k1]) - 48; } void aMain() { int k1,k2,n1,n2; string x1,x2; SetUp1(); GetTour2(); } int main(int argc, char** argv) { int k1,k2,n1,n2; string x1,x2; aMain(); exit(0); system("PAUSE"); return 0; } Program B: Print 6 million tours. It takes about 45 minutes to run this program. An example of using Brute Force in a PC Algorithm Using an incompleted knight tour (29 moves, Part 1) as a starting point to complete the rest 35 moves. I permutate the 35 moves and generate 6 million Part 2 tours. I use ASCII to represent Part 1 moves (in Fuction SetUp1()): "A0:4>O^oe_ndj`Q@1;5?ND39HYhbl" = "17,0,10,4,14,31,46,63,53,47,62,52,58,48,33,16,1,11,5,15,30,20,3,9,24,41,56,50,60" 3 ways to represent the chessboard 1-D 2-D ASCII 0 1 2 3 4 5 6 7 21 22 23 24 25 26 27 28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 31 32 33 34 35 36 37 38 8 9 : ; < = > ? 16 17 18 19 20 21 22 23 41 42 43 44 45 46 47 48 @ A B C D E F G 24 25 26 27 28 29 30 31 51 52 53 54 55 56 57 58 H I J K L M N O 32 33 34 35 36 37 38 39 61 62 63 64 65 66 67 68 P Q R S T U V W 40 41 42 43 44 45 46 47 71 72 73 74 75 76 77 78 X Y Z [ \ ] ^ _ 48 49 50 51 52 53 54 55 81 82 83 84 85 86 87 88 ` a b c d e f g 56 57 58 59 60 61 62 63 91 92 93 94 95 96 97 98 h i j k l m n o 1 2 3 4 5 6 7 8 02 17 -- 23 04 19 -- -- 1 -- 24 03 18 -- -- 05 20 2 16 01 -- -- 22 -- -- -- 3 25 -- -- -- -- -- 21 06 4 -- 15 -- -- -- -- -- -- 5 -- 26 -- -- -- -- 07 10 6 14 -- 28 -- 12 09 -- -- 7 27 -- 13 -- 29 -- 11 08 8 Step 1 (SetUp1()) I compile acess index: mIndex(149), integer and nIndex(149), string and acess retrieving index: mStart(63) and mEnd(63). The first available cell is cell 2. Its acessible cells: 8,12,19 or 8 ? @ A B C D E F G H I J K L M N O P Q R S T U V W - - - [ - ] - - - - - - - - f - - - - - l - - - I save the 168,272 tours into a textfile named move1.txt. Step 3 (PileUp3()) Opening up the move1.txt,I first filter out the bad tours. The 168,272 tours are reduced about 90%. Then 10-moves tours pick up one move and I save the tours into move2.txt Now I call PileUp3() again to pick up yet another move and save the tours into move1.txt. What happens is: open move1, pick up a move and then save the tours into move2.txt And open move2, pick up a move and then save the tours into move1.txt. I stop when I get the 33 moves. Now I get 6 million tours. Notice that I do not use an array to represent the tours. Instead, I load up a move, process it and then save it outside the program. Step 4 (PileUp4()) Now there is no more filtering operations. Just pick up another 2 moves. The tours are completed (35 moves, 6 million tours) void PileUp4(int pCount) { int k1, k2, k3, n1, n2, aCount = -1,aLen = -2, aStart, aEnd, aTail; string x1, x2, aMove, bMove, aName,bName; char c1[1]; aName = fName[pCount]; bName = fName[pCount+1]; ifstream aInFile(aName.c_str(), ios::in); do { aLen = aLen + 1; aInFile >> x1; } while (!aInFile.eof()); // Find out the length of the text file. aInFile.close(); ifstream InFile(aName.c_str(), ios::in); ofstream OutFile(bName.c_str(), ios::out); for (k2 = 0; k2 <= aLen; k2++) { InFile >> aMove; bMove = aMove.substr(pCount -1,1); bMove.copy(c1,1); aTail = int(c1[0]) - 48; aStart = mStart[aTail]; aEnd = mEnd[aTail]; for (k1 = aStart; k1 <= aEnd; k1++) { x1 = nIndex[k1]; if (aMove.find(x1,0) == -1) { aCount = aCount + 1; x2 = aMove + x1; OutFile << x2 << endl; } } } OutFile.close(); InFile.close(); cout << pCount << " " << aCount << " " << x2 << " " << x2.length() << endl; } void PileUp3(int pCount) { int k1, k2, k3, n1, n2, aCount = -1,aLen, aStart, aEnd, aTail,aPosit[64], bPosit[64]; string x1, x2, aMove, bMove, aName, bName; char c1[35]; aName = fName[pCount]; bName = fName[pCount+1]; ifstream aInFile(aName.c_str(), ios::in); aLen = -2; do { aLen = aLen + 1; aInFile >> x1; } while (!aInFile.eof()); aInFile.close(); ifstream InFile(aName.c_str(), ios::in); ofstream OutFile(bName.c_str(), ios::out); for (k3 = 0; k3 <= aLen; k3++) { InFile >> aMove; aMove.copy(c1,pCount); for (k2 = 0; k2<= 63; k2++) { aPosit[k2] = mPosit[k2]; bPosit[k2] = mPosit[k2]; } for (k2 = 0; k2< pCount; k2++) { n1 = int(c1[k2]) - 48; aPosit[n1] = 1; bPosit[n1] = 1; } aTail = n1; bPosit[n1] = 0; bPosit[17] = 0; for (k2 = 0; k2<= 63; k2++) { if (aPosit[k2] == 0) { aStart = mStart[k2]; aEnd = mEnd[k2]; n1 = 0; for (k1 = aStart; k1<= aEnd; k1++) { n2 = mIndex[k1]; n1 = n1 + (1 - bPosit[n2]); } if (n1 < 2) goto aSkip; } } aStart = mStart[aTail]; aEnd = mEnd[aTail]; for (k2 = aStart; k2<= aEnd; k2++) { x1 = nIndex[k2]; if (aMove.find(x1,0) == -1) { aCount = aCount + 1; x2 = aMove + x1; OutFile << x2 << endl; } } aSkip: k1 = 0; } OutFile.close(); InFile.close(); cout<< pCount << " " << aCount << " " << x2 << " " << x2.length() << endl; } void PileUp2() { int k1,k2, k3, n1, n2,n3,aCount = 2, aLen,aStart,aEnd, aTail; string x1,x2,aMove[60840],bMove[168272]; char c1[10]; bMove[0] = "["; bMove[1] = "]";bMove[2] = "f"; for (k3 = 0; k3<= 8; k3++) { aLen = aCount; aCount = -1; for (k2 = 0; k2<= aLen; k2++) aMove[k2] = bMove[k2]; for (k2 = 0; k2<= aLen; k2++) { x1 = aMove[k2]; x2 = x1.substr(k3,1); x2.copy(c1,1); aTail = int(c1[0]) - 48; aStart = mStart[aTail]; aEnd = mEnd[aTail]; for (k1 = aStart; k1<= aEnd; k1++) { x2 = nIndex[k1]; if (x1.find(x2,0) == -1) { aCount = aCount + 1; bMove[aCount] = x1 + nIndex[k1]; } } } } ofstream OutFile("Move1.txt", ios::out); for (k1 = 0; k1 <= aCount; k1++) OutFile << bMove[k1] << endl; OutFile.close(); } void SetUp1() { int k1,k2, n1 = -1, n2,n3,aCount = -1, aFilter[64], bFilter[120]; int aStep[] = {-21,-19,-12,-8,8,12,19,21}; string x1,x2; char c1[64]; for (k1 = 0; k1 <= 63; k1++) mNum[k1] = char(k1+48); for (k1 = 0; k1 <= 119; k1++) bFilter[k1] = -1; x1 = "A0:4>O^oe_ndj`Q@1;5?ND39HYhbl"; x1.copy(c1,29); for (k1 = 0; k1<= 28; k1++) { n1 = int(c1[k1]) - 48; mPosit[n1] = 1; } for (k2 = 21; k2<= 91; k2+= 10) for (k1 = k2; k1<= k2 + 7; k1++) { aCount = aCount + 1; aFilter[aCount] = k1; if (mPosit[aCount] == 1) bFilter[k1] = -1; else bFilter[k1] = aCount; } aCount = -1; for (k2 = 0; k2<= 63; k2++) { if (mPosit[k2] == 0) { mStart[k2] = aCount + 1; n1 = aFilter[k2]; for (k1 = 0; k1<= 7; k1++) { n2 = n1 + aStep[k1]; n3 = bFilter[n2]; if (n3 != -1) { aCount = aCount + 1; mIndex[aCount] = n3; nIndex[aCount] = mNum[n3]; } } } mEnd[k2] = aCount; } x1 = "Move1.txt"; x2 = "Move2.txt"; for (k1 = 10; k1 <= 34; k1+= 2) { fName[k1] = x1; fName[k1 + 1] = x2; } } void aMain() { int k1,k2,n1,n2; string x1,x2; SetUp1(); PileUp2(); for (k1 = 10; k1 <= 32; k1++) PileUp3(k1); PileUp4(33); PileUp4(34); } int main(int argc, char** argv) { int k1,k2,n1,n2; string x1,x2; aMain(); exit(0); system("PAUSE"); return 0; } Program C(processing Move2.txt): After Program B I have a textfile named Move2.txt that is a list of 6 million knight's tours, each one is 35 characters (35 move). It is time to check for errors Algorithm Check the 6 million tours for errors: 1.Duplicate tour (one tour shows up in the tour list more than once) 2.Duplicate move(64 in total) one move shows up more than once within the same tour). 3.Wrong move (a move is not a L-shaped). 1. Duplicate tour Since the list of 6 million tours is already in correct order, any duplicate items are next to each other. I only need to make 6 million comparisons: compare item 0 to item 1 and item 1 to 2, so on. 2. Duplicate move Each of the 6 million tours is the position variation of the string: fU[JPakZiXI8BS]gmcTE6GVL=7FWM<2CR\K. I load up a tour and substr the tour one by one and erase the substr item from the above string. At the end of delete, the string is empty, meaning the tour passes. 3. Wrong move I index each cell's acess moves: mIndex[n]. Suppose the first move falls on cell 2(2), and second move is on 17(A). The move from 2 to 17 is L-shaped because mIndex[2] = 2O^oe_ndj`Q@1;5?ND39HYhbl" to the tours to form the complete tours. Here is the program: string mNum[64],mIndex[64], mTour; void Check6() { int k1; string x1, x2, aMove, p1; p1 = "0:4>O^oe_ndj`Q@1;5?ND39HYhbl"; ifstream InFile("Move2.txt", ios::in); ofstream OutFile("6587629a.txt", ios::out); for (k1 = 0; k1 <= 6587629; k1++) { InFile >> x1; aMove = p1 + x1; OutFile << aMove << endl; } OutFile.close(); InFile.close(); } void Check5() { int k1; string x1, aMove,aCheck ="2KPR"; ifstream InFile("Move2.txt", ios::in); ofstream OutFile("2024129.txt", ios::out); for (k1 = 0; k1 <= 6587629; k1++) { InFile >> aMove; x1 = aMove.substr(34,1); if (aCheck.find(x1,0) != -1) OutFile << aMove << endl; } OutFile.close(); InFile.close(); } void Check4() { int k1, k2, n1; string x1, aMove; char c1[35]; ifstream InFile("Move2.txt", ios::in); for (k2 = 0; k2 <= 6587629; k2++) { InFile >> aMove; aMove.copy(c1,35); for (k1 = 0; k1 <= 33; k1++) { x1 = aMove.substr(k1,1); n1 = int(c1[k1+1]) - 48; if (mIndex[n1].find(x1,0) == -1) { cout << "Error in: " << k2 << endl; } } } InFile.close(); } void Check3() { int k1, k2, n1, n2; string x1, x2, aMove; ifstream InFile("Move2.txt", ios::in); for (k2 = 0; k2 <= 6587629; k2++) { InFile >> x1; aMove = mTour; for (k1 = 0; k1 <= 34; k1++) { x2 = x1.substr(k1,1); n1 = aMove.find(x2,0); aMove.erase(n1,1); } if (aMove != "") cout << k2 << " " << aMove << endl; } InFile.close(); } void Check2() { int k1; string x1,x2; ifstream InFile("Move2.txt", ios::in); for (k1 = 0; k1 <= 6587629; k1++) { InFile >> x1; if (x1 <= x2) cout << x2 << " " << x1 << " " << k1 << endl; x2 = x1; } InFile.close(); } void SetUp1() { int k1,k2, n1 = -1, n2,n3,aCount = -1, aFilter[64], bFilter[120]; int aStep[] = {-21,-19,-12,-8,8,12,19,21}, aPosit[64] = {0}; string x1,x2; char c1[64]; for (k1 = 0; k1 <= 63; k1++) mNum[k1] = char(k1+48); for (k1 = 0; k1 <= 119; k1++) bFilter[k1] = -1; x1 = "A0:4>O^oe_ndj`Q@1;5?ND39HYhbl"; x1.copy(c1,29); for (k1 = 0; k1<= 28; k1++) { n1 = int(c1[k1]) - 48; aPosit[n1] = 1; } for (k1 = 0; k1 <= 63; k1++) if (aPosit[k1] == 0) mTour = mTour + mNum[k1]; for (k2 = 21; k2<= 91; k2+= 10) for (k1 = k2; k1<= k2 + 7; k1++) { aCount = aCount + 1; aFilter[aCount] = k1; if (aPosit[aCount] == 1) bFilter[k1] = -1; else bFilter[k1] = aCount; } aCount = -1; for (k2 = 0; k2<= 63; k2++) { if (aPosit[k2] == 0) { n1 = aFilter[k2]; x1 = ""; for (k1 = 0; k1<= 7; k1++) { n2 = n1 + aStep[k1]; n3 = bFilter[n2]; if (n3 != -1) x1 = x1 + mNum[n3]; } } mIndex[k2] = x1; } } void aMain() { int k1,k2,n1,n2; string x1,x2; SetUp1(); Check5(); } int main(int argc, char** argv) { int k1,k2,n1,n2; string x1,x2; aMain(); exit(0); system("PAUSE"); return 0; }