I was going to try to mask the code, but then I thought, why? It's not as if this is some top secret project. It's just a personal project and if someone really wants to steal my idea, not only would I be extremely surprised, but I don't see why I should care either. Perhaps I should be embarrassed about the code being inelegant, but whatever. As I said, this is just a personal project, it doesn't have to be super efficient or fancy. But the inefficiency of the current load method DOES need to get fixed.
The program is attempting to create EVERY possible legal board for a game of Connect 4. Each iteration represents a specific turn in the game. I load all of the boards from the previous turn, remove any "winners" from the previous turn, then calculate every possible response for the current turn. It doesn't matter whether it would be "stupid" to make a certain play, only whether it is "legal" by the rules of the game.
The input files are all simply lines of text similar to these:
AeeeeeeRReeeeeeeeeeeeeeeeeeeeeeeeeeeeBBeeee
AeeeeeeReeeeeBBReeeeeeeeeeeeeeeeeeeeeeeeeee
AeeeeeeReeeeeBBeeeeReeeeeeeeeeeeeeeeeeeeeee
AeeeeeeReeeeeBBeeeeeeeeeeReeeeeeeeeeeeeeeee
These were pulled straight from a section of the output file for the 4th iteration. Each iteration fills in one more of the 'e'mpty values with either a 'B'lack or 'R'ed, according to the rules of Connect 4.
The program is a simple console app. Here's both the main() and LoadData() functions from the current version. When I tried to move the file manipulation into Main and just pass the file pointer into the load function, I couldn't get it to work correctly for some reason.
Code:
int main(int argc, char* argv[])
{
bool bMore = false;
int x,
col,
row,
iCount,
iOffset;
char cField[80],
cPlayer;
BOARD *sCurrBoard = 0;
strcpy (sBoard.cBoard, "Aeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
for (x = LEVEL; x < LEVEL + DEPTH; x++)
{
iOffset = -OFFSET;
if (x % 2 == 0)
cPlayer = 'R';
else
cPlayer = 'B';
cout << "Loading Data from level " << (x - 1) << ".\n";
do
{
iOffset += OFFSET;
cout << x << " = " << iOffset << " - " << iOffset + OFFSET << '\n';
bMore = LoadData(x - 1, iOffset / OFFSET);
if (iTotalBoards > 0)
{
sCurrBoard = sPrevBoard.next;
iCount = 0;
iNewTotal = 0;
cout << "Calculating moves for level " << x << ".\n";
while (sCurrBoard)
{
if ( (iCount % 1000) == 0)
cout << "Board #" << iCount + iOffset << " of #"
<< iTotalBoards + iOffset << ".\n";
strcpy (cField, sCurrBoard->cBoard);
for (col = 1; col < 8; col++)
{
row = 1;
while ( (row < 7)
&& (cField[(col - 1) * 6 + row] != 'e')
)
{
row ++;
}
if (row < 7)
{
cField[(col - 1) * 6 + row] = cPlayer;
InsertBoard (cField, (BOARD*) calloc (1, sizeof (BOARD) ) );
iNewTotal++;
cField[(col - 1) * 6 + row] = 'e';
}
}
sCurrBoard = sCurrBoard->next;
iCount++;
}
cout << "Removing duplicates and sorting.\n";
SortBoards ();
cout << "Marking winners for level " << x << ".\n";
MarkWinners ();
cout << "Saving data for level " << x << ".\n";
SaveData (x, iOffset / OFFSET);
ClearData (sBoard.next);
ClearData (sPrevBoard.next);
sBoard.next = 0;
sPrevBoard.next = 0;
}
} while (bMore);
FileMerge (x, iOffset / OFFSET + 1);
}
return 0;
}
bool LoadData (int iLevel, int iOffset)
{
char sData[360] = {0},
sFile[80];
BOARD *pNewBoard = 0,
*pCurrBoard = 0;
bool bMore = false;
if (iOffset == 0)
sprintf (sFile, "c:\\dev\\connect4\\connect4\\level%d.txt", iLevel);
else
sprintf (sFile, "c:\\dev\\connect4\\connect4\\level%dload%d.txt", iLevel, iOffset);
ifstream Data(sFile);
Data >> sData;
pCurrBoard = &sPrevBoard;
iTotalBoards = 0;
while ( (strlen (sData) > 20)
&& (iTotalBoards < OFFSET)
)
{
if (sData[0] == 'A')
{
pNewBoard = (BOARD*) calloc (1, sizeof (BOARD) );
strcpy (pNewBoard->cBoard, sData);
pCurrBoard->next = pNewBoard;
pCurrBoard = pNewBoard;
iTotalBoards++;
}
if (iTotalBoards < OFFSET)
Data >> sData;
}
if (strlen (sData) > 20)
{
Data >> sData;
if (strlen (sData) > 20)
{
sprintf (sFile, "c:\\dev\\connect4\\connect4\\level%dload%d.txt", iLevel, iOffset + 1);
ofstream Data2 (sFile);
while (strlen (sData) > 20)
{
Data2 << sData << '\n';
Data >> sData;
}
bMore = true;
Data2.close();
}
}
Data.close();
if (iOffset != 0)
{
sprintf (sFile, "c:\\dev\\connect4\\connect4\\level%dload%d.txt", iLevel, iOffset);
remove (sFile);
}
return bMore;
}
As I think about it more, I suspect my problem was probably one of scope. Specifically that I declared the file pointer at a level where it was ending up out of scope before I got back to it. But I don't have the code from those attempts any more, so I can't be sure.