perfect: Format code with msvc
This commit is contained in:
parent
5c71717a9c
commit
f74762d2c7
|
@ -27,8 +27,7 @@ BufferedFile::BufferedFile(unsigned int numberOfThreads, unsigned int bufferSize
|
|||
bytesInReadBuffer = new unsigned int[numThreads];
|
||||
bytesInWriteBuffer = new unsigned int[numThreads];
|
||||
|
||||
for (curThread = 0; curThread < numThreads; curThread++)
|
||||
{
|
||||
for (curThread = 0; curThread < numThreads; curThread++) {
|
||||
curReadingPointer[curThread] = 0;
|
||||
curWritingPointer[curThread] = 0;
|
||||
bytesInReadBuffer[curThread] = 0;
|
||||
|
@ -40,8 +39,7 @@ BufferedFile::BufferedFile(unsigned int numberOfThreads, unsigned int bufferSize
|
|||
hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
hFile = nullptr;
|
||||
return;
|
||||
}
|
||||
|
@ -91,8 +89,7 @@ long long BufferedFile::getFileSize()
|
|||
//-----------------------------------------------------------------------------
|
||||
bool BufferedFile::flushBuffers()
|
||||
{
|
||||
for (unsigned int threadNo = 0; threadNo < numThreads; threadNo++)
|
||||
{
|
||||
for (unsigned int threadNo = 0; threadNo < numThreads; threadNo++) {
|
||||
writeDataToFile(hFile, curWritingPointer[threadNo] - bytesInWriteBuffer[threadNo], bytesInWriteBuffer[threadNo], &writeBuffer[threadNo * bufferSize + 0]);
|
||||
bytesInWriteBuffer[threadNo] = 0;
|
||||
}
|
||||
|
@ -115,18 +112,14 @@ void BufferedFile::writeDataToFile(HANDLE hFile, long long offset, unsigned int
|
|||
while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
|
||||
cout << endl
|
||||
<< "SetFilePointerEx failed!";
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesWritten;
|
||||
pData = (void *)(((unsigned char *)pData) + dwBytesWritten);
|
||||
if (restingBytes > 0)
|
||||
cout << endl
|
||||
<< "Still " << restingBytes << " to write!";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cout << endl
|
||||
<< "WriteFile Failed!";
|
||||
}
|
||||
|
@ -150,18 +143,14 @@ void BufferedFile::readDataFromFile(HANDLE hFile, long long offset, unsigned int
|
|||
while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
|
||||
cout << endl
|
||||
<< "SetFilePointerEx failed!";
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesRead;
|
||||
pData = (void *)(((unsigned char *)pData) + dwBytesRead);
|
||||
if (restingBytes > 0)
|
||||
cout << endl
|
||||
<< "Still " << restingBytes << " to read!";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cout << endl
|
||||
<< "ReadFile Failed!";
|
||||
}
|
||||
|
@ -193,8 +182,7 @@ bool BufferedFile::writeBytes(unsigned int threadNo, long long positionInFile, u
|
|||
// locals
|
||||
|
||||
// if buffer full or not sequential write operation write buffer to file
|
||||
if (bytesInWriteBuffer[threadNo] && (positionInFile != curWritingPointer[threadNo] || bytesInWriteBuffer[threadNo] + numBytes >= bufferSize))
|
||||
{
|
||||
if (bytesInWriteBuffer[threadNo] && (positionInFile != curWritingPointer[threadNo] || bytesInWriteBuffer[threadNo] + numBytes >= bufferSize)) {
|
||||
|
||||
writeDataToFile(hFile, curWritingPointer[threadNo] - bytesInWriteBuffer[threadNo], bytesInWriteBuffer[threadNo], &writeBuffer[threadNo * bufferSize + 0]);
|
||||
bytesInWriteBuffer[threadNo] = 0;
|
||||
|
@ -231,8 +219,7 @@ bool BufferedFile::readBytes(unsigned int threadNo, long long positionInFile, un
|
|||
return false;
|
||||
|
||||
// read from file into buffer if not enough data in buffer or if it is not an sequential reading operation?
|
||||
if (positionInFile != curReadingPointer[threadNo] || bytesInReadBuffer[threadNo] < numBytes)
|
||||
{
|
||||
if (positionInFile != curReadingPointer[threadNo] || bytesInReadBuffer[threadNo] < numBytes) {
|
||||
bytesInReadBuffer[threadNo] = ((positionInFile + bufferSize <= fileSize) ? bufferSize : (unsigned int)(fileSize - positionInFile));
|
||||
if (bytesInReadBuffer[threadNo] < numBytes)
|
||||
return false;
|
||||
|
|
|
@ -29,8 +29,7 @@ CyclicArray::CyclicArray(unsigned int blockSizeInBytes, unsigned int numberOfBlo
|
|||
hFile = CreateFileA(fileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
hFile = nullptr;
|
||||
return;
|
||||
}
|
||||
|
@ -67,18 +66,14 @@ void CyclicArray::writeDataToFile(HANDLE hFile, long long offset, unsigned int s
|
|||
cout << endl
|
||||
<< "SetFilePointerEx failed!";
|
||||
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesWritten;
|
||||
pData = (void *)(((unsigned char *)pData) + dwBytesWritten);
|
||||
if (restingBytes > 0)
|
||||
cout << endl
|
||||
<< "Still " << restingBytes << " to write!";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cout << endl
|
||||
<< "WriteFile Failed!";
|
||||
}
|
||||
|
@ -101,18 +96,14 @@ void CyclicArray::readDataFromFile(HANDLE hFile, long long offset, unsigned int
|
|||
cout << endl
|
||||
<< "SetFilePointerEx failed!";
|
||||
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesRead;
|
||||
pData = (void *)(((unsigned char *)pData) + dwBytesRead);
|
||||
if (restingBytes > 0)
|
||||
cout << endl
|
||||
<< "Still " << restingBytes << " to read!";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cout << endl
|
||||
<< "ReadFile Failed!";
|
||||
}
|
||||
|
@ -130,8 +121,7 @@ bool CyclicArray::addBytes(unsigned int numBytes, unsigned char *pData)
|
|||
unsigned int bytesWritten = 0;
|
||||
|
||||
// write each byte
|
||||
while (bytesWritten < numBytes)
|
||||
{
|
||||
while (bytesWritten < numBytes) {
|
||||
|
||||
// store byte in current reading block
|
||||
*curWritingPointer = *pData;
|
||||
|
@ -140,12 +130,10 @@ bool CyclicArray::addBytes(unsigned int numBytes, unsigned char *pData)
|
|||
pData++;
|
||||
|
||||
// when block is full then save current one to file and begin new one
|
||||
if (curWritingPointer == writingBlock + blockSize)
|
||||
{
|
||||
if (curWritingPointer == writingBlock + blockSize) {
|
||||
|
||||
// copy data into reading block?
|
||||
if (curReadingBlock == curWritingBlock)
|
||||
{
|
||||
if (curReadingBlock == curWritingBlock) {
|
||||
memcpy(readingBlock, writingBlock, blockSize);
|
||||
curReadingPointer = readingBlock + (curReadingPointer - writingBlock);
|
||||
}
|
||||
|
@ -192,8 +180,7 @@ bool CyclicArray::takeBytes(unsigned int numBytes, unsigned char *pData)
|
|||
unsigned int bytesRead = 0;
|
||||
|
||||
// read each byte
|
||||
while (bytesRead < numBytes)
|
||||
{
|
||||
while (bytesRead < numBytes) {
|
||||
|
||||
// was current reading byte already written ?
|
||||
if (curReadingBlock == curWritingBlock && curReadingPointer == curWritingPointer && readWriteInSameRound)
|
||||
|
@ -206,8 +193,7 @@ bool CyclicArray::takeBytes(unsigned int numBytes, unsigned char *pData)
|
|||
pData++;
|
||||
|
||||
// load next block?
|
||||
if (curReadingPointer == readingBlock + blockSize)
|
||||
{
|
||||
if (curReadingPointer == readingBlock + blockSize) {
|
||||
|
||||
// go to next block
|
||||
curReadingBlock = (curReadingBlock + 1) % numBlocks;
|
||||
|
@ -215,12 +201,9 @@ bool CyclicArray::takeBytes(unsigned int numBytes, unsigned char *pData)
|
|||
readWriteInSameRound = true;
|
||||
|
||||
// writing block reached ?
|
||||
if (curReadingBlock == curWritingBlock)
|
||||
{
|
||||
if (curReadingBlock == curWritingBlock) {
|
||||
curReadingPointer = writingBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// set pointer to beginnig of reading block
|
||||
curReadingPointer = readingBlock;
|
||||
|
@ -261,16 +244,14 @@ bool CyclicArray::loadFile(const char *fileName, LONGLONG &numBytesLoaded)
|
|||
hLoadFile = CreateFileA(fileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hLoadFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hLoadFile == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// does data of file fit into cyclic array ?
|
||||
GetFileSizeEx(hLoadFile, &largeInt);
|
||||
|
||||
if (maxFileSize < largeInt.QuadPart)
|
||||
{
|
||||
if (maxFileSize < largeInt.QuadPart) {
|
||||
CloseHandle(hLoadFile);
|
||||
return false;
|
||||
}
|
||||
|
@ -287,8 +268,7 @@ bool CyclicArray::loadFile(const char *fileName, LONGLONG &numBytesLoaded)
|
|||
dataInFile = new unsigned char[blockSize];
|
||||
|
||||
//
|
||||
for (curBlock = 0; curBlock < numBlocksInFile - 1; curBlock++, curOffset += blockSize)
|
||||
{
|
||||
for (curBlock = 0; curBlock < numBlocksInFile - 1; curBlock++, curOffset += blockSize) {
|
||||
|
||||
// load data from file
|
||||
readDataFromFile(hLoadFile, curOffset, blockSize, dataInFile);
|
||||
|
@ -325,8 +305,7 @@ bool CyclicArray::saveFile(const char *fileName)
|
|||
void *pointer;
|
||||
|
||||
// cyclic array file must be open
|
||||
if (hFile == nullptr)
|
||||
{
|
||||
if (hFile == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -334,8 +313,7 @@ bool CyclicArray::saveFile(const char *fileName)
|
|||
hSaveFile = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hSaveFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hSaveFile == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -344,27 +322,19 @@ bool CyclicArray::saveFile(const char *fileName)
|
|||
curBlock = curReadingBlock;
|
||||
dataInFile = new unsigned char[blockSize];
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
|
||||
// copy current block
|
||||
if (curBlock == curWritingBlock && curBlock == curReadingBlock)
|
||||
{
|
||||
if (curBlock == curWritingBlock && curBlock == curReadingBlock) {
|
||||
pointer = curReadingPointer;
|
||||
bytesToWrite = (unsigned int)(curWritingPointer - curReadingPointer);
|
||||
}
|
||||
else if (curBlock == curWritingBlock)
|
||||
{
|
||||
} else if (curBlock == curWritingBlock) {
|
||||
pointer = writingBlock;
|
||||
bytesToWrite = (unsigned int)(curWritingPointer - writingBlock);
|
||||
}
|
||||
else if (curBlock == curReadingBlock)
|
||||
{
|
||||
} else if (curBlock == curReadingBlock) {
|
||||
pointer = curReadingPointer;
|
||||
bytesToWrite = blockSize - (unsigned int)(curReadingPointer - readingBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
readDataFromFile(hFile, ((long long)curBlock) * ((long long)blockSize), blockSize, dataInFile);
|
||||
pointer = dataInFile;
|
||||
bytesToWrite = blockSize;
|
||||
|
|
|
@ -47,8 +47,7 @@ int main(void)
|
|||
pos->beginNewGame(ai, ai, (rand() % 2) ? fieldStruct::playerOne : fieldStruct::playerTwo);
|
||||
#endif // SELF_PLAY
|
||||
|
||||
if (calculateDatabase)
|
||||
{
|
||||
if (calculateDatabase) {
|
||||
|
||||
// calculate
|
||||
ai->calculateDatabase(MAX_DEPTH_OF_TREE, false);
|
||||
|
@ -61,9 +60,7 @@ int main(void)
|
|||
<< "End test at layer: ";
|
||||
endTestAtLayer;
|
||||
ai->testLayers(startTestFromLayer, endTestAtLayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
#ifdef SELF_PLAY
|
||||
int moveCount = 0;
|
||||
|
@ -79,8 +76,7 @@ int main(void)
|
|||
#endif // SELF_PLAY
|
||||
|
||||
// play
|
||||
do
|
||||
{
|
||||
do {
|
||||
// print board
|
||||
cout << "\n\n\n\n\n\n\n\n\n\n\n";
|
||||
pos->getComputersChoice(&pushFrom, &pushTo);
|
||||
|
@ -89,8 +85,7 @@ int main(void)
|
|||
|
||||
#ifdef SELF_PLAY
|
||||
moveCount++;
|
||||
if (moveCount > 99)
|
||||
{
|
||||
if (moveCount > 99) {
|
||||
goto out;
|
||||
}
|
||||
#endif // SELF_PLAY
|
||||
|
@ -98,10 +93,8 @@ int main(void)
|
|||
pos->printBoard();
|
||||
|
||||
// Human
|
||||
if ((pos->getCurrentPlayer() == fieldStruct::playerOne && playerOneHuman) || (pos->getCurrentPlayer() == fieldStruct::playerTwo && playerTwoHuman))
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((pos->getCurrentPlayer() == fieldStruct::playerOne && playerOneHuman) || (pos->getCurrentPlayer() == fieldStruct::playerTwo && playerTwoHuman)) {
|
||||
do {
|
||||
// Show text
|
||||
if (pos->mustStoneBeRemoved())
|
||||
cout << "\n Which stone do you want to remove? [a-x]: \n\n\n";
|
||||
|
@ -117,15 +110,12 @@ int main(void)
|
|||
else
|
||||
pushFrom = fieldStruct::size;
|
||||
|
||||
if (pos->inSettingPhase())
|
||||
{
|
||||
if (pos->inSettingPhase()) {
|
||||
if ((ch[0] >= 'a') && (ch[0] <= 'x'))
|
||||
pushTo = ch[0] - 'a';
|
||||
else
|
||||
pushTo = fieldStruct::size;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if ((ch[1] >= 'a') && (ch[1] <= 'x'))
|
||||
pushTo = ch[1] - 'a';
|
||||
else
|
||||
|
@ -133,12 +123,10 @@ int main(void)
|
|||
}
|
||||
|
||||
// undo
|
||||
if (ch[0] == 'u' && ch[1] == 'n' && ch[2] == 'd' && ch[3] == 'o')
|
||||
{
|
||||
if (ch[0] == 'u' && ch[1] == 'n' && ch[2] == 'd' && ch[3] == 'o') {
|
||||
|
||||
// undo moves until a human player shall move
|
||||
do
|
||||
{
|
||||
do {
|
||||
pos->undo_move();
|
||||
} while (!((pos->getCurrentPlayer() == fieldStruct::playerOne && playerOneHuman) || (pos->getCurrentPlayer() == fieldStruct::playerTwo && playerTwoHuman)));
|
||||
|
||||
|
@ -149,9 +137,7 @@ int main(void)
|
|||
} while (pos->do_move(pushFrom, pushTo) == false);
|
||||
|
||||
// Computer
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cout << "\n";
|
||||
pos->do_move(pushFrom, pushTo);
|
||||
}
|
||||
|
|
|
@ -60,8 +60,7 @@ void fieldStruct::printBoard()
|
|||
//-----------------------------------------------------------------------------
|
||||
char fieldStruct::GetCharFromStone(int stone)
|
||||
{
|
||||
switch (stone)
|
||||
{
|
||||
switch (stone) {
|
||||
case fieldStruct::playerOne:
|
||||
return 'o';
|
||||
case fieldStruct::playerTwo:
|
||||
|
@ -93,15 +92,13 @@ void fieldStruct::copyBoard(fieldStruct *destination)
|
|||
destination->settingPhase = this->settingPhase;
|
||||
destination->stoneMustBeRemoved = this->stoneMustBeRemoved;
|
||||
|
||||
for (i = 0; i < this->size; i++)
|
||||
{
|
||||
for (i = 0; i < this->size; i++) {
|
||||
|
||||
destination->board[i] = this->board[i];
|
||||
destination->warnings[i] = this->warnings[i];
|
||||
destination->stonePartOfMill[i] = this->stonePartOfMill[i];
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (j = 0; j < 4; j++) {
|
||||
|
||||
destination->connectedSquare[i][j] = this->connectedSquare[i][j];
|
||||
destination->stoneMoveAble[i][j] = this->stoneMoveAble[i][j];
|
||||
|
@ -157,8 +154,7 @@ void fieldStruct::createBoard()
|
|||
oppPlayer->numStonesMissing = 0;
|
||||
|
||||
// zero
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
for (i = 0; i < size; i++) {
|
||||
board[i] = squareIsFree;
|
||||
warnings[i] = noWarning;
|
||||
stonePartOfMill[i] = 0;
|
||||
|
|
|
@ -39,8 +39,7 @@ void MiniMaxAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
|
|||
unsigned int searchDepth;
|
||||
|
||||
// automatic depth
|
||||
if (depthOfFullTree == 0)
|
||||
{
|
||||
if (depthOfFullTree == 0) {
|
||||
if (theField->settingPhase)
|
||||
searchDepth = 5;
|
||||
else if (theField->curPlayer->numStones <= 4)
|
||||
|
@ -49,9 +48,7 @@ void MiniMaxAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
|
|||
searchDepth = 7;
|
||||
else
|
||||
searchDepth = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
searchDepth = depthOfFullTree;
|
||||
}
|
||||
|
||||
|
@ -67,18 +64,13 @@ void MiniMaxAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
|
|||
Possibility *rootPossibilities = (Possibility *)getBestChoice(searchDepth, &bestChoice, MAX_NUM_POS_MOVES);
|
||||
|
||||
// decode the best choice
|
||||
if (field->stoneMustBeRemoved)
|
||||
{
|
||||
if (field->stoneMustBeRemoved) {
|
||||
*pushFrom = bestChoice;
|
||||
*pushTo = 0;
|
||||
}
|
||||
else if (field->settingPhase)
|
||||
{
|
||||
} else if (field->settingPhase) {
|
||||
*pushFrom = 0;
|
||||
*pushTo = bestChoice;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*pushFrom = rootPossibilities->from[bestChoice];
|
||||
*pushTo = rootPossibilities->to[bestChoice];
|
||||
}
|
||||
|
@ -123,12 +115,10 @@ unsigned int *MiniMaxAI::getPossSettingPhase(unsigned int *numPossibilities, voi
|
|||
unsigned int *idPossibility = &idPossibilities[curSearchDepth * MAX_NUM_POS_MOVES];
|
||||
|
||||
// possibilities with cut off
|
||||
for ((*numPossibilities) = 0, i = 0; i < field->size; i++)
|
||||
{
|
||||
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
|
||||
|
||||
// move possible ?
|
||||
if (field->board[i] == field->squareIsFree)
|
||||
{
|
||||
if (field->board[i] == field->squareIsFree) {
|
||||
|
||||
idPossibility[*numPossibilities] = i;
|
||||
(*numPossibilities)++;
|
||||
|
@ -153,20 +143,16 @@ unsigned int *MiniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
|
|||
Possibility *possibility = &possibilities[curSearchDepth];
|
||||
|
||||
// if he is not allowed to spring
|
||||
if (field->curPlayer->numStones > 3)
|
||||
{
|
||||
if (field->curPlayer->numStones > 3) {
|
||||
|
||||
for ((*numPossibilities) = 0, from = 0; from < field->size; from++)
|
||||
{
|
||||
for (dir = 0; dir < 4; dir++)
|
||||
{
|
||||
for ((*numPossibilities) = 0, from = 0; from < field->size; from++) {
|
||||
for (dir = 0; dir < 4; dir++) {
|
||||
|
||||
// destination
|
||||
to = field->connectedSquare[from][dir];
|
||||
|
||||
// move possible ?
|
||||
if (to < field->size && field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree)
|
||||
{
|
||||
if (to < field->size && field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree) {
|
||||
|
||||
// stone is moveable
|
||||
idPossibility[*numPossibilities] = *numPossibilities;
|
||||
|
@ -178,18 +164,13 @@ unsigned int *MiniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
for ((*numPossibilities) = 0, from = 0; from < field->size; from++)
|
||||
{
|
||||
for (to = 0; to < field->size; to++)
|
||||
{
|
||||
for ((*numPossibilities) = 0, from = 0; from < field->size; from++) {
|
||||
for (to = 0; to < field->size; to++) {
|
||||
|
||||
// move possible ?
|
||||
if (field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES)
|
||||
{
|
||||
if (field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES) {
|
||||
|
||||
// stone is moveable
|
||||
idPossibility[*numPossibilities] = *numPossibilities;
|
||||
|
@ -218,12 +199,10 @@ unsigned int *MiniMaxAI::getPossStoneRemove(unsigned int *numPossibilities, void
|
|||
unsigned int *idPossibility = &idPossibilities[curSearchDepth * MAX_NUM_POS_MOVES];
|
||||
|
||||
// possibilities with cut off
|
||||
for ((*numPossibilities) = 0, i = 0; i < field->size; i++)
|
||||
{
|
||||
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
|
||||
|
||||
// move possible ?
|
||||
if (field->board[i] == field->oppPlayer->id && !field->stonePartOfMill[i])
|
||||
{
|
||||
if (field->board[i] == field->oppPlayer->id && !field->stonePartOfMill[i]) {
|
||||
|
||||
idPossibility[*numPossibilities] = i;
|
||||
(*numPossibilities)++;
|
||||
|
@ -246,14 +225,11 @@ unsigned int *MiniMaxAI::getPossibilities(unsigned int threadNo, unsigned int *n
|
|||
*opponentsMove = (field->curPlayer->id == ownId) ? false : true;
|
||||
|
||||
// When game has ended of course nothing happens any more
|
||||
if (gameHasFinished)
|
||||
{
|
||||
if (gameHasFinished) {
|
||||
*numPossibilities = 0;
|
||||
return 0;
|
||||
// look what is to do
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (field->stoneMustBeRemoved)
|
||||
return getPossStoneRemove(numPossibilities, pPossibilities);
|
||||
else if (field->settingPhase)
|
||||
|
@ -310,8 +286,7 @@ void MiniMaxAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
|
|||
field->board[oldState->to] = oldState->fieldTo;
|
||||
|
||||
// very expensive
|
||||
for (int i = 0; i < field->size; i++)
|
||||
{
|
||||
for (int i = 0; i < field->size; i++) {
|
||||
field->stonePartOfMill[i] = oldState->stonePartOfMill[i];
|
||||
field->warnings[i] = oldState->warnings[i];
|
||||
}
|
||||
|
@ -324,8 +299,7 @@ void MiniMaxAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
|
|||
inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo, unsigned int stoneThree)
|
||||
{
|
||||
// if all 3 fields are occupied by current player than he closed a mill
|
||||
if (field->board[stoneOne] == field->curPlayer->id && field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id)
|
||||
{
|
||||
if (field->board[stoneOne] == field->curPlayer->id && field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id) {
|
||||
|
||||
field->stonePartOfMill[stoneOne]++;
|
||||
field->stonePartOfMill[stoneTwo]++;
|
||||
|
@ -334,8 +308,7 @@ inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
|
|||
}
|
||||
|
||||
// is a mill destroyed ?
|
||||
if (field->board[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree])
|
||||
{
|
||||
if (field->board[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree]) {
|
||||
|
||||
field->stonePartOfMill[stoneOne]--;
|
||||
field->stonePartOfMill[stoneTwo]--;
|
||||
|
@ -343,8 +316,7 @@ inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
|
|||
}
|
||||
|
||||
// stone was set
|
||||
if (field->board[stoneOne] == field->curPlayer->id)
|
||||
{
|
||||
if (field->board[stoneOne] == field->curPlayer->id) {
|
||||
|
||||
// a warnig was destroyed
|
||||
field->warnings[stoneOne] = field->noWarning;
|
||||
|
@ -356,9 +328,7 @@ inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
|
|||
field->warnings[stoneTwo] |= field->curPlayer->warning;
|
||||
|
||||
// stone was removed
|
||||
}
|
||||
else if (field->board[stoneOne] == field->squareIsFree)
|
||||
{
|
||||
} else if (field->board[stoneOne] == field->squareIsFree) {
|
||||
|
||||
// a warning is created
|
||||
if (field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id)
|
||||
|
@ -367,8 +337,7 @@ inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
|
|||
field->warnings[stoneOne] |= field->oppPlayer->warning;
|
||||
|
||||
// a warning is destroyed
|
||||
if (field->warnings[stoneTwo] && field->board[stoneThree] != field->squareIsFree)
|
||||
{
|
||||
if (field->warnings[stoneTwo] && field->board[stoneThree] != field->squareIsFree) {
|
||||
|
||||
// reset warning if necessary
|
||||
if (field->board[field->neighbour[stoneTwo][0][0]] == field->curPlayer->id && field->board[field->neighbour[stoneTwo][0][1]] == field->curPlayer->id)
|
||||
|
@ -381,9 +350,7 @@ inline void MiniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
|
|||
field->warnings[stoneTwo] = field->oppPlayer->warning;
|
||||
else
|
||||
field->warnings[stoneTwo] = field->noWarning;
|
||||
}
|
||||
else if (field->warnings[stoneThree] && field->board[stoneTwo] != field->squareIsFree)
|
||||
{
|
||||
} else if (field->warnings[stoneThree] && field->board[stoneTwo] != field->squareIsFree) {
|
||||
|
||||
// reset warning if necessary
|
||||
if (field->board[field->neighbour[stoneThree][0][0]] == field->curPlayer->id && field->board[field->neighbour[stoneThree][0][1]] == field->curPlayer->id)
|
||||
|
@ -422,8 +389,7 @@ inline void MiniMaxAI::updateWarning(unsigned int firstStone, unsigned int secon
|
|||
bool atLeastOneStoneRemoveAble = false;
|
||||
if (field->stoneMustBeRemoved)
|
||||
for (i = 0; i < field->size; i++)
|
||||
if (field->stonePartOfMill[i] == 0 && field->board[i] == field->oppPlayer->id)
|
||||
{
|
||||
if (field->stonePartOfMill[i] == 0 && field->board[i] == field->oppPlayer->id) {
|
||||
atLeastOneStoneRemoveAble = true;
|
||||
break;
|
||||
}
|
||||
|
@ -441,22 +407,19 @@ inline void MiniMaxAI::updatePossibleMoves(unsigned int stone, Player *stoneOwne
|
|||
unsigned int neighbor, direction;
|
||||
|
||||
// look into every direction
|
||||
for (direction = 0; direction < 4; direction++)
|
||||
{
|
||||
for (direction = 0; direction < 4; direction++) {
|
||||
|
||||
neighbor = field->connectedSquare[stone][direction];
|
||||
|
||||
// neighbor must exist
|
||||
if (neighbor < field->size)
|
||||
{
|
||||
if (neighbor < field->size) {
|
||||
|
||||
// relevant when moving from one square to another connected square
|
||||
if (ignoreStone == neighbor)
|
||||
continue;
|
||||
|
||||
// if there is no neighbour stone than it only affects the actual stone
|
||||
if (field->board[neighbor] == field->squareIsFree)
|
||||
{
|
||||
if (field->board[neighbor] == field->squareIsFree) {
|
||||
|
||||
if (stoneRemoved)
|
||||
stoneOwner->numPossibleMoves--;
|
||||
|
@ -464,17 +427,13 @@ inline void MiniMaxAI::updatePossibleMoves(unsigned int stone, Player *stoneOwne
|
|||
stoneOwner->numPossibleMoves++;
|
||||
|
||||
// if there is a neighbour stone than it effects only this one
|
||||
}
|
||||
else if (field->board[neighbor] == field->curPlayer->id)
|
||||
{
|
||||
} else if (field->board[neighbor] == field->curPlayer->id) {
|
||||
|
||||
if (stoneRemoved)
|
||||
field->curPlayer->numPossibleMoves++;
|
||||
else
|
||||
field->curPlayer->numPossibleMoves--;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
if (stoneRemoved)
|
||||
field->oppPlayer->numPossibleMoves++;
|
||||
|
@ -602,23 +561,17 @@ void MiniMaxAI::move(unsigned int threadNo, unsigned int idPossibility, bool opp
|
|||
curSearchDepth++;
|
||||
|
||||
// very expensive
|
||||
for (i = 0; i < field->size; i++)
|
||||
{
|
||||
for (i = 0; i < field->size; i++) {
|
||||
oldState->stonePartOfMill[i] = field->stonePartOfMill[i];
|
||||
oldState->warnings[i] = field->warnings[i];
|
||||
}
|
||||
|
||||
// move
|
||||
if (field->stoneMustBeRemoved)
|
||||
{
|
||||
if (field->stoneMustBeRemoved) {
|
||||
removeStone(idPossibility, oldState);
|
||||
}
|
||||
else if (field->settingPhase)
|
||||
{
|
||||
} else if (field->settingPhase) {
|
||||
setStone(idPossibility, oldState);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
normalMove(tmpPossibility->from[idPossibility], tmpPossibility->to[idPossibility], oldState);
|
||||
}
|
||||
|
||||
|
@ -639,8 +592,7 @@ void MiniMaxAI::move(unsigned int threadNo, unsigned int idPossibility, bool opp
|
|||
currentValue = VALUE_GAME_LOST + curSearchDepth;
|
||||
|
||||
// set next player
|
||||
if (!field->stoneMustBeRemoved)
|
||||
{
|
||||
if (!field->stoneMustBeRemoved) {
|
||||
tmpPlayer = field->curPlayer;
|
||||
field->curPlayer = field->oppPlayer;
|
||||
field->oppPlayer = tmpPlayer;
|
||||
|
|
|
@ -44,15 +44,12 @@ MiniMax::MiniMax()
|
|||
numWriteSkvOperations = 0;
|
||||
numReadPlyOperations = 0;
|
||||
numWritePlyOperations = 0;
|
||||
if (MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_ONLY_IO) {
|
||||
readSkvInterval.QuadPart = 0;
|
||||
writeSkvInterval.QuadPart = 0;
|
||||
readPlyInterval.QuadPart = 0;
|
||||
writePlyInterval.QuadPart = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
QueryPerformanceCounter(&readSkvInterval);
|
||||
QueryPerformanceCounter(&writeSkvInterval);
|
||||
QueryPerformanceCounter(&readPlyInterval);
|
||||
|
@ -147,8 +144,7 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
|
|||
prepareDatabaseCalculation();
|
||||
|
||||
// when database not completed then do it
|
||||
if (hFileShortKnotValues != nullptr && skvfHeader.completed == false)
|
||||
{
|
||||
if (hFileShortKnotValues != nullptr && skvfHeader.completed == false) {
|
||||
|
||||
// reserve memory
|
||||
lastCalculatedLayer.clear();
|
||||
|
@ -159,8 +155,7 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
|
|||
arrayInfos.vectorArrays.resize(ArrayInfo::numArrayTypes * skvfHeader.numLayers, arrayInfos.listArrays.end());
|
||||
|
||||
// calc layer after layer, beginning with the last one
|
||||
for (curCalculatedLayer = 0; curCalculatedLayer < skvfHeader.numLayers; curCalculatedLayer++)
|
||||
{
|
||||
for (curCalculatedLayer = 0; curCalculatedLayer < skvfHeader.numLayers; curCalculatedLayer++) {
|
||||
|
||||
// layer already calculated?
|
||||
if (layerStats[curCalculatedLayer].layerIsCompletedAndInFile)
|
||||
|
@ -191,8 +186,7 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
|
|||
// don't save layer and header when only preparing layers or when
|
||||
if (onlyPrepareLayer)
|
||||
return;
|
||||
if (!abortCalculation)
|
||||
{
|
||||
if (!abortCalculation) {
|
||||
|
||||
// calc layer statistics
|
||||
calcLayerStatistics("statistics.txt");
|
||||
|
@ -206,9 +200,7 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
|
|||
|
||||
// free mem
|
||||
curCalculationActionId = MM_ACTION_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PRINT(1, this, "\nThe database is already fully calculated.\n");
|
||||
}
|
||||
|
||||
|
@ -230,8 +222,7 @@ bool MiniMax::calcLayer(unsigned int layerNumber)
|
|||
vector<unsigned int> layersToCalculate;
|
||||
|
||||
// moves can be done reverse, leading to too depth searching trees
|
||||
if (shallRetroAnalysisBeUsed(layerNumber))
|
||||
{
|
||||
if (shallRetroAnalysisBeUsed(layerNumber)) {
|
||||
|
||||
// calc values for all states of layer
|
||||
layersToCalculate.push_back(layerNumber);
|
||||
|
@ -241,15 +232,12 @@ bool MiniMax::calcLayer(unsigned int layerNumber)
|
|||
return false;
|
||||
|
||||
// save partner layer
|
||||
if (layerStats[layerNumber].partnerLayer != layerNumber)
|
||||
{
|
||||
if (layerStats[layerNumber].partnerLayer != layerNumber) {
|
||||
saveLayerToFile(layerStats[layerNumber].partnerLayer);
|
||||
}
|
||||
|
||||
// use minimax-algorithm
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!calcKnotValuesByAlphaBeta(layerNumber))
|
||||
return false;
|
||||
}
|
||||
|
@ -258,17 +246,14 @@ bool MiniMax::calcLayer(unsigned int layerNumber)
|
|||
saveLayerToFile(layerNumber);
|
||||
|
||||
// test layer
|
||||
if (!testLayer(layerNumber))
|
||||
{
|
||||
if (!testLayer(layerNumber)) {
|
||||
PRINT(0, this, "ERROR: Layer calculation cancelled or failed!" << endl);
|
||||
return false;
|
||||
}
|
||||
|
||||
// test partner layer if retro-analysis has been used
|
||||
if (shallRetroAnalysisBeUsed(layerNumber) && layerStats[layerNumber].partnerLayer != layerNumber)
|
||||
{
|
||||
if (!testLayer(layerStats[layerNumber].partnerLayer))
|
||||
{
|
||||
if (shallRetroAnalysisBeUsed(layerNumber) && layerStats[layerNumber].partnerLayer != layerNumber) {
|
||||
if (!testLayer(layerStats[layerNumber].partnerLayer)) {
|
||||
PRINT(0, this, "ERROR: Layer calculation cancelled or failed!" << endl);
|
||||
return false;
|
||||
}
|
||||
|
@ -276,8 +261,7 @@ bool MiniMax::calcLayer(unsigned int layerNumber)
|
|||
|
||||
// update output information
|
||||
EnterCriticalSection(&csOsPrint);
|
||||
if (shallRetroAnalysisBeUsed(layerNumber) && layerNumber != layerStats[layerNumber].partnerLayer)
|
||||
{
|
||||
if (shallRetroAnalysisBeUsed(layerNumber) && layerNumber != layerStats[layerNumber].partnerLayer) {
|
||||
lastCalculatedLayer.push_back(layerStats[layerNumber].partnerLayer);
|
||||
}
|
||||
lastCalculatedLayer.push_back(layerNumber);
|
||||
|
|
|
@ -303,7 +303,9 @@ public:
|
|||
while (true)
|
||||
;
|
||||
};
|
||||
virtual void storeValueOfMove(unsigned int threadNo, unsigned int idPossibility, void *pPossibilities, TwoBit value, unsigned int *freqValuesSubMoves, PlyInfoVarType plyInfo){};
|
||||
virtual void storeValueOfMove(unsigned int threadNo, unsigned int idPossibility, void *pPossibilities, TwoBit value, unsigned int *freqValuesSubMoves, PlyInfoVarType plyInfo)
|
||||
{
|
||||
};
|
||||
virtual void move(unsigned int threadNo, unsigned int idPossibility, bool opponentsMove, void **pBackup, void *pPossibilities)
|
||||
{
|
||||
while (true)
|
||||
|
@ -451,15 +453,13 @@ private:
|
|||
AlphaBetaGlobalVars(MiniMax *pMiniMax, unsigned int layerNumber)
|
||||
{
|
||||
this->thread.resize(pMiniMax->threadManager.getNumThreads());
|
||||
for (unsigned int threadNo = 0; threadNo < pMiniMax->threadManager.getNumThreads(); threadNo++)
|
||||
{
|
||||
for (unsigned int threadNo = 0; threadNo < pMiniMax->threadManager.getNumThreads(); threadNo++) {
|
||||
this->thread[threadNo].numStatesToProcess = 0;
|
||||
this->thread[threadNo].threadNo = threadNo;
|
||||
}
|
||||
this->layerNumber = layerNumber;
|
||||
this->pMiniMax = pMiniMax;
|
||||
if (pMiniMax->layerStats)
|
||||
{
|
||||
if (pMiniMax->layerStats) {
|
||||
this->numKnotsToCalc = pMiniMax->layerStats[layerNumber].knotsInLayer;
|
||||
this->totalNumKnots = pMiniMax->layerStats[layerNumber].knotsInLayer;
|
||||
}
|
||||
|
@ -478,23 +478,23 @@ private:
|
|||
LONGLONG statesProcessed;
|
||||
unsigned int statsValueCounter[SKV_NUM_VALUES];
|
||||
|
||||
AlphaBetaDefaultThreadVars(){};
|
||||
AlphaBetaDefaultThreadVars()
|
||||
{
|
||||
};
|
||||
AlphaBetaDefaultThreadVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber)
|
||||
{
|
||||
this->statesProcessed = 0;
|
||||
this->layerNumber = layerNumber;
|
||||
this->pMiniMax = pMiniMax;
|
||||
this->alphaBetaVars = alphaBetaVars;
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++)
|
||||
{
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++) {
|
||||
this->statsValueCounter[curStateValue] = 0;
|
||||
}
|
||||
};
|
||||
void reduceDefault()
|
||||
{
|
||||
pMiniMax->numStatesProcessed += this->statesProcessed;
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++)
|
||||
{
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++) {
|
||||
alphaBetaVars->statsValueCounter[curStateValue] += this->statsValueCounter[curStateValue];
|
||||
}
|
||||
};
|
||||
|
@ -505,7 +505,9 @@ private:
|
|||
BufferedFile *bufferedFile;
|
||||
bool initAlreadyDone;
|
||||
|
||||
InitAlphaBetaVars(){};
|
||||
InitAlphaBetaVars()
|
||||
{
|
||||
};
|
||||
InitAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber)
|
||||
{
|
||||
this->bufferedFile = initArray;
|
||||
|
@ -527,7 +529,9 @@ private:
|
|||
unsigned int *freqValuesSubMovesBranchWon = nullptr; // ...
|
||||
unsigned int freqValuesSubMoves[4]; // ...
|
||||
|
||||
RunAlphaBetaVars(){};
|
||||
RunAlphaBetaVars()
|
||||
{
|
||||
};
|
||||
RunAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber)
|
||||
{
|
||||
initializeElement(*this);
|
||||
|
@ -585,23 +589,23 @@ private:
|
|||
LONGLONG statesProcessed;
|
||||
unsigned int statsValueCounter[SKV_NUM_VALUES];
|
||||
|
||||
RetroAnalysisDefaultThreadVars(){};
|
||||
RetroAnalysisDefaultThreadVars()
|
||||
{
|
||||
};
|
||||
RetroAnalysisDefaultThreadVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber)
|
||||
{
|
||||
this->statesProcessed = 0;
|
||||
this->layerNumber = layerNumber;
|
||||
this->pMiniMax = pMiniMax;
|
||||
this->retroVars = retroVars;
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++)
|
||||
{
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++) {
|
||||
this->statsValueCounter[curStateValue] = 0;
|
||||
}
|
||||
};
|
||||
void reduceDefault()
|
||||
{
|
||||
pMiniMax->numStatesProcessed += this->statesProcessed;
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++)
|
||||
{
|
||||
for (unsigned int curStateValue = 0; curStateValue < SKV_NUM_VALUES; curStateValue++) {
|
||||
retroVars->statsValueCounter[curStateValue] += this->statsValueCounter[curStateValue];
|
||||
}
|
||||
};
|
||||
|
@ -612,7 +616,9 @@ private:
|
|||
BufferedFile *bufferedFile;
|
||||
bool initAlreadyDone;
|
||||
|
||||
InitRetroAnalysisVars(){};
|
||||
InitRetroAnalysisVars()
|
||||
{
|
||||
};
|
||||
InitRetroAnalysisVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber)
|
||||
{
|
||||
this->bufferedFile = initArray;
|
||||
|
@ -632,8 +638,12 @@ private:
|
|||
{
|
||||
RetroAnalysisPredVars predVars[MAX_NUM_PREDECESSORS];
|
||||
|
||||
AddNumSuccedorsVars(){};
|
||||
AddNumSuccedorsVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber){};
|
||||
AddNumSuccedorsVars()
|
||||
{
|
||||
};
|
||||
AddNumSuccedorsVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber)
|
||||
{
|
||||
};
|
||||
void initializeElement(AddNumSuccedorsVars &master)
|
||||
{
|
||||
*this = master;
|
||||
|
|
|
@ -90,7 +90,9 @@ protected:
|
|||
{
|
||||
return 0;
|
||||
};
|
||||
void getSuccLayers(unsigned int layerNum, unsigned int *amountOfSuccLayers, unsigned int *succLayers){};
|
||||
void getSuccLayers(unsigned int layerNum, unsigned int *amountOfSuccLayers, unsigned int *succLayers)
|
||||
{
|
||||
};
|
||||
unsigned int getPartnerLayer(unsigned int layerNum)
|
||||
{
|
||||
return 0;
|
||||
|
@ -99,7 +101,9 @@ protected:
|
|||
{
|
||||
return string("");
|
||||
};
|
||||
void setOpponentLevel(unsigned int threadNo, bool isOpponentLevel){};
|
||||
void setOpponentLevel(unsigned int threadNo, bool isOpponentLevel)
|
||||
{
|
||||
};
|
||||
bool setSituation(unsigned int threadNo, unsigned int layerNum, unsigned int stateNumber)
|
||||
{
|
||||
return false;
|
||||
|
@ -116,11 +120,21 @@ protected:
|
|||
{
|
||||
return 0;
|
||||
};
|
||||
void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers){};
|
||||
void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars){};
|
||||
void printBoard(unsigned int threadNo, unsigned char value){};
|
||||
void prepareDatabaseCalculation(){};
|
||||
void wrapUpDatabaseCalculation(bool calculationAborted){};
|
||||
void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers)
|
||||
{
|
||||
};
|
||||
void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars)
|
||||
{
|
||||
};
|
||||
void printBoard(unsigned int threadNo, unsigned char value)
|
||||
{
|
||||
};
|
||||
void prepareDatabaseCalculation()
|
||||
{
|
||||
};
|
||||
void wrapUpDatabaseCalculation(bool calculationAborted)
|
||||
{
|
||||
};
|
||||
|
||||
public:
|
||||
// Constructor / destructor
|
||||
|
|
|
@ -19,9 +19,15 @@
|
|||
class MiniMaxGuiField
|
||||
{
|
||||
public:
|
||||
virtual void setAlignment(wildWeasel::alignment &newAlignment){};
|
||||
virtual void setVisibility(bool visible){};
|
||||
virtual void setState(unsigned int curShowedLayer, MiniMax::StateNumberVarType curShowedState){};
|
||||
virtual void setAlignment(wildWeasel::alignment &newAlignment)
|
||||
{
|
||||
};
|
||||
virtual void setVisibility(bool visible)
|
||||
{
|
||||
};
|
||||
virtual void setState(unsigned int curShowedLayer, MiniMax::StateNumberVarType curShowedState)
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
|
|
|
@ -23,15 +23,13 @@ bool MiniMax::calcKnotValuesByAlphaBeta(unsigned int layerNumber)
|
|||
|
||||
// initialization
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2 << endl);
|
||||
if (!initAlphaBeta(alphaBetaVars))
|
||||
{
|
||||
if (!initAlphaBeta(alphaBetaVars)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// run alpha-beta algorithmn
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2 << endl);
|
||||
if (!runAlphaBeta(alphaBetaVars))
|
||||
{
|
||||
if (!runAlphaBeta(alphaBetaVars)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -69,8 +67,7 @@ void MiniMax::alphaBetaSaveInDatabase(unsigned int threadNo, unsigned int layerN
|
|||
savePlyInfoInDatabase(layerNumber, stateNumber, plyValue);
|
||||
|
||||
// save value for all symmetric states
|
||||
for (i = 0; i < numSymmetricStates; i++)
|
||||
{
|
||||
for (i = 0; i < numSymmetricStates; i++) {
|
||||
|
||||
// get state number
|
||||
sysStateNumber = symStateNumbers[i];
|
||||
|
@ -109,8 +106,7 @@ bool MiniMax::initAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
|
|||
// does initialization file exist ?
|
||||
CreateDirectoryA(ssInvArrayDirectory.str().c_str(), nullptr);
|
||||
invalidArray = new BufferedFile(threadManager.getNumThreads(), FILE_BUFFER_SIZE, ssInvArrayFilePath.str().c_str());
|
||||
if (invalidArray->getFileSize() == (LONGLONG)layerStats[alphaBetaVars.layerNumber].knotsInLayer)
|
||||
{
|
||||
if (invalidArray->getFileSize() == (LONGLONG)layerStats[alphaBetaVars.layerNumber].knotsInLayer) {
|
||||
PRINT(2, this, " Loading invalid states from file: " << ssInvArrayFilePath.str());
|
||||
initAlreadyDone = true;
|
||||
}
|
||||
|
@ -124,8 +120,7 @@ bool MiniMax::initAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
|
|||
ThreadManager::ThreadVarsArray<InitAlphaBetaVars> tva(threadManager.getNumThreads(), InitAlphaBetaVars(this, &alphaBetaVars, alphaBetaVars.layerNumber, invalidArray, initAlreadyDone));
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeParallelLoop(initAlphaBetaThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[alphaBetaVars.layerNumber].knotsInLayer - 1, 1))
|
||||
{
|
||||
switch (threadManager.executeParallelLoop(initAlphaBetaThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[alphaBetaVars.layerNumber].knotsInLayer - 1, 1)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -141,8 +136,7 @@ bool MiniMax::initAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
|
|||
|
||||
// reduce and delete thread specific data
|
||||
tva.reduce();
|
||||
if (numStatesProcessed < layerStats[alphaBetaVars.layerNumber].knotsInLayer)
|
||||
{
|
||||
if (numStatesProcessed < layerStats[alphaBetaVars.layerNumber].knotsInLayer) {
|
||||
SAFE_DELETE(invalidArray);
|
||||
return falseOrStop();
|
||||
}
|
||||
|
@ -180,47 +174,34 @@ DWORD MiniMax::initAlphaBetaThreadProc(void *pParameter, int index)
|
|||
iabVars->statesProcessed++;
|
||||
|
||||
// print status
|
||||
if (iabVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (iabVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(2, m, "Already initialized " << m->numStatesProcessed << " of " << m->layerStats[curState.layerNumber].knotsInLayer << " states");
|
||||
}
|
||||
|
||||
// layer initialization already done ? if so, then read from file
|
||||
if (iabVars->initAlreadyDone)
|
||||
{
|
||||
if (!iabVars->bufferedFile->readBytes(iabVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue))
|
||||
{
|
||||
if (iabVars->initAlreadyDone) {
|
||||
if (!iabVars->bufferedFile->readBytes(iabVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue)) {
|
||||
PRINT(0, m, "ERROR: initArray->takeBytes() failed");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
// initialization not done
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// set current selected situation
|
||||
if (!m->setSituation(iabVars->curThreadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (!m->setSituation(iabVars->curThreadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
curStateValue = SKV_VALUE_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// get value of current situation
|
||||
m->getValueOfSituation(iabVars->curThreadNo, floatValue, curStateValue);
|
||||
}
|
||||
}
|
||||
|
||||
// calc ply info
|
||||
if (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST)
|
||||
{
|
||||
if (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST) {
|
||||
plyInfo = 0;
|
||||
}
|
||||
else if (curStateValue == SKV_VALUE_INVALID)
|
||||
{
|
||||
} else if (curStateValue == SKV_VALUE_INVALID) {
|
||||
plyInfo = PLYINFO_VALUE_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
plyInfo = PLYINFO_VALUE_UNCALCULATED;
|
||||
}
|
||||
|
||||
|
@ -229,10 +210,8 @@ DWORD MiniMax::initAlphaBetaThreadProc(void *pParameter, int index)
|
|||
m->savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, plyInfo);
|
||||
|
||||
// write data to file
|
||||
if (!iabVars->initAlreadyDone)
|
||||
{
|
||||
if (!iabVars->bufferedFile->writeBytes(iabVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue))
|
||||
{
|
||||
if (!iabVars->initAlreadyDone) {
|
||||
if (!iabVars->bufferedFile->writeBytes(iabVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue)) {
|
||||
PRINT(0, m, "ERROR: bufferedFile->writeBytes failed!");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
|
@ -261,8 +240,7 @@ bool MiniMax::runAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
|
|||
threadManager.setNumThreads(1);
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeParallelLoop(runAlphaBetaThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[alphaBetaVars.layerNumber].knotsInLayer - 1, 1))
|
||||
{
|
||||
switch (threadManager.executeParallelLoop(runAlphaBetaThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[alphaBetaVars.layerNumber].knotsInLayer - 1, 1)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -307,8 +285,7 @@ DWORD MiniMax::runAlphaBetaThreadProc(void *pParameter, int index)
|
|||
rabVars->statesProcessed++;
|
||||
|
||||
// print status
|
||||
if (rabVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (rabVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(2, m, " Processed " << m->numStatesProcessed << " of " << m->layerStats[curState.layerNumber].knotsInLayer << " states");
|
||||
}
|
||||
|
@ -319,14 +296,11 @@ DWORD MiniMax::runAlphaBetaThreadProc(void *pParameter, int index)
|
|||
return TM_RETURN_VALUE_OK;
|
||||
|
||||
// set current selected situation
|
||||
if (m->setSituation(rabVars->curThreadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (m->setSituation(rabVars->curThreadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
|
||||
// calc value of situation
|
||||
m->letTheTreeGrow(&root, rabVars, m->depthOfFullTree, SKV_VALUE_GAME_LOST, SKV_VALUE_GAME_WON);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// should not occur, because already tested by plyInfo == PLYINFO_VALUE_UNCALCULATED
|
||||
MessageBoxW(nullptr, L"This event should never occur. if (!m->setSituation())", L"ERROR", MB_OK);
|
||||
}
|
||||
|
@ -357,25 +331,19 @@ void MiniMax::letTheTreeGrow(Node *knot, RunAlphaBetaVars *rabVars, unsigned int
|
|||
knot->floatValue = (float)knot->shortValue;
|
||||
|
||||
// evaluate situation, musn't occur while calculating database
|
||||
if (tilLevel == 0)
|
||||
{
|
||||
if (calcDatabase)
|
||||
{
|
||||
if (tilLevel == 0) {
|
||||
if (calcDatabase) {
|
||||
// if tilLevel is equal zero it means that memory is gone out, since each recursive step needs memory
|
||||
PRINT(0, this, "ERROR: tilLevel == 0");
|
||||
knot->shortValue = SKV_VALUE_INVALID;
|
||||
knot->plyInfo = PLYINFO_VALUE_INVALID;
|
||||
knot->floatValue = (float)knot->shortValue;
|
||||
falseOrStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
getValueOfSituation(rabVars->curThreadNo, knot->floatValue, knot->shortValue);
|
||||
}
|
||||
// investigate branches
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// get layer and state number of current state and look if short knot value can be found in database or in an array
|
||||
if (alphaBetaTryDataBase(knot, rabVars, tilLevel, layerNumber, stateNumber))
|
||||
|
@ -385,8 +353,7 @@ void MiniMax::letTheTreeGrow(Node *knot, RunAlphaBetaVars *rabVars, unsigned int
|
|||
idPossibility = getPossibilities(rabVars->curThreadNo, &knot->numPossibilities, &knot->isOpponentLevel, &pPossibilities);
|
||||
|
||||
// unable to move
|
||||
if (knot->numPossibilities == 0)
|
||||
{
|
||||
if (knot->numPossibilities == 0) {
|
||||
|
||||
// if unable to move a final state is reached
|
||||
knot->plyInfo = 0;
|
||||
|
@ -395,17 +362,14 @@ void MiniMax::letTheTreeGrow(Node *knot, RunAlphaBetaVars *rabVars, unsigned int
|
|||
rabVars->freqValuesSubMoves[knot->shortValue]++;
|
||||
|
||||
// if unable to move an invalid state was reached if nobody has won
|
||||
if (calcDatabase && knot->shortValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (calcDatabase && knot->shortValue == SKV_VALUE_GAME_DRAWN) {
|
||||
knot->shortValue = SKV_VALUE_INVALID;
|
||||
knot->plyInfo = PLYINFO_VALUE_INVALID;
|
||||
knot->floatValue = (float)knot->shortValue;
|
||||
}
|
||||
|
||||
// movement is possible
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// move, letTreeGroe, undo
|
||||
alphaBetaTryPossibilites(knot, rabVars, tilLevel, idPossibility, pPossibilities, maxWonfreqValuesSubMoves, alpha, beta);
|
||||
|
@ -442,8 +406,7 @@ bool MiniMax::alphaBetaTryDataBase(Node *knot, RunAlphaBetaVars *rabVars, unsign
|
|||
PlyInfoVarType plyInfo = PLYINFO_VALUE_UNCALCULATED;
|
||||
|
||||
// use database ?
|
||||
if (hFilePlyInfo != nullptr && hFileShortKnotValues != nullptr && (calcDatabase || layerInDatabase))
|
||||
{
|
||||
if (hFilePlyInfo != nullptr && hFileShortKnotValues != nullptr && (calcDatabase || layerInDatabase)) {
|
||||
|
||||
// situation already existend in database ?
|
||||
readKnotValueFromDatabase(rabVars->curThreadNo, layerNumber, stateNumber, shortKnotValue, invalidLayerOrStateNumber, subLayerInDatabaseAndCompleted);
|
||||
|
@ -451,8 +414,7 @@ bool MiniMax::alphaBetaTryDataBase(Node *knot, RunAlphaBetaVars *rabVars, unsign
|
|||
|
||||
// it was possible to achieve an invalid state using move(),
|
||||
// so the original state was an invalid one
|
||||
if ((tilLevel < depthOfFullTree && invalidLayerOrStateNumber) || (tilLevel < depthOfFullTree && shortKnotValue == SKV_VALUE_INVALID && subLayerInDatabaseAndCompleted) || (tilLevel < depthOfFullTree && shortKnotValue == SKV_VALUE_INVALID && plyInfo != PLYINFO_VALUE_UNCALCULATED))
|
||||
{ // version 22: replaced: curCalculatedLayer == layerNumber && knot->plyInfo != PLYINFO_VALUE_UNCALCULATED)) {
|
||||
if ((tilLevel < depthOfFullTree && invalidLayerOrStateNumber) || (tilLevel < depthOfFullTree && shortKnotValue == SKV_VALUE_INVALID && subLayerInDatabaseAndCompleted) || (tilLevel < depthOfFullTree && shortKnotValue == SKV_VALUE_INVALID && plyInfo != PLYINFO_VALUE_UNCALCULATED)) { // version 22: replaced: curCalculatedLayer == layerNumber && knot->plyInfo != PLYINFO_VALUE_UNCALCULATED)) {
|
||||
knot->shortValue = SKV_VALUE_INVALID;
|
||||
knot->plyInfo = PLYINFO_VALUE_INVALID;
|
||||
knot->floatValue = (float)knot->shortValue;
|
||||
|
@ -460,14 +422,12 @@ bool MiniMax::alphaBetaTryDataBase(Node *knot, RunAlphaBetaVars *rabVars, unsign
|
|||
}
|
||||
|
||||
// print out put, if not calculating database, but requesting a knot value
|
||||
if (shortKnotValue != SKV_VALUE_INVALID && tilLevel == depthOfFullTree && !calcDatabase && subLayerInDatabaseAndCompleted)
|
||||
{
|
||||
if (shortKnotValue != SKV_VALUE_INVALID && tilLevel == depthOfFullTree && !calcDatabase && subLayerInDatabaseAndCompleted) {
|
||||
PRINT(2, this, "This state is marked as " << ((shortKnotValue == SKV_VALUE_GAME_WON) ? "WON" : ((shortKnotValue == SKV_VALUE_GAME_LOST) ? "LOST" : ((shortKnotValue == SKV_VALUE_GAME_DRAWN) ? "DRAW" : "INVALID"))) << endl);
|
||||
}
|
||||
|
||||
// when knot value is valid then return best branch
|
||||
if (calcDatabase && tilLevel < depthOfFullTree && shortKnotValue != SKV_VALUE_INVALID && plyInfo != PLYINFO_VALUE_UNCALCULATED || !calcDatabase && tilLevel < depthOfFullTree - 1 && shortKnotValue != SKV_VALUE_INVALID)
|
||||
{
|
||||
if (calcDatabase && tilLevel < depthOfFullTree && shortKnotValue != SKV_VALUE_INVALID && plyInfo != PLYINFO_VALUE_UNCALCULATED || !calcDatabase && tilLevel < depthOfFullTree - 1 && shortKnotValue != SKV_VALUE_INVALID) {
|
||||
|
||||
// switch if is not opponent level
|
||||
if (knot->isOpponentLevel)
|
||||
|
@ -492,12 +452,10 @@ void MiniMax::alphaBetaTryPossibilites(Node *knot, RunAlphaBetaVars *rabVars, un
|
|||
void *pBackup;
|
||||
unsigned int curPoss;
|
||||
|
||||
for (curPoss = 0; curPoss < knot->numPossibilities; curPoss++)
|
||||
{
|
||||
for (curPoss = 0; curPoss < knot->numPossibilities; curPoss++) {
|
||||
|
||||
// output
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase)
|
||||
{
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase) {
|
||||
printMoveInformation(rabVars->curThreadNo, idPossibility[curPoss], pPossibilities);
|
||||
rabVars->freqValuesSubMoves[SKV_VALUE_INVALID] = 0;
|
||||
rabVars->freqValuesSubMoves[SKV_VALUE_GAME_LOST] = 0;
|
||||
|
@ -515,25 +473,18 @@ void MiniMax::alphaBetaTryPossibilites(Node *knot, RunAlphaBetaVars *rabVars, un
|
|||
undo(rabVars->curThreadNo, idPossibility[curPoss], knot->isOpponentLevel, pBackup, pPossibilities);
|
||||
|
||||
// output
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase)
|
||||
{
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase) {
|
||||
rabVars->freqValuesSubMovesBranchWon[curPoss] = rabVars->freqValuesSubMoves[SKV_VALUE_GAME_WON];
|
||||
if (rabVars->freqValuesSubMoves[SKV_VALUE_GAME_WON] > maxWonfreqValuesSubMoves && knot->branches[curPoss].shortValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (rabVars->freqValuesSubMoves[SKV_VALUE_GAME_WON] > maxWonfreqValuesSubMoves && knot->branches[curPoss].shortValue == SKV_VALUE_GAME_DRAWN) {
|
||||
maxWonfreqValuesSubMoves = rabVars->freqValuesSubMoves[SKV_VALUE_GAME_WON];
|
||||
}
|
||||
if (hFileShortKnotValues != nullptr && layerInDatabase)
|
||||
{
|
||||
if (hFileShortKnotValues != nullptr && layerInDatabase) {
|
||||
storeValueOfMove(rabVars->curThreadNo, idPossibility[curPoss], pPossibilities, knot->branches[curPoss].shortValue, rabVars->freqValuesSubMoves, knot->branches[curPoss].plyInfo);
|
||||
PRINT(0, this, "\t: " << ((knot->branches[curPoss].shortValue == SKV_VALUE_GAME_WON) ? "WON" : ((knot->branches[curPoss].shortValue == SKV_VALUE_GAME_LOST) ? "LOST" : ((knot->branches[curPoss].shortValue == SKV_VALUE_GAME_DRAWN) ? "DRAW" : "INVALID"))) << endl);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PRINT(0, this, "\t: " << knot->branches[curPoss].floatValue << endl);
|
||||
}
|
||||
}
|
||||
else if (tilLevel == depthOfFullTree - 1 && !calcDatabase)
|
||||
{
|
||||
} else if (tilLevel == depthOfFullTree - 1 && !calcDatabase) {
|
||||
rabVars->freqValuesSubMoves[knot->branches[curPoss].shortValue]++;
|
||||
}
|
||||
|
||||
|
@ -544,39 +495,27 @@ void MiniMax::alphaBetaTryPossibilites(Node *knot, RunAlphaBetaVars *rabVars, un
|
|||
continue;
|
||||
|
||||
// alpha beta algorithmn
|
||||
if (!knot->isOpponentLevel)
|
||||
{
|
||||
if (knot->branches[curPoss].floatValue >= beta)
|
||||
{
|
||||
if (!knot->isOpponentLevel) {
|
||||
if (knot->branches[curPoss].floatValue >= beta) {
|
||||
knot->numPossibilities = curPoss + 1;
|
||||
break;
|
||||
}
|
||||
else if (knot->branches[curPoss].floatValue > alpha)
|
||||
{
|
||||
} else if (knot->branches[curPoss].floatValue > alpha) {
|
||||
alpha = knot->branches[curPoss].floatValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (knot->branches[curPoss].floatValue <= alpha)
|
||||
{
|
||||
} else {
|
||||
if (knot->branches[curPoss].floatValue <= alpha) {
|
||||
knot->numPossibilities = curPoss + 1;
|
||||
break;
|
||||
}
|
||||
else if (knot->branches[curPoss].floatValue < beta)
|
||||
{
|
||||
} else if (knot->branches[curPoss].floatValue < beta) {
|
||||
beta = knot->branches[curPoss].floatValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let delete pPossibilities
|
||||
if (tilLevel < depthOfFullTree)
|
||||
{
|
||||
if (tilLevel < depthOfFullTree) {
|
||||
deletePossibilities(rabVars->curThreadNo, pPossibilities);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
pRootPossibilities = pPossibilities;
|
||||
}
|
||||
}
|
||||
|
@ -593,25 +532,18 @@ void MiniMax::alphaBetaCalcKnotValue(Node *knot)
|
|||
unsigned int i;
|
||||
|
||||
// opponent tries to minimize the value
|
||||
if (knot->isOpponentLevel)
|
||||
{
|
||||
for (i = 1; i < knot->numPossibilities; i++)
|
||||
{
|
||||
if (knot->isOpponentLevel) {
|
||||
for (i = 1; i < knot->numPossibilities; i++) {
|
||||
// version 21: it should be impossible that knot->shortValue is equal SKV_VALUE_INVALID
|
||||
if (/*knot->shortValue != SKV_VALUE_INVALID && */ knot->branches[i].floatValue < maxValue)
|
||||
{
|
||||
if (/*knot->shortValue != SKV_VALUE_INVALID && */ knot->branches[i].floatValue < maxValue) {
|
||||
maxValue = knot->branches[i].floatValue;
|
||||
maxBranch = i;
|
||||
}
|
||||
}
|
||||
// maximize the value
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < knot->numPossibilities; i++)
|
||||
{
|
||||
if (/*knot->shortValue != SKV_VALUE_INVALID && */ knot->branches[i].floatValue > maxValue)
|
||||
{
|
||||
} else {
|
||||
for (i = 1; i < knot->numPossibilities; i++) {
|
||||
if (/*knot->shortValue != SKV_VALUE_INVALID && */ knot->branches[i].floatValue > maxValue) {
|
||||
maxValue = knot->branches[i].floatValue;
|
||||
maxBranch = i;
|
||||
}
|
||||
|
@ -636,16 +568,11 @@ void MiniMax::alphaBetaCalcPlyInfo(Node *knot)
|
|||
TwoBit shortKnotValue;
|
||||
|
||||
//
|
||||
if (knot->shortValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (knot->shortValue == SKV_VALUE_GAME_DRAWN) {
|
||||
knot->plyInfo = PLYINFO_VALUE_DRAWN;
|
||||
}
|
||||
else if (knot->shortValue == SKV_VALUE_INVALID)
|
||||
{
|
||||
} else if (knot->shortValue == SKV_VALUE_INVALID) {
|
||||
knot->plyInfo = PLYINFO_VALUE_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// calculate value of knot
|
||||
shortKnotValue = (knot->isOpponentLevel) ? skvPerspectiveMatrix[knot->shortValue][PL_TO_MOVE_UNCHANGED] : knot->shortValue;
|
||||
|
@ -653,11 +580,9 @@ void MiniMax::alphaBetaCalcPlyInfo(Node *knot)
|
|||
maxBranch = 0;
|
||||
|
||||
// when current knot is a won state
|
||||
if (shortKnotValue == SKV_VALUE_GAME_WON)
|
||||
{
|
||||
if (shortKnotValue == SKV_VALUE_GAME_WON) {
|
||||
|
||||
for (i = 0; i < knot->numPossibilities; i++)
|
||||
{
|
||||
for (i = 0; i < knot->numPossibilities; i++) {
|
||||
|
||||
// invert knot value if necessary
|
||||
shortKnotValue = (knot->branches[i].isOpponentLevel) ? skvPerspectiveMatrix[knot->branches[i].shortValue][PL_TO_MOVE_UNCHANGED] : knot->branches[i].shortValue;
|
||||
|
@ -666,8 +591,7 @@ void MiniMax::alphaBetaCalcPlyInfo(Node *knot)
|
|||
if ((knot->branches[i].plyInfo < maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_LOST && knot->isOpponentLevel != knot->branches[i].isOpponentLevel)
|
||||
|
||||
// after this move the same player will continue, so take the minimum of the won states
|
||||
|| (knot->branches[i].plyInfo < maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_WON && knot->isOpponentLevel == knot->branches[i].isOpponentLevel))
|
||||
{
|
||||
|| (knot->branches[i].plyInfo < maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_WON && knot->isOpponentLevel == knot->branches[i].isOpponentLevel)) {
|
||||
|
||||
maxPlyInfo = knot->branches[i].plyInfo;
|
||||
maxBranch = i;
|
||||
|
@ -675,12 +599,9 @@ void MiniMax::alphaBetaCalcPlyInfo(Node *knot)
|
|||
}
|
||||
|
||||
// current state is a lost state
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
for (i = 0; i < knot->numPossibilities; i++)
|
||||
{
|
||||
for (i = 0; i < knot->numPossibilities; i++) {
|
||||
|
||||
// invert knot value if necessary
|
||||
shortKnotValue = (knot->branches[i].isOpponentLevel) ? skvPerspectiveMatrix[knot->branches[i].shortValue][PL_TO_MOVE_UNCHANGED] : knot->branches[i].shortValue;
|
||||
|
@ -689,8 +610,7 @@ void MiniMax::alphaBetaCalcPlyInfo(Node *knot)
|
|||
if ((knot->branches[i].plyInfo > maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_WON && knot->isOpponentLevel != knot->branches[i].isOpponentLevel)
|
||||
|
||||
// take the maximum of the won states, since that's the longest path
|
||||
|| (knot->branches[i].plyInfo > maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_LOST && knot->isOpponentLevel == knot->branches[i].isOpponentLevel))
|
||||
{
|
||||
|| (knot->branches[i].plyInfo > maxPlyInfo && shortKnotValue == SKV_VALUE_GAME_LOST && knot->isOpponentLevel == knot->branches[i].isOpponentLevel)) {
|
||||
|
||||
maxPlyInfo = knot->branches[i].plyInfo;
|
||||
maxBranch = i;
|
||||
|
@ -717,49 +637,37 @@ void MiniMax::alphaBetaChooseBestMove(Node *knot, RunAlphaBetaVars *rabVars, uns
|
|||
unsigned int maxBranch;
|
||||
|
||||
// select randomly one of the best moves, if they are equivalent
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase)
|
||||
{
|
||||
if (tilLevel == depthOfFullTree && !calcDatabase) {
|
||||
|
||||
// check every possible move
|
||||
for (numBestChoices = 0, i = 0; i < knot->numPossibilities; i++)
|
||||
{
|
||||
for (numBestChoices = 0, i = 0; i < knot->numPossibilities; i++) {
|
||||
|
||||
// use information in database
|
||||
if (layerInDatabase && hFileShortKnotValues != nullptr)
|
||||
{
|
||||
if (layerInDatabase && hFileShortKnotValues != nullptr) {
|
||||
|
||||
// selected move with equal knot value
|
||||
if (knot->branches[i].shortValue == knot->shortValue)
|
||||
{
|
||||
if (knot->branches[i].shortValue == knot->shortValue) {
|
||||
|
||||
// best move lead to drawn state
|
||||
if (knot->shortValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (maxWonfreqValuesSubMoves == rabVars->freqValuesSubMovesBranchWon[i])
|
||||
{
|
||||
if (knot->shortValue == SKV_VALUE_GAME_DRAWN) {
|
||||
if (maxWonfreqValuesSubMoves == rabVars->freqValuesSubMovesBranchWon[i]) {
|
||||
bestBranches[numBestChoices] = i;
|
||||
numBestChoices++;
|
||||
}
|
||||
|
||||
// best move lead to lost or won state
|
||||
}
|
||||
else
|
||||
{
|
||||
if (knot->plyInfo == knot->branches[i].plyInfo + 1)
|
||||
{
|
||||
} else {
|
||||
if (knot->plyInfo == knot->branches[i].plyInfo + 1) {
|
||||
bestBranches[numBestChoices] = i;
|
||||
numBestChoices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// conventionell mini-max algorithm
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dif = knot->branches[i].floatValue - knot->floatValue;
|
||||
dif = (dif > 0) ? dif : -1.0f * dif;
|
||||
if (dif < FPKV_THRESHOLD)
|
||||
{
|
||||
if (dif < FPKV_THRESHOLD) {
|
||||
bestBranches[numBestChoices] = i;
|
||||
numBestChoices++;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
void MiniMax::closeDatabase()
|
||||
{
|
||||
// close database
|
||||
if (hFileShortKnotValues != nullptr)
|
||||
{
|
||||
if (hFileShortKnotValues != nullptr) {
|
||||
unloadAllLayers();
|
||||
SAFE_DELETE_ARRAY(layerStats);
|
||||
CloseHandle(hFileShortKnotValues);
|
||||
|
@ -24,8 +23,7 @@ void MiniMax::closeDatabase()
|
|||
}
|
||||
|
||||
// close ply information file
|
||||
if (hFilePlyInfo != nullptr)
|
||||
{
|
||||
if (hFilePlyInfo != nullptr) {
|
||||
unloadAllPlyInfos();
|
||||
SAFE_DELETE_ARRAY(plyInfos);
|
||||
CloseHandle(hFilePlyInfo);
|
||||
|
@ -65,8 +63,7 @@ void MiniMax::unloadLayer(unsigned int layerNumber)
|
|||
//-----------------------------------------------------------------------------
|
||||
void MiniMax::unloadAllPlyInfos()
|
||||
{
|
||||
for (unsigned int i = 0; i < plyInfoHeader.numLayers; i++)
|
||||
{
|
||||
for (unsigned int i = 0; i < plyInfoHeader.numLayers; i++) {
|
||||
unloadPlyInfo(i);
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +74,7 @@ void MiniMax::unloadAllPlyInfos()
|
|||
//-----------------------------------------------------------------------------
|
||||
void MiniMax::unloadAllLayers()
|
||||
{
|
||||
for (unsigned int i = 0; i < skvfHeader.numLayers; i++)
|
||||
{
|
||||
for (unsigned int i = 0; i < skvfHeader.numLayers; i++) {
|
||||
unloadLayer(i);
|
||||
}
|
||||
}
|
||||
|
@ -97,23 +93,18 @@ void MiniMax::saveBytesToFile(HANDLE hFile, long long offset, unsigned int numBy
|
|||
|
||||
liDistanceToMove.QuadPart = offset;
|
||||
|
||||
while (errorPrint = !SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
|
||||
{
|
||||
while (errorPrint = !SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN)) {
|
||||
if (!errorPrint)
|
||||
PRINT(1, this, "ERROR: SetFilePointerEx failed!");
|
||||
}
|
||||
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (WriteFile(hFile, myPointer, restingBytes, &dwBytesWritten, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (WriteFile(hFile, myPointer, restingBytes, &dwBytesWritten, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesWritten;
|
||||
myPointer = (void *)(((unsigned char *)myPointer) + dwBytesWritten);
|
||||
if (restingBytes > 0)
|
||||
PRINT(2, this, "Still " << restingBytes << " to write!");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!errorPrint)
|
||||
PRINT(0, this, "ERROR: WriteFile Failed!");
|
||||
errorPrint = true;
|
||||
|
@ -135,25 +126,19 @@ void MiniMax::loadBytesFromFile(HANDLE hFile, long long offset, unsigned int num
|
|||
|
||||
liDistanceToMove.QuadPart = offset;
|
||||
|
||||
while (errorPrint = !SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
|
||||
{
|
||||
while (errorPrint = !SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN)) {
|
||||
if (!errorPrint)
|
||||
PRINT(0, this, "ERROR: SetFilePointerEx failed!");
|
||||
}
|
||||
|
||||
while (restingBytes > 0)
|
||||
{
|
||||
if (ReadFile(hFile, pBytes, restingBytes, &dwBytesRead, nullptr) == TRUE)
|
||||
{
|
||||
while (restingBytes > 0) {
|
||||
if (ReadFile(hFile, pBytes, restingBytes, &dwBytesRead, nullptr) == TRUE) {
|
||||
restingBytes -= dwBytesRead;
|
||||
myPointer = (void *)(((unsigned char *)myPointer) + dwBytesRead);
|
||||
if (restingBytes > 0)
|
||||
{
|
||||
if (restingBytes > 0) {
|
||||
PRINT(2, this, "Still " << restingBytes << " bytes to read!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (!errorPrint)
|
||||
PRINT(0, this, "ERROR: ReadFile Failed!");
|
||||
errorPrint = true;
|
||||
|
@ -169,12 +154,9 @@ bool MiniMax::isCurrentStateInDatabase(unsigned int threadNo)
|
|||
{
|
||||
unsigned int layerNum, stateNumber;
|
||||
|
||||
if (hFileShortKnotValues == nullptr)
|
||||
{
|
||||
if (hFileShortKnotValues == nullptr) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
getLayerAndStateNumber(threadNo, layerNum, stateNumber);
|
||||
return layerStats[layerNum].layerIsCompletedAndInFile;
|
||||
}
|
||||
|
@ -210,8 +192,7 @@ void MiniMax::saveHeader(PlyInfoFileHeader *piH, PlyInfo *pInfo)
|
|||
//-----------------------------------------------------------------------------
|
||||
bool MiniMax::openDatabase(const char *directory, unsigned int maximumNumberOfBranches)
|
||||
{
|
||||
if (strlen(directory) && !PathFileExistsA(directory))
|
||||
{
|
||||
if (strlen(directory) && !PathFileExistsA(directory)) {
|
||||
PRINT(0, this, "ERROR: Database path " << directory << " not valid!");
|
||||
return falseOrStop();
|
||||
}
|
||||
|
@ -244,8 +225,7 @@ void MiniMax::openSkvFile(const char *directory, unsigned int maximumNumberOfBra
|
|||
hFileShortKnotValues = CreateFileA(ssDatabaseFile.str().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hFileShortKnotValues == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hFileShortKnotValues == INVALID_HANDLE_VALUE) {
|
||||
hFileShortKnotValues = nullptr;
|
||||
return;
|
||||
}
|
||||
|
@ -258,8 +238,7 @@ void MiniMax::openSkvFile(const char *directory, unsigned int maximumNumberOfBra
|
|||
ReadFile(hFileShortKnotValues, &skvfHeader, sizeof(SkvFileHeader), &dwBytesRead, nullptr);
|
||||
|
||||
// invalid file ?
|
||||
if (dwBytesRead != sizeof(SkvFileHeader) || skvfHeader.headerCode != SKV_FILE_HEADER_CODE)
|
||||
{
|
||||
if (dwBytesRead != sizeof(SkvFileHeader) || skvfHeader.headerCode != SKV_FILE_HEADER_CODE) {
|
||||
|
||||
// create default header
|
||||
skvfHeader.completed = false;
|
||||
|
@ -269,8 +248,7 @@ void MiniMax::openSkvFile(const char *directory, unsigned int maximumNumberOfBra
|
|||
layerStats = new LayerStats[skvfHeader.numLayers];
|
||||
layerStats[0].layerOffset = 0;
|
||||
|
||||
for (i = 0; i < skvfHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 0; i < skvfHeader.numLayers; i++) {
|
||||
getSuccLayers(i, &layerStats[i].numSuccLayers, &layerStats[i].succLayers[0]);
|
||||
layerStats[i].partnerLayer = getPartnerLayer(i);
|
||||
layerStats[i].knotsInLayer = getNumberOfKnotsInLayer(i);
|
||||
|
@ -285,8 +263,7 @@ void MiniMax::openSkvFile(const char *directory, unsigned int maximumNumberOfBra
|
|||
layerStats[i].numInvalidStates = 0;
|
||||
}
|
||||
|
||||
for (i = 1; i < skvfHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 1; i < skvfHeader.numLayers; i++) {
|
||||
layerStats[i].layerOffset = layerStats[i - 1].layerOffset + layerStats[i - 1].sizeInBytes;
|
||||
}
|
||||
|
||||
|
@ -294,13 +271,10 @@ void MiniMax::openSkvFile(const char *directory, unsigned int maximumNumberOfBra
|
|||
saveHeader(&skvfHeader, layerStats);
|
||||
|
||||
// read layer stats
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
layerStats = new LayerStats[skvfHeader.numLayers];
|
||||
ReadFile(hFileShortKnotValues, layerStats, sizeof(LayerStats) * skvfHeader.numLayers, &dwBytesRead, nullptr);
|
||||
for (i = 0; i < skvfHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 0; i < skvfHeader.numLayers; i++) {
|
||||
layerStats[i].shortKnotValueByte = nullptr;
|
||||
layerStats[i].skvCompressed = nullptr;
|
||||
}
|
||||
|
@ -331,8 +305,7 @@ void MiniMax::openPlyInfoFile(const char *directory)
|
|||
hFilePlyInfo = CreateFileA(ssFile.str().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
|
||||
// opened file succesfully
|
||||
if (hFilePlyInfo == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (hFilePlyInfo == INVALID_HANDLE_VALUE) {
|
||||
hFilePlyInfo = nullptr;
|
||||
return;
|
||||
}
|
||||
|
@ -344,8 +317,7 @@ void MiniMax::openPlyInfoFile(const char *directory)
|
|||
ReadFile(hFilePlyInfo, &plyInfoHeader, sizeof(plyInfoHeader), &dwBytesRead, nullptr);
|
||||
|
||||
// invalid file ?
|
||||
if (dwBytesRead != sizeof(plyInfoHeader) || plyInfoHeader.headerCode != PLYINFO_HEADER_CODE)
|
||||
{
|
||||
if (dwBytesRead != sizeof(plyInfoHeader) || plyInfoHeader.headerCode != PLYINFO_HEADER_CODE) {
|
||||
|
||||
// create default header
|
||||
plyInfoHeader.plyInfoCompleted = false;
|
||||
|
@ -355,8 +327,7 @@ void MiniMax::openPlyInfoFile(const char *directory)
|
|||
plyInfos = new PlyInfo[plyInfoHeader.numLayers];
|
||||
plyInfos[0].layerOffset = 0;
|
||||
|
||||
for (i = 0; i < plyInfoHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 0; i < plyInfoHeader.numLayers; i++) {
|
||||
plyInfos[i].knotsInLayer = getNumberOfKnotsInLayer(i);
|
||||
plyInfos[i].plyInfo = nullptr;
|
||||
plyInfos[i].plyInfoCompressed = nullptr;
|
||||
|
@ -365,8 +336,7 @@ void MiniMax::openPlyInfoFile(const char *directory)
|
|||
plyInfos[i].sizeInBytes = plyInfos[i].knotsInLayer * sizeof(PlyInfoVarType);
|
||||
}
|
||||
|
||||
for (i = 1; i < plyInfoHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 1; i < plyInfoHeader.numLayers; i++) {
|
||||
plyInfos[i].layerOffset = plyInfos[i - 1].layerOffset + plyInfos[i - 1].sizeInBytes;
|
||||
}
|
||||
|
||||
|
@ -374,13 +344,10 @@ void MiniMax::openPlyInfoFile(const char *directory)
|
|||
saveHeader(&plyInfoHeader, plyInfos);
|
||||
|
||||
// read layer stats
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
plyInfos = new PlyInfo[plyInfoHeader.numLayers];
|
||||
ReadFile(hFilePlyInfo, plyInfos, sizeof(PlyInfo) * plyInfoHeader.numLayers, &dwBytesRead, nullptr);
|
||||
for (i = 0; i < plyInfoHeader.numLayers; i++)
|
||||
{
|
||||
for (i = 0; i < plyInfoHeader.numLayers; i++) {
|
||||
plyInfos[i].plyInfo = nullptr;
|
||||
plyInfos[i].plyInfoCompressed = nullptr;
|
||||
}
|
||||
|
@ -400,8 +367,7 @@ void MiniMax::saveLayerToFile(unsigned int layerNumber)
|
|||
return;
|
||||
|
||||
// save layer if there are any states
|
||||
if (myLss->sizeInBytes)
|
||||
{
|
||||
if (myLss->sizeInBytes) {
|
||||
|
||||
// short knot values & ply info
|
||||
curCalculationActionId = MM_ACTION_SAVING_LAYER_TO_FILE;
|
||||
|
@ -428,21 +394,17 @@ inline void MiniMax::measureIops(long long &numOperations, LARGE_INTEGER &interv
|
|||
numOperations++; // ... not thread-safe !!!
|
||||
|
||||
// only the time for the io-operation is considered and accumulated
|
||||
if (MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_ONLY_IO) {
|
||||
QueryPerformanceCounter(&curTimeAfter);
|
||||
interval.QuadPart += curTimeAfter.QuadPart - curTimeBefore.QuadPart; // ... not thread-safe !!!
|
||||
double totalTimeGone = (double)interval.QuadPart / frequency.QuadPart; // ... not thread-safe !!!
|
||||
if (totalTimeGone >= 5.0)
|
||||
{
|
||||
if (totalTimeGone >= 5.0) {
|
||||
PRINT(0, this, text << "operations per second for last interval: " << (int)(numOperations / totalTimeGone));
|
||||
interval.QuadPart = 0; // ... not thread-safe !!!
|
||||
numOperations = 0; // ... not thread-safe !!!
|
||||
}
|
||||
// the whole time passed since the beginning of the interval is considered
|
||||
}
|
||||
else if (numOperations >= MEASURE_TIME_FREQUENCY)
|
||||
{
|
||||
} else if (numOperations >= MEASURE_TIME_FREQUENCY) {
|
||||
QueryPerformanceCounter(&curTimeAfter);
|
||||
double totalTimeGone = (double)(curTimeAfter.QuadPart - interval.QuadPart) / frequency.QuadPart; // ... not thread-safe !!!
|
||||
PRINT(0, this, text << "operations per second for last interval: " << numOperations / totalTimeGone);
|
||||
|
@ -465,17 +427,13 @@ void MiniMax::readKnotValueFromDatabase(unsigned int threadNo, unsigned int &lay
|
|||
layerInDatabaseAndCompleted = myLss->layerIsCompletedAndInFile;
|
||||
|
||||
// valid state and layer number ?
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer)
|
||||
{
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer) {
|
||||
invalidLayerOrStateNumber = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
invalidLayerOrStateNumber = false; // checkStateIntegrity();
|
||||
}
|
||||
|
||||
if (invalidLayerOrStateNumber)
|
||||
{
|
||||
if (invalidLayerOrStateNumber) {
|
||||
knotValue = SKV_VALUE_INVALID;
|
||||
return;
|
||||
}
|
||||
|
@ -497,38 +455,29 @@ void MiniMax::readKnotValueFromDatabase(unsigned int layerNumber, unsigned int s
|
|||
LayerStats *myLss = &layerStats[layerNumber];
|
||||
|
||||
// valid state and layer number ?
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer)
|
||||
{
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer) {
|
||||
PRINT(0, this, "ERROR: INVALID layerNumber OR stateNumber in readKnotValueFromDatabase()!");
|
||||
knotValue = SKV_VALUE_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
// if database is complete get whole byte from file
|
||||
if (skvfHeader.completed || layerInDatabase || myLss->layerIsCompletedAndInFile)
|
||||
{
|
||||
if (skvfHeader.completed || layerInDatabase || myLss->layerIsCompletedAndInFile) {
|
||||
EnterCriticalSection(&csDatabase);
|
||||
loadBytesFromFile(hFileShortKnotValues, skvfHeader.headerAndStatsSize + myLss->layerOffset + stateNumber / 4, 1, &databaseByte);
|
||||
LeaveCriticalSection(&csDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// is layer already loaded
|
||||
if (!myLss->layerIsLoaded)
|
||||
{
|
||||
if (!myLss->layerIsLoaded) {
|
||||
|
||||
EnterCriticalSection(&csDatabase);
|
||||
if (!myLss->layerIsLoaded)
|
||||
{
|
||||
if (!myLss->layerIsLoaded) {
|
||||
// if layer is in database and completed, then load layer from file into memory, set default value otherwise
|
||||
myLss->shortKnotValueByte = new unsigned char[myLss->sizeInBytes];
|
||||
if (myLss->layerIsCompletedAndInFile)
|
||||
{
|
||||
if (myLss->layerIsCompletedAndInFile) {
|
||||
loadBytesFromFile(hFileShortKnotValues, skvfHeader.headerAndStatsSize + myLss->layerOffset, myLss->sizeInBytes, myLss->shortKnotValueByte);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
memset(myLss->shortKnotValueByte, SKV_WHOLE_BYTE_IS_INVALID, myLss->sizeInBytes);
|
||||
}
|
||||
bytesAllocated = myLss->sizeInBytes;
|
||||
|
@ -544,8 +493,7 @@ void MiniMax::readKnotValueFromDatabase(unsigned int layerNumber, unsigned int s
|
|||
|
||||
// measure io-operations per second
|
||||
LARGE_INTEGER curTimeBefore;
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO) {
|
||||
QueryPerformanceCounter(&curTimeBefore);
|
||||
}
|
||||
|
||||
|
@ -573,39 +521,29 @@ void MiniMax::readPlyInfoFromDatabase(unsigned int layerNumber, unsigned int sta
|
|||
PlyInfo *myPis = &plyInfos[layerNumber];
|
||||
|
||||
// valid state and layer number ?
|
||||
if (layerNumber > plyInfoHeader.numLayers || stateNumber > myPis->knotsInLayer)
|
||||
{
|
||||
if (layerNumber > plyInfoHeader.numLayers || stateNumber > myPis->knotsInLayer) {
|
||||
PRINT(0, this, "ERROR: INVALID layerNumber OR stateNumber in readPlyInfoFromDatabase()!");
|
||||
value = PLYINFO_VALUE_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
// if database is complete get whole byte from file
|
||||
if (plyInfoHeader.plyInfoCompleted || layerInDatabase || myPis->plyInfoIsCompletedAndInFile)
|
||||
{
|
||||
if (plyInfoHeader.plyInfoCompleted || layerInDatabase || myPis->plyInfoIsCompletedAndInFile) {
|
||||
EnterCriticalSection(&csDatabase);
|
||||
loadBytesFromFile(hFilePlyInfo, plyInfoHeader.headerAndPlyInfosSize + myPis->layerOffset + sizeof(PlyInfoVarType) * stateNumber, sizeof(PlyInfoVarType), &value);
|
||||
LeaveCriticalSection(&csDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// is layer already in memory?
|
||||
if (!myPis->plyInfoIsLoaded)
|
||||
{
|
||||
if (!myPis->plyInfoIsLoaded) {
|
||||
EnterCriticalSection(&csDatabase);
|
||||
if (!myPis->plyInfoIsLoaded)
|
||||
{
|
||||
if (!myPis->plyInfoIsLoaded) {
|
||||
// if layer is in database and completed, then load layer from file into memory; set default value otherwise
|
||||
myPis->plyInfo = new PlyInfoVarType[myPis->knotsInLayer];
|
||||
if (myPis->plyInfoIsCompletedAndInFile)
|
||||
{
|
||||
if (myPis->plyInfoIsCompletedAndInFile) {
|
||||
loadBytesFromFile(hFilePlyInfo, plyInfoHeader.headerAndPlyInfosSize + myPis->layerOffset, myPis->sizeInBytes, myPis->plyInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++)
|
||||
{
|
||||
} else {
|
||||
for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++) {
|
||||
myPis->plyInfo[curKnot] = defValue;
|
||||
}
|
||||
}
|
||||
|
@ -620,8 +558,7 @@ void MiniMax::readPlyInfoFromDatabase(unsigned int layerNumber, unsigned int sta
|
|||
|
||||
// measure io-operations per second
|
||||
LARGE_INTEGER curTimeBefore;
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO) {
|
||||
QueryPerformanceCounter(&curTimeBefore);
|
||||
}
|
||||
|
||||
|
@ -645,26 +582,22 @@ void MiniMax::saveKnotValueInDatabase(unsigned int layerNumber, unsigned int sta
|
|||
LayerStats *myLss = &layerStats[layerNumber];
|
||||
|
||||
// valid state and layer number ?
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer)
|
||||
{
|
||||
if (layerNumber > skvfHeader.numLayers || stateNumber > myLss->knotsInLayer) {
|
||||
PRINT(0, this, "ERROR: INVALID layerNumber OR stateNumber in saveKnotValueInDatabase()!");
|
||||
return;
|
||||
}
|
||||
|
||||
// is layer already completed ?
|
||||
if (myLss->layerIsCompletedAndInFile)
|
||||
{
|
||||
if (myLss->layerIsCompletedAndInFile) {
|
||||
PRINT(0, this, "ERROR: layer already completed and in file! function: saveKnotValueInDatabase()!");
|
||||
return;
|
||||
}
|
||||
|
||||
// is layer already loaded?
|
||||
if (!myLss->layerIsLoaded)
|
||||
{
|
||||
if (!myLss->layerIsLoaded) {
|
||||
|
||||
EnterCriticalSection(&csDatabase);
|
||||
if (!myLss->layerIsLoaded)
|
||||
{
|
||||
if (!myLss->layerIsLoaded) {
|
||||
// reserve memory for this layer & create array for ply info with default value
|
||||
myLss->shortKnotValueByte = new TwoBit[myLss->sizeInBytes];
|
||||
memset(myLss->shortKnotValueByte, SKV_WHOLE_BYTE_IS_INVALID, myLss->sizeInBytes);
|
||||
|
@ -681,8 +614,7 @@ void MiniMax::saveKnotValueInDatabase(unsigned int layerNumber, unsigned int sta
|
|||
|
||||
// measure io-operations per second
|
||||
LARGE_INTEGER curTimeBefore;
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO) {
|
||||
QueryPerformanceCounter(&curTimeBefore);
|
||||
}
|
||||
|
||||
|
@ -692,8 +624,7 @@ void MiniMax::saveKnotValueInDatabase(unsigned int layerNumber, unsigned int sta
|
|||
long mask = 0x00000003 << numBitsToShift;
|
||||
long curShortKnotValueLong, newShortKnotValueLong;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
curShortKnotValueLong = *pShortKnotValue;
|
||||
newShortKnotValueLong = (curShortKnotValueLong & (~mask)) + (knotValue << numBitsToShift);
|
||||
} while (InterlockedCompareExchange(pShortKnotValue, newShortKnotValueLong, curShortKnotValueLong) != curShortKnotValueLong);
|
||||
|
@ -715,30 +646,25 @@ void MiniMax::savePlyInfoInDatabase(unsigned int layerNumber, unsigned int state
|
|||
PlyInfo *myPis = &plyInfos[layerNumber];
|
||||
|
||||
// valid state and layer number ?
|
||||
if (layerNumber > plyInfoHeader.numLayers || stateNumber > myPis->knotsInLayer)
|
||||
{
|
||||
if (layerNumber > plyInfoHeader.numLayers || stateNumber > myPis->knotsInLayer) {
|
||||
PRINT(0, this, "ERROR: INVALID layerNumber OR stateNumber in savePlyInfoInDatabase()!");
|
||||
return;
|
||||
}
|
||||
|
||||
// is layer already completed ?
|
||||
if (myPis->plyInfoIsCompletedAndInFile)
|
||||
{
|
||||
if (myPis->plyInfoIsCompletedAndInFile) {
|
||||
PRINT(0, this, "ERROR: layer already completed and in file! function: savePlyInfoInDatabase()!");
|
||||
return;
|
||||
}
|
||||
|
||||
// is layer already loaded
|
||||
if (!myPis->plyInfoIsLoaded)
|
||||
{
|
||||
if (!myPis->plyInfoIsLoaded) {
|
||||
|
||||
EnterCriticalSection(&csDatabase);
|
||||
if (!myPis->plyInfoIsLoaded)
|
||||
{
|
||||
if (!myPis->plyInfoIsLoaded) {
|
||||
// reserve memory for this layer & create array for ply info with default value
|
||||
myPis->plyInfo = new PlyInfoVarType[myPis->knotsInLayer];
|
||||
for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++)
|
||||
{
|
||||
for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++) {
|
||||
myPis->plyInfo[curKnot] = defValue;
|
||||
}
|
||||
bytesAllocated = myPis->sizeInBytes;
|
||||
|
@ -752,8 +678,7 @@ void MiniMax::savePlyInfoInDatabase(unsigned int layerNumber, unsigned int state
|
|||
|
||||
// measure io-operations per second
|
||||
LARGE_INTEGER curTimeBefore;
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO)
|
||||
{
|
||||
if (MEASURE_IOPS && MEASURE_ONLY_IO) {
|
||||
QueryPerformanceCounter(&curTimeBefore);
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
|
|||
|
||||
// init retro vars
|
||||
retroVars.thread.resize(threadManager.getNumThreads());
|
||||
for (threadNo = 0; threadNo < threadManager.getNumThreads(); threadNo++)
|
||||
{
|
||||
for (threadNo = 0; threadNo < threadManager.getNumThreads(); threadNo++) {
|
||||
retroVars.thread[threadNo].statesToProcess.resize(PLYINFO_EXP_VALUE, nullptr);
|
||||
retroVars.thread[threadNo].numStatesToProcess = 0;
|
||||
retroVars.thread[threadNo].threadNo = threadNo;
|
||||
|
@ -40,13 +39,11 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
|
|||
retroVars.layerInitialized.resize(skvfHeader.numLayers, false);
|
||||
retroVars.layersToCalculate = layersToCalculate;
|
||||
retroVars.pMiniMax = this;
|
||||
for (retroVars.totalNumKnots = 0, retroVars.numKnotsToCalc = 0, curLayer = 0; curLayer < layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (retroVars.totalNumKnots = 0, retroVars.numKnotsToCalc = 0, curLayer = 0; curLayer < layersToCalculate.size(); curLayer++) {
|
||||
retroVars.numKnotsToCalc += layerStats[layersToCalculate[curLayer]].knotsInLayer;
|
||||
retroVars.totalNumKnots += layerStats[layersToCalculate[curLayer]].knotsInLayer;
|
||||
retroVars.layerInitialized[layersToCalculate[curLayer]] = true;
|
||||
for (curSubLayer = 0; curSubLayer < layerStats[layersToCalculate[curLayer]].numSuccLayers; curSubLayer++)
|
||||
{
|
||||
for (curSubLayer = 0; curSubLayer < layerStats[layersToCalculate[curLayer]].numSuccLayers; curSubLayer++) {
|
||||
if (retroVars.layerInitialized[layerStats[layersToCalculate[curLayer]].succLayers[curSubLayer]])
|
||||
continue;
|
||||
else
|
||||
|
@ -63,16 +60,14 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
|
|||
|
||||
// initialization
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2 << endl);
|
||||
if (!initRetroAnalysis(retroVars))
|
||||
{
|
||||
if (!initRetroAnalysis(retroVars)) {
|
||||
abortCalculation = true;
|
||||
goto freeMem;
|
||||
}
|
||||
|
||||
// prepare count arrays
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2 << endl);
|
||||
if (!prepareCountArrays(retroVars))
|
||||
{
|
||||
if (!prepareCountArrays(retroVars)) {
|
||||
abortCalculation = true;
|
||||
goto freeMem;
|
||||
}
|
||||
|
@ -83,33 +78,27 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
|
|||
|
||||
// iteration
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2 << endl);
|
||||
if (!performRetroAnalysis(retroVars))
|
||||
{
|
||||
if (!performRetroAnalysis(retroVars)) {
|
||||
abortCalculation = true;
|
||||
goto freeMem;
|
||||
}
|
||||
|
||||
// show output
|
||||
PRINT(2, this, " Bytes in memory: " << memoryUsed2);
|
||||
for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++) {
|
||||
showLayerStats(layersToCalculate[curLayer]);
|
||||
}
|
||||
PRINT(2, this, "");
|
||||
|
||||
// free memory
|
||||
freeMem:
|
||||
for (threadNo = 0; threadNo < threadManager.getNumThreads(); threadNo++)
|
||||
{
|
||||
for (plyCounter = 0; plyCounter < retroVars.thread[threadNo].statesToProcess.size(); plyCounter++)
|
||||
{
|
||||
for (threadNo = 0; threadNo < threadManager.getNumThreads(); threadNo++) {
|
||||
for (plyCounter = 0; plyCounter < retroVars.thread[threadNo].statesToProcess.size(); plyCounter++) {
|
||||
SAFE_DELETE(retroVars.thread[threadNo].statesToProcess[plyCounter]);
|
||||
}
|
||||
}
|
||||
for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
if (retroVars.countArrays[curLayer] != nullptr)
|
||||
{
|
||||
for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++) {
|
||||
if (retroVars.countArrays[curLayer] != nullptr) {
|
||||
memoryUsed2 -= layerStats[layersToCalculate[curLayer]].knotsInLayer * sizeof(CountArrayVarType);
|
||||
arrayInfos.removeArray(layersToCalculate[curLayer], ArrayInfo::arrayType_countArray, layerStats[layersToCalculate[curLayer]].knotsInLayer * sizeof(CountArrayVarType), 0);
|
||||
}
|
||||
|
@ -135,8 +124,7 @@ bool MiniMax::initRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
bool initAlreadyDone = false; // true if the initialization information is already available in a file
|
||||
|
||||
// process each layer
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++)
|
||||
{
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) {
|
||||
|
||||
// set current processed layer number
|
||||
layerNumber = retroVars.layersToCalculate[curLayerId];
|
||||
|
@ -152,8 +140,7 @@ bool MiniMax::initRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
// does initialization file exist ?
|
||||
CreateDirectoryA(ssInitArrayPath.str().c_str(), nullptr);
|
||||
initArray = new BufferedFile(threadManager.getNumThreads(), FILE_BUFFER_SIZE, ssInitArrayFilePath.str().c_str());
|
||||
if (initArray->getFileSize() == (LONGLONG)layerStats[layerNumber].knotsInLayer)
|
||||
{
|
||||
if (initArray->getFileSize() == (LONGLONG)layerStats[layerNumber].knotsInLayer) {
|
||||
PRINT(2, this, " Loading init states from file: " << ssInitArrayFilePath.str());
|
||||
initAlreadyDone = true;
|
||||
}
|
||||
|
@ -173,8 +160,7 @@ bool MiniMax::initRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
ThreadManager::ThreadVarsArray<InitRetroAnalysisVars> tva(threadManager.getNumThreads(), InitRetroAnalysisVars(this, &retroVars, layerNumber, initArray, initAlreadyDone));
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeParallelLoop(initRetroAnalysisThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1))
|
||||
{
|
||||
switch (threadManager.executeParallelLoop(initRetroAnalysisThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -225,48 +211,38 @@ DWORD MiniMax::initRetroAnalysisThreadProc(void *pParameter, int index)
|
|||
iraVars->statesProcessed++;
|
||||
|
||||
// print status
|
||||
if (iraVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (iraVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(2, m, "Already initialized " << m->numStatesProcessed << " of " << m->layerStats[curState.layerNumber].knotsInLayer << " states");
|
||||
}
|
||||
|
||||
// layer initialization already done ? if so, then read from file
|
||||
if (iraVars->initAlreadyDone)
|
||||
{
|
||||
if (!iraVars->bufferedFile->readBytes(iraVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue))
|
||||
{
|
||||
if (iraVars->initAlreadyDone) {
|
||||
if (!iraVars->bufferedFile->readBytes(iraVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue)) {
|
||||
PRINT(0, m, "ERROR: initArray->takeBytes() failed");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
|
||||
// initialization not done
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// set current selected situation
|
||||
if (!m->setSituation(iraVars->curThreadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (!m->setSituation(iraVars->curThreadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
curStateValue = SKV_VALUE_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// get value of current situation
|
||||
m->getValueOfSituation(iraVars->curThreadNo, floatValue, curStateValue);
|
||||
}
|
||||
}
|
||||
|
||||
// save init value
|
||||
if (curStateValue != SKV_VALUE_INVALID)
|
||||
{
|
||||
if (curStateValue != SKV_VALUE_INVALID) {
|
||||
|
||||
// save short knot value
|
||||
m->saveKnotValueInDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
|
||||
|
||||
// put in list if state is final
|
||||
if (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST)
|
||||
{
|
||||
if (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST) {
|
||||
|
||||
// ply info
|
||||
m->savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, 0);
|
||||
|
@ -277,11 +253,9 @@ DWORD MiniMax::initRetroAnalysisThreadProc(void *pParameter, int index)
|
|||
}
|
||||
|
||||
// write data to file
|
||||
if (!iraVars->initAlreadyDone)
|
||||
{
|
||||
if (!iraVars->initAlreadyDone) {
|
||||
// curStateValue sollte 2 sein bei index == 1329322
|
||||
if (!iraVars->bufferedFile->writeBytes(iraVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue))
|
||||
{
|
||||
if (!iraVars->bufferedFile->writeBytes(iraVars->curThreadNo, index * sizeof(TwoBit), sizeof(TwoBit), (unsigned char *)&curStateValue)) {
|
||||
PRINT(0, m, "ERROR: bufferedFile->writeBytes failed!");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
|
@ -320,15 +294,13 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
|
|||
|
||||
// prepare count arrays
|
||||
CreateDirectoryA(ssCountArrayPath.str().c_str(), nullptr);
|
||||
if ((hFileCountArray = CreateFileA(ssCountArrayFilePath.str().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if ((hFileCountArray = CreateFileA(ssCountArrayFilePath.str().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr)) == INVALID_HANDLE_VALUE) {
|
||||
PRINT(0, this, "ERROR: Could not open File " << ssCountArrayFilePath.str() << "!");
|
||||
return falseOrStop();
|
||||
}
|
||||
|
||||
// allocate memory for count arrays
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++) {
|
||||
numKnotsInCurLayer = layerStats[retroVars.layersToCalculate[curLayer]].knotsInLayer;
|
||||
retroVars.countArrays[curLayer] = new CountArrayVarType[numKnotsInCurLayer];
|
||||
memoryUsed2 += numKnotsInCurLayer * sizeof(CountArrayVarType);
|
||||
|
@ -336,12 +308,10 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
|
|||
}
|
||||
|
||||
// load file if already existend
|
||||
if (GetFileSizeEx(hFileCountArray, &fileSize) && fileSize.QuadPart == retroVars.numKnotsToCalc)
|
||||
{
|
||||
if (GetFileSizeEx(hFileCountArray, &fileSize) && fileSize.QuadPart == retroVars.numKnotsToCalc) {
|
||||
PRINT(2, this, " Load number of succedors from file: " << ssCountArrayFilePath.str().c_str());
|
||||
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++) {
|
||||
numKnotsInCurLayer = layerStats[retroVars.layersToCalculate[curLayer]].knotsInLayer;
|
||||
if (!ReadFile(hFileCountArray, retroVars.countArrays[curLayer], numKnotsInCurLayer * sizeof(CountArrayVarType), &dwRead, nullptr))
|
||||
return falseOrStop();
|
||||
|
@ -350,30 +320,24 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
|
|||
}
|
||||
|
||||
// else calculate number of succedding states
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// Set default value 0
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++) {
|
||||
numKnotsInCurLayer = layerStats[retroVars.layersToCalculate[curLayer]].knotsInLayer;
|
||||
for (curState.stateNumber = 0; curState.stateNumber < numKnotsInCurLayer; curState.stateNumber++)
|
||||
{
|
||||
for (curState.stateNumber = 0; curState.stateNumber < numKnotsInCurLayer; curState.stateNumber++) {
|
||||
retroVars.countArrays[curLayer][curState.stateNumber] = defValue;
|
||||
}
|
||||
}
|
||||
|
||||
// calc values
|
||||
if (!calcNumSuccedors(retroVars))
|
||||
{
|
||||
if (!calcNumSuccedors(retroVars)) {
|
||||
CloseHandle(hFileCountArray);
|
||||
return false;
|
||||
}
|
||||
|
||||
// save to file
|
||||
for (curLayer = 0, dwWritten = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++)
|
||||
{
|
||||
for (curLayer = 0, dwWritten = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++) {
|
||||
numKnotsInCurLayer = layerStats[retroVars.layersToCalculate[curLayer]].knotsInLayer;
|
||||
if (!WriteFile(hFileCountArray, retroVars.countArrays[curLayer], numKnotsInCurLayer * sizeof(CountArrayVarType), &dwWritten, nullptr))
|
||||
return falseOrStop();
|
||||
|
@ -402,16 +366,14 @@ bool MiniMax::calcNumSuccedors(retroAnalysisGlobalVars &retroVars)
|
|||
vector<bool> succCalculated(skvfHeader.numLayers, false); //
|
||||
|
||||
// process each layer
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++)
|
||||
{
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) {
|
||||
|
||||
// set current processed layer number
|
||||
layerNumber = retroVars.layersToCalculate[curLayerId];
|
||||
PRINT(0, this, " *** Calculate number of succeding states for each state of layer " << layerNumber << " ***");
|
||||
|
||||
// process layer ...
|
||||
if (!succCalculated[layerNumber])
|
||||
{
|
||||
if (!succCalculated[layerNumber]) {
|
||||
|
||||
// prepare parameters for multithreading
|
||||
succCalculated[layerNumber] = true;
|
||||
|
@ -419,8 +381,7 @@ bool MiniMax::calcNumSuccedors(retroAnalysisGlobalVars &retroVars)
|
|||
ThreadManager::ThreadVarsArray<AddNumSuccedorsVars> tva(threadManager.getNumThreads(), AddNumSuccedorsVars(this, &retroVars, layerNumber));
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeParallelLoop(addNumSuccedorsThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1))
|
||||
{
|
||||
switch (threadManager.executeParallelLoop(addNumSuccedorsThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -438,15 +399,12 @@ bool MiniMax::calcNumSuccedors(retroAnalysisGlobalVars &retroVars)
|
|||
return falseOrStop();
|
||||
|
||||
// don't calc layers twice
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return falseOrStop();
|
||||
}
|
||||
|
||||
// ... and process succeding layers
|
||||
for (curState.layerNumber = 0; curState.layerNumber < layerStats[layerNumber].numSuccLayers; curState.layerNumber++)
|
||||
{
|
||||
for (curState.layerNumber = 0; curState.layerNumber < layerStats[layerNumber].numSuccLayers; curState.layerNumber++) {
|
||||
|
||||
// get current pred. layer
|
||||
succState.layerNumber = layerStats[layerNumber].succLayers[curState.layerNumber];
|
||||
|
@ -469,8 +427,7 @@ bool MiniMax::calcNumSuccedors(retroAnalysisGlobalVars &retroVars)
|
|||
ThreadManager::ThreadVarsArray<AddNumSuccedorsVars> tva(threadManager.getNumThreads(), AddNumSuccedorsVars(this, &retroVars, succState.layerNumber));
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeParallelLoop(addNumSuccedorsThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[succState.layerNumber].knotsInLayer - 1, 1))
|
||||
{
|
||||
switch (threadManager.executeParallelLoop(addNumSuccedorsThreadProc, tva.getPointerToArray(), tva.getSizeOfArray(), TM_SCHEDULE_STATIC, 0, layerStats[succState.layerNumber].knotsInLayer - 1, 1)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -518,8 +475,7 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
|
|||
|
||||
// print status
|
||||
ansVars->statesProcessed++;
|
||||
if (ansVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (ansVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(2, m, " Already processed " << m->numStatesProcessed << " of " << m->layerStats[curState.layerNumber].knotsInLayer << " states");
|
||||
}
|
||||
|
@ -530,8 +486,7 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
|
|||
return TM_RETURN_VALUE_OK;
|
||||
|
||||
// set current selected situation
|
||||
if (!m->setSituation(ansVars->curThreadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (!m->setSituation(ansVars->curThreadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
PRINT(0, m, "ERROR: setSituation() returned false!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
|
@ -540,16 +495,14 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
|
|||
m->getPredecessors(ansVars->curThreadNo, &amountOfPred, ansVars->predVars);
|
||||
|
||||
// iteration
|
||||
for (curPred = 0; curPred < amountOfPred; curPred++)
|
||||
{
|
||||
for (curPred = 0; curPred < amountOfPred; curPred++) {
|
||||
|
||||
// current predecessor
|
||||
predState.layerNumber = ansVars->predVars[curPred].predLayerNumbers;
|
||||
predState.stateNumber = ansVars->predVars[curPred].predStateNumbers;
|
||||
|
||||
// don't calculate states from layers above yet
|
||||
for (curLayerId = 0; curLayerId < numLayersToCalculate; curLayerId++)
|
||||
{
|
||||
for (curLayerId = 0; curLayerId < numLayersToCalculate; curLayerId++) {
|
||||
if (ansVars->retroVars->layersToCalculate[curLayerId] == predState.layerNumber)
|
||||
break;
|
||||
}
|
||||
|
@ -557,8 +510,7 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
|
|||
continue;
|
||||
|
||||
// put in list (with states to be processed) if state is final
|
||||
if (!cuStateAddedToProcessQueue && (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST))
|
||||
{
|
||||
if (!cuStateAddedToProcessQueue && (curStateValue == SKV_VALUE_GAME_WON || curStateValue == SKV_VALUE_GAME_LOST)) {
|
||||
m->readPlyInfoFromDatabase(curState.layerNumber, curState.stateNumber, numPlies);
|
||||
m->addStateToProcessQueue(*ansVars->retroVars, ansVars->retroVars->thread[ansVars->curThreadNo], numPlies, &curState);
|
||||
cuStateAddedToProcessQueue = true;
|
||||
|
@ -570,17 +522,13 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
|
|||
long mask = 0x000000ff << numBitsToShift;
|
||||
long curCountLong, newCountLong;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
curCountLong = *pCountValue;
|
||||
countValue = (CountArrayVarType)((curCountLong & mask) >> numBitsToShift);
|
||||
if (countValue == 255)
|
||||
{
|
||||
if (countValue == 255) {
|
||||
PRINT(0, m, "ERROR: maximum value for Count[] reached!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
countValue++;
|
||||
newCountLong = (curCountLong & (~mask)) + (countValue << numBitsToShift);
|
||||
}
|
||||
|
@ -607,8 +555,7 @@ bool MiniMax::performRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
curCalculationActionId = MM_ACTION_PERFORM_RETRO_ANAL;
|
||||
|
||||
// process each state in the current layer
|
||||
switch (threadManager.executeInParallel(performRetroAnalysisThreadProc, (void **)&retroVars, 0))
|
||||
{
|
||||
switch (threadManager.executeInParallel(performRetroAnalysisThreadProc, (void **)&retroVars, 0)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
|
@ -621,10 +568,8 @@ bool MiniMax::performRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
}
|
||||
|
||||
// if there are still states to process, than something went wrong
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++)
|
||||
{
|
||||
if (retroVars.thread[curThreadNo].numStatesToProcess)
|
||||
{
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++) {
|
||||
if (retroVars.thread[curThreadNo].numStatesToProcess) {
|
||||
PRINT(0, this, "ERROR: There are still states to process after performing retro analysis!");
|
||||
return falseOrStop();
|
||||
}
|
||||
|
@ -632,10 +577,8 @@ bool MiniMax::performRetroAnalysis(retroAnalysisGlobalVars &retroVars)
|
|||
|
||||
// copy drawn and invalid states to ply info
|
||||
PRINT(2, this, " Copy drawn and invalid states to ply info database...");
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++)
|
||||
{
|
||||
for (curState.layerNumber = retroVars.layersToCalculate[curLayerId], curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++)
|
||||
{
|
||||
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) {
|
||||
for (curState.layerNumber = retroVars.layersToCalculate[curLayerId], curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) {
|
||||
readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
|
||||
if (curStateValue == SKV_VALUE_GAME_DRAWN)
|
||||
savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, PLYINFO_VALUE_DRAWN);
|
||||
|
@ -677,28 +620,22 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
TwoBit curStateValue; // current state value
|
||||
RetroAnalysisPredVars predVars[MAX_NUM_PREDECESSORS];
|
||||
|
||||
for (numStatesProcessed = 0, curNumPlies = 0; curNumPlies < threadVars->statesToProcess.size(); curNumPlies++)
|
||||
{
|
||||
for (numStatesProcessed = 0, curNumPlies = 0; curNumPlies < threadVars->statesToProcess.size(); curNumPlies++) {
|
||||
|
||||
// skip empty and uninitialized cyclic arrays
|
||||
if (threadVars->statesToProcess[curNumPlies] != nullptr)
|
||||
{
|
||||
if (threadVars->statesToProcess[curNumPlies] != nullptr) {
|
||||
|
||||
if (threadNo == 0)
|
||||
{
|
||||
if (threadNo == 0) {
|
||||
PRINT(0, m, " Current number of plies: " << (unsigned int)curNumPlies << "/" << threadVars->statesToProcess.size());
|
||||
for (threadCounter = 0; threadCounter < m->threadManager.getNumThreads(); threadCounter++)
|
||||
{
|
||||
for (threadCounter = 0; threadCounter < m->threadManager.getNumThreads(); threadCounter++) {
|
||||
PRINT(0, m, " States to process for thread " << threadCounter << ": " << retroVars->thread[threadCounter].numStatesToProcess);
|
||||
}
|
||||
}
|
||||
|
||||
while (threadVars->statesToProcess[curNumPlies]->takeBytes(sizeof(StateAdress), (unsigned char *)&curState))
|
||||
{
|
||||
while (threadVars->statesToProcess[curNumPlies]->takeBytes(sizeof(StateAdress), (unsigned char *)&curState)) {
|
||||
|
||||
// execution cancelled by user?
|
||||
if (m->threadManager.wasExecutionCancelled())
|
||||
{
|
||||
if (m->threadManager.wasExecutionCancelled()) {
|
||||
PRINT(0, m, "\n****************************************\nSub-thread no. " << threadNo << ": Execution cancelled by user!\n****************************************\n");
|
||||
return TM_RETURN_VALUE_EXECUTION_CANCELLED;
|
||||
}
|
||||
|
@ -707,8 +644,7 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
m->readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
|
||||
m->readPlyInfoFromDatabase(curState.layerNumber, curState.stateNumber, numPliesTillCurState);
|
||||
|
||||
if (numPliesTillCurState != curNumPlies)
|
||||
{
|
||||
if (numPliesTillCurState != curNumPlies) {
|
||||
PRINT(0, m, "ERROR: numPliesTillCurState != curNumPlies");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
|
@ -716,19 +652,16 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
// console output
|
||||
numStatesProcessed++;
|
||||
threadVars->numStatesToProcess--;
|
||||
if (numStatesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (numStatesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
for (totalNumStatesToProcess = 0, threadCounter = 0; threadCounter < m->threadManager.getNumThreads(); threadCounter++)
|
||||
{
|
||||
for (totalNumStatesToProcess = 0, threadCounter = 0; threadCounter < m->threadManager.getNumThreads(); threadCounter++) {
|
||||
totalNumStatesToProcess += retroVars->thread[threadCounter].numStatesToProcess;
|
||||
}
|
||||
PRINT(2, m, " states already processed: " << m->numStatesProcessed << " \t states still in list: " << totalNumStatesToProcess);
|
||||
}
|
||||
|
||||
// set current selected situation
|
||||
if (!m->setSituation(threadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (!m->setSituation(threadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
PRINT(0, m, "ERROR: setSituation() returned false!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
|
@ -737,16 +670,14 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
m->getPredecessors(threadNo, &amountOfPred, predVars);
|
||||
|
||||
// iteration
|
||||
for (curPred = 0; curPred < amountOfPred; curPred++)
|
||||
{
|
||||
for (curPred = 0; curPred < amountOfPred; curPred++) {
|
||||
|
||||
// current predecessor
|
||||
predState.layerNumber = predVars[curPred].predLayerNumbers;
|
||||
predState.stateNumber = predVars[curPred].predStateNumbers;
|
||||
|
||||
// don't calculate states from layers above yet
|
||||
for (curLayerId = 0; curLayerId < retroVars->layersToCalculate.size(); curLayerId++)
|
||||
{
|
||||
for (curLayerId = 0; curLayerId < retroVars->layersToCalculate.size(); curLayerId++) {
|
||||
if (retroVars->layersToCalculate[curLayerId] == predState.layerNumber)
|
||||
break;
|
||||
}
|
||||
|
@ -757,41 +688,32 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
m->readKnotValueFromDatabase(predState.layerNumber, predState.stateNumber, predStateValue);
|
||||
|
||||
// only drawn states are relevant here, since the other are already calculated
|
||||
if (predStateValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (predStateValue == SKV_VALUE_GAME_DRAWN) {
|
||||
|
||||
// if current considered state is a lost game then all predecessors are a won game
|
||||
if (curStateValue == m->skvPerspectiveMatrix[SKV_VALUE_GAME_LOST][predVars[curPred].playerToMoveChanged ? PL_TO_MOVE_CHANGED : PL_TO_MOVE_UNCHANGED])
|
||||
{
|
||||
if (curStateValue == m->skvPerspectiveMatrix[SKV_VALUE_GAME_LOST][predVars[curPred].playerToMoveChanged ? PL_TO_MOVE_CHANGED : PL_TO_MOVE_UNCHANGED]) {
|
||||
m->saveKnotValueInDatabase(predState.layerNumber, predState.stateNumber, SKV_VALUE_GAME_WON);
|
||||
m->savePlyInfoInDatabase(predState.layerNumber, predState.stateNumber, numPliesTillCurState + 1); // (requirement: curNumPlies == numPliesTillCurState)
|
||||
if (numPliesTillCurState + 1 < curNumPlies)
|
||||
{
|
||||
if (numPliesTillCurState + 1 < curNumPlies) {
|
||||
PRINT(0, m, "ERROR: Current number of plies is bigger than numPliesTillCurState + 1!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
m->addStateToProcessQueue(*retroVars, *threadVars, numPliesTillCurState + 1, &predState);
|
||||
// if current state is a won game, then this state is not an option any more for all predecessors
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// reduce count value by one
|
||||
long *pCountValue = ((long *)retroVars->countArrays[curLayerId]) + predState.stateNumber / (sizeof(long) / sizeof(CountArrayVarType));
|
||||
long numBitsToShift = sizeof(CountArrayVarType) * 8 * (predState.stateNumber % (sizeof(long) / sizeof(CountArrayVarType))); // little-endian byte-order
|
||||
long mask = 0x000000ff << numBitsToShift;
|
||||
long curCountLong, newCountLong;
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
curCountLong = *pCountValue;
|
||||
countValue = (CountArrayVarType)((curCountLong & mask) >> numBitsToShift);
|
||||
if (countValue > 0)
|
||||
{
|
||||
if (countValue > 0) {
|
||||
countValue--;
|
||||
newCountLong = (curCountLong & (~mask)) + (countValue << numBitsToShift);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PRINT(0, m, "ERROR: Count is already zero!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
|
@ -799,17 +721,14 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
|
||||
// ply info (requirement: curNumPlies == numPliesTillCurState)
|
||||
m->readPlyInfoFromDatabase(predState.layerNumber, predState.stateNumber, numPliesTillPredState);
|
||||
if (numPliesTillPredState == PLYINFO_VALUE_UNCALCULATED || numPliesTillCurState + 1 > numPliesTillPredState)
|
||||
{
|
||||
if (numPliesTillPredState == PLYINFO_VALUE_UNCALCULATED || numPliesTillCurState + 1 > numPliesTillPredState) {
|
||||
m->savePlyInfoInDatabase(predState.layerNumber, predState.stateNumber, numPliesTillCurState + 1);
|
||||
}
|
||||
|
||||
// when all successor are won states then this is a lost state (this should only be the case for one thread)
|
||||
if (countValue == 0)
|
||||
{
|
||||
if (countValue == 0) {
|
||||
m->saveKnotValueInDatabase(predState.layerNumber, predState.stateNumber, SKV_VALUE_GAME_LOST);
|
||||
if (numPliesTillCurState + 1 < curNumPlies)
|
||||
{
|
||||
if (numPliesTillCurState + 1 < curNumPlies) {
|
||||
PRINT(0, m, "ERROR: Current number of plies is bigger than numPliesTillCurState + 1!");
|
||||
return TM_RETURN_VALUE_TERMINATE_ALL_THREADS;
|
||||
}
|
||||
|
@ -836,15 +755,13 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
|
|||
bool MiniMax::addStateToProcessQueue(retroAnalysisGlobalVars &retroVars, RetroAnalysisThreadVars &threadVars, unsigned int plyNumber, StateAdress *pState)
|
||||
{
|
||||
// resize vector if too small
|
||||
if (plyNumber >= threadVars.statesToProcess.size())
|
||||
{
|
||||
if (plyNumber >= threadVars.statesToProcess.size()) {
|
||||
threadVars.statesToProcess.resize(max(plyNumber + 1, 10 * threadVars.statesToProcess.size()), nullptr);
|
||||
PRINT(4, this, " statesToProcess resized to " << threadVars.statesToProcess.size());
|
||||
}
|
||||
|
||||
// initialize cyclic array if necessary
|
||||
if (threadVars.statesToProcess[plyNumber] == nullptr)
|
||||
{
|
||||
if (threadVars.statesToProcess[plyNumber] == nullptr) {
|
||||
stringstream ssStatesToProcessFilePath;
|
||||
stringstream ssStatesToProcessPath;
|
||||
ssStatesToProcessPath << fileDirectory << (fileDirectory.size() ? "\\" : "") << "statesToProcess";
|
||||
|
@ -856,8 +773,7 @@ bool MiniMax::addStateToProcessQueue(retroAnalysisGlobalVars &retroVars, RetroAn
|
|||
}
|
||||
|
||||
// add state
|
||||
if (!threadVars.statesToProcess[plyNumber]->addBytes(sizeof(StateAdress), (unsigned char *)pState))
|
||||
{
|
||||
if (!threadVars.statesToProcess[plyNumber]->addBytes(sizeof(StateAdress), (unsigned char *)pState)) {
|
||||
PRINT(0, this, "ERROR: Cyclic list to small! numStatesToProcess:" << threadVars.numStatesToProcess);
|
||||
return falseOrStop();
|
||||
}
|
||||
|
|
|
@ -19,8 +19,7 @@ bool MiniMax::testLayer(unsigned int layerNumber)
|
|||
unsigned int returnValue;
|
||||
|
||||
// database open?
|
||||
if (hFileShortKnotValues == nullptr || hFilePlyInfo == nullptr)
|
||||
{
|
||||
if (hFileShortKnotValues == nullptr || hFilePlyInfo == nullptr) {
|
||||
PRINT(0, this, "ERROR: Database file not open!");
|
||||
return falseOrStop();
|
||||
}
|
||||
|
@ -36,8 +35,7 @@ bool MiniMax::testLayer(unsigned int layerNumber)
|
|||
curCalculatedLayer = layerNumber;
|
||||
curCalculationActionId = MM_ACTION_TESTING_LAYER;
|
||||
TestLayersVars *tlVars = new TestLayersVars[threadManager.getNumThreads()];
|
||||
for (curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++) {
|
||||
tlVars[curThreadNo].curThreadNo = curThreadNo;
|
||||
tlVars[curThreadNo].pMiniMax = this;
|
||||
tlVars[curThreadNo].layerNumber = layerNumber;
|
||||
|
@ -49,26 +47,21 @@ bool MiniMax::testLayer(unsigned int layerNumber)
|
|||
|
||||
// process each state in the current layer
|
||||
returnValue = threadManager.executeParallelLoop(testLayerThreadProc, (void *)tlVars, sizeof(TestLayersVars), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1);
|
||||
switch (returnValue)
|
||||
{
|
||||
switch (returnValue) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
// reduce and delete thread specific data
|
||||
for (numStatesProcessed = 0, curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++)
|
||||
{
|
||||
for (numStatesProcessed = 0, curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++) {
|
||||
numStatesProcessed += tlVars[curThreadNo].statesProcessed;
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].subValueInDatabase);
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].hasCurPlayerChanged);
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].subPlyInfos);
|
||||
}
|
||||
SAFE_DELETE_ARRAY(tlVars);
|
||||
if (returnValue == TM_RETURN_VALUE_EXECUTION_CANCELLED)
|
||||
{
|
||||
if (returnValue == TM_RETURN_VALUE_EXECUTION_CANCELLED) {
|
||||
PRINT(0, this, "Main thread: Execution cancelled by user");
|
||||
return false; // ... better would be to return a cancel-specific value
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -78,14 +71,11 @@ bool MiniMax::testLayer(unsigned int layerNumber)
|
|||
}
|
||||
|
||||
// layer is not ok
|
||||
if (numStatesProcessed < layerStats[layerNumber].knotsInLayer)
|
||||
{
|
||||
if (numStatesProcessed < layerStats[layerNumber].knotsInLayer) {
|
||||
PRINT(0, this, "DATABASE ERROR IN LAYER " << layerNumber);
|
||||
return falseOrStop();
|
||||
// layer is ok
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PRINT(1, this, " TEST PASSED !" << endl
|
||||
<< endl);
|
||||
return true;
|
||||
|
@ -124,8 +114,7 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
|
||||
// output
|
||||
tlVars->statesProcessed++;
|
||||
if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(0, m, m->numStatesProcessed << " states of " << m->layerStats[layerNumber].knotsInLayer << " tested");
|
||||
}
|
||||
|
@ -135,24 +124,19 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
m->readPlyInfoFromDatabase(layerNumber, stateNumber, numPliesTillCurState);
|
||||
|
||||
// prepare the situation
|
||||
if (!m->setSituation(threadNo, layerNumber, stateNumber))
|
||||
{
|
||||
if (!m->setSituation(threadNo, layerNumber, stateNumber)) {
|
||||
|
||||
// when situation cannot be constructed then state must be marked as invalid in database
|
||||
if (shortValueInDatabase != SKV_VALUE_INVALID || numPliesTillCurState != PLYINFO_VALUE_INVALID)
|
||||
{
|
||||
if (shortValueInDatabase != SKV_VALUE_INVALID || numPliesTillCurState != PLYINFO_VALUE_INVALID) {
|
||||
PRINT(0, m, "ERROR: DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Could not set situation, but value is not invalid.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return TM_RETURN_VALUE_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// debug information
|
||||
if (m->verbosity > 5)
|
||||
{
|
||||
if (m->verbosity > 5) {
|
||||
PRINT(5, m, "layer: " << layerNumber << " state: " << stateNumber);
|
||||
m->printBoard(threadNo, shortValueInDatabase);
|
||||
}
|
||||
|
@ -162,30 +146,24 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
idPossibility = m->getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities);
|
||||
|
||||
// unable to move
|
||||
if (numPossibilities == 0)
|
||||
{
|
||||
if (numPossibilities == 0) {
|
||||
|
||||
// get ingame value
|
||||
m->getValueOfSituation(threadNo, floatValueInGame, shortValueInGame);
|
||||
|
||||
// compare database with game
|
||||
if (shortValueInDatabase != shortValueInGame || numPliesTillCurState != 0)
|
||||
{
|
||||
if (shortValueInDatabase != shortValueInGame || numPliesTillCurState != 0) {
|
||||
PRINT(0, m, "ERROR: DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Number of possibilities is zero, but knot value is not invalid or ply info equal zero.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
if (shortValueInDatabase == SKV_VALUE_INVALID)
|
||||
{
|
||||
if (shortValueInDatabase == SKV_VALUE_INVALID) {
|
||||
PRINT(0, m, "ERROR: DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Number of possibilities is zero, but knot value is invalid.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// check each possible move
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
|
||||
// move
|
||||
m->move(threadNo, idPossibility[i], isOpponentLevel, &pBackup, pPossibilities);
|
||||
|
@ -196,15 +174,13 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
hasCurPlayerChanged[i] = (m->getOpponentLevel(threadNo) == true);
|
||||
|
||||
// debug information
|
||||
if (m->verbosity > 5)
|
||||
{
|
||||
if (m->verbosity > 5) {
|
||||
PRINT(5, m, "layer: " << tmpLayerNumber << " state: " << tmpStateNumber << " value: " << (int)subValueInDatabase[i]);
|
||||
m->printBoard(threadNo, subValueInDatabase[i]);
|
||||
}
|
||||
|
||||
// if layer or state number is invalid then value of testes state must be invalid
|
||||
if (invalidLayerOrStateNumber && shortValueInDatabase != SKV_VALUE_INVALID)
|
||||
{
|
||||
if (invalidLayerOrStateNumber && shortValueInDatabase != SKV_VALUE_INVALID) {
|
||||
PRINT(0, m, "ERROR: DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Succeding state has invalid layer (" << tmpLayerNumber << ")or state number (" << tmpStateNumber << "), but tested state is not marked as invalid.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -216,50 +192,39 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
}
|
||||
|
||||
// value possible?
|
||||
switch (shortValueInDatabase)
|
||||
{
|
||||
switch (shortValueInDatabase) {
|
||||
case SKV_VALUE_GAME_LOST:
|
||||
|
||||
// all possible moves must be lost for the current player or won for the opponent
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_INVALID)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_INVALID) {
|
||||
PRINT(0, m, "ERROR: DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": All possible moves must be lost for the current player or won for the opponent");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
}
|
||||
// not all options can be invalid
|
||||
for (j = 0, i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
if (subValueInDatabase[i] == SKV_VALUE_INVALID)
|
||||
{
|
||||
for (j = 0, i = 0; i < numPossibilities; i++) {
|
||||
if (subValueInDatabase[i] == SKV_VALUE_INVALID) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j == numPossibilities)
|
||||
{
|
||||
if (j == numPossibilities) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ". Not all options can be invalid");
|
||||
}
|
||||
// ply info must be max(subPlyInfos[]+1)
|
||||
max = 0;
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
if (subValueInDatabase[i] == ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST))
|
||||
{
|
||||
if (subPlyInfos[i] + 1 > max)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
if (subValueInDatabase[i] == ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST)) {
|
||||
if (subPlyInfos[i] + 1 > max) {
|
||||
max = subPlyInfos[i] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numPliesTillCurState > PLYINFO_VALUE_DRAWN)
|
||||
{
|
||||
if (numPliesTillCurState > PLYINFO_VALUE_DRAWN) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Knot value is LOST, but numPliesTillCurState is bigger than PLYINFO_MAX_VALUE.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
if (numPliesTillCurState != max)
|
||||
{
|
||||
if (numPliesTillCurState != max) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Number of needed plies is not maximal for LOST state.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -268,37 +233,30 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
case SKV_VALUE_GAME_WON:
|
||||
|
||||
// at least one possible move must be lost for the opponent or won for the current player
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
// if (subValueInDatabase[i] == SKV_VALUE_INVALID) { PRINT(0,m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": At least one possible move must be lost for the opponent or won for the current player. But subValueInDatabase[i] == SKV_VALUE_INVALID."); goto errorInDatabase; }
|
||||
if (subValueInDatabase[i] == ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_LOST : SKV_VALUE_GAME_WON))
|
||||
i = numPossibilities;
|
||||
}
|
||||
if (i == numPossibilities)
|
||||
{
|
||||
if (i == numPossibilities) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": At least one possible move must be lost for the opponent or won for the current player.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
||||
// ply info must be min(subPlyInfos[]+1)
|
||||
min = PLYINFO_VALUE_DRAWN;
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
if (subValueInDatabase[i] == ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_LOST : SKV_VALUE_GAME_WON))
|
||||
{
|
||||
if (subPlyInfos[i] + 1 < min)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
if (subValueInDatabase[i] == ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_LOST : SKV_VALUE_GAME_WON)) {
|
||||
if (subPlyInfos[i] + 1 < min) {
|
||||
min = subPlyInfos[i] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numPliesTillCurState > PLYINFO_VALUE_DRAWN)
|
||||
{
|
||||
if (numPliesTillCurState > PLYINFO_VALUE_DRAWN) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Knot value is WON, but numPliesTillCurState is bigger than PLYINFO_MAX_VALUE.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
if (numPliesTillCurState != min)
|
||||
{
|
||||
if (numPliesTillCurState != min) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Number of needed plies is not minimal for WON state.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -307,11 +265,9 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
case SKV_VALUE_GAME_DRAWN:
|
||||
|
||||
// all possible moves must be won for the opponent, lost for the current player or drawn
|
||||
for (j = 0, i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
for (j = 0, i = 0; i < numPossibilities; i++) {
|
||||
// if (subValueInDatabase[i] == SKV_VALUE_INVALID) { PRINT(0,m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": All possible moves must be won for the opponent, lost for the current player or drawn. But subValueInDatabase[i] == SKV_VALUE_INVALID."); goto errorInDatabase; }
|
||||
if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_GAME_DRAWN && subValueInDatabase[i] != SKV_VALUE_INVALID)
|
||||
{
|
||||
if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_GAME_DRAWN && subValueInDatabase[i] != SKV_VALUE_INVALID) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": All possible moves must be won for the opponent, lost for the current player or drawn.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -320,15 +276,13 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
}
|
||||
|
||||
// at least one succeding state must be drawn
|
||||
if (j == 0)
|
||||
{
|
||||
if (j == 0) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": At least one succeding state must be drawn.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
||||
// ply info must also be drawn
|
||||
if (numPliesTillCurState != PLYINFO_VALUE_DRAWN)
|
||||
{
|
||||
if (numPliesTillCurState != PLYINFO_VALUE_DRAWN) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Knot value is drawn but ply info is not!");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -336,19 +290,16 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
|
|||
|
||||
case SKV_VALUE_INVALID:
|
||||
// if setSituation() returned true but state value is invalid, then all following states must be invalid
|
||||
for (i = 0; i < numPossibilities; i++)
|
||||
{
|
||||
for (i = 0; i < numPossibilities; i++) {
|
||||
if (subValueInDatabase[i] != SKV_VALUE_INVALID)
|
||||
break;
|
||||
}
|
||||
if (i != numPossibilities)
|
||||
{
|
||||
if (i != numPossibilities) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": If setSituation() returned true but state value is invalid, then all following states must be invalid.");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
// ply info must also be invalid
|
||||
if (numPliesTillCurState != PLYINFO_VALUE_INVALID)
|
||||
{
|
||||
if (numPliesTillCurState != PLYINFO_VALUE_INVALID) {
|
||||
PRINT(0, m, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber << ": Knot value is invalid but ply info is not!");
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
@ -409,8 +360,7 @@ bool MiniMax::testSetSituationAndGetPoss(unsigned int layerNumber)
|
|||
numStatesProcessed = 0;
|
||||
curCalculationActionId = MM_ACTION_TESTING_LAYER;
|
||||
TestLayersVars *tlVars = new TestLayersVars[threadManager.getNumThreads()];
|
||||
for (curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++) {
|
||||
tlVars[curThreadNo].curThreadNo = curThreadNo;
|
||||
tlVars[curThreadNo].pMiniMax = this;
|
||||
tlVars[curThreadNo].layerNumber = layerNumber;
|
||||
|
@ -422,26 +372,21 @@ bool MiniMax::testSetSituationAndGetPoss(unsigned int layerNumber)
|
|||
|
||||
// process each state in the current layer
|
||||
returnValue = threadManager.executeParallelLoop(testSetSituationThreadProc, (void *)tlVars, sizeof(TestLayersVars), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1);
|
||||
switch (returnValue)
|
||||
{
|
||||
switch (returnValue) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
case TM_RETURN_VALUE_EXECUTION_CANCELLED:
|
||||
// reduce and delete thread specific data
|
||||
for (numStatesProcessed = 0, curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++)
|
||||
{
|
||||
for (numStatesProcessed = 0, curThreadNo = 0; curThreadNo < threadManager.getNumThreads(); curThreadNo++) {
|
||||
numStatesProcessed += tlVars[curThreadNo].statesProcessed;
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].subValueInDatabase);
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].hasCurPlayerChanged);
|
||||
SAFE_DELETE_ARRAY(tlVars[curThreadNo].subPlyInfos);
|
||||
}
|
||||
SAFE_DELETE_ARRAY(tlVars);
|
||||
if (returnValue == TM_RETURN_VALUE_EXECUTION_CANCELLED)
|
||||
{
|
||||
if (returnValue == TM_RETURN_VALUE_EXECUTION_CANCELLED) {
|
||||
PRINT(0, this, "Main thread: Execution cancelled by user");
|
||||
return false; // ... better would be to return a cancel-specific value
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -451,14 +396,11 @@ bool MiniMax::testSetSituationAndGetPoss(unsigned int layerNumber)
|
|||
}
|
||||
|
||||
// layer is not ok
|
||||
if (numStatesProcessed < layerStats[layerNumber].knotsInLayer)
|
||||
{
|
||||
if (numStatesProcessed < layerStats[layerNumber].knotsInLayer) {
|
||||
PRINT(0, this, "DATABASE ERROR IN LAYER " << layerNumber);
|
||||
return falseOrStop();
|
||||
// layer is ok
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
PRINT(1, this, " TEST PASSED !" << endl
|
||||
<< endl);
|
||||
return true;
|
||||
|
@ -488,19 +430,15 @@ DWORD MiniMax::testSetSituationThreadProc(void *pParameter, int index)
|
|||
|
||||
// output
|
||||
tlVars->statesProcessed++;
|
||||
if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0)
|
||||
{
|
||||
if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
|
||||
m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
|
||||
PRINT(0, m, m->numStatesProcessed << " states of " << m->layerStats[curState.layerNumber].knotsInLayer << " tested");
|
||||
}
|
||||
|
||||
// set state
|
||||
if (m->setSituation(tlVars->curThreadNo, curState.layerNumber, curState.stateNumber))
|
||||
{
|
||||
if (m->setSituation(tlVars->curThreadNo, curState.layerNumber, curState.stateNumber)) {
|
||||
m->getValueOfSituation(tlVars->curThreadNo, floatValue, shortKnotValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
shortKnotValue = SKV_VALUE_INVALID;
|
||||
}
|
||||
|
||||
|
@ -508,26 +446,20 @@ DWORD MiniMax::testSetSituationThreadProc(void *pParameter, int index)
|
|||
idPossibility = m->getPossibilities(tlVars->curThreadNo, &knot.numPossibilities, &knot.isOpponentLevel, &pPossibilities);
|
||||
|
||||
// unable to move
|
||||
if (knot.numPossibilities == 0)
|
||||
{
|
||||
if (shortKnotValue == SKV_VALUE_GAME_DRAWN)
|
||||
{
|
||||
if (knot.numPossibilities == 0) {
|
||||
if (shortKnotValue == SKV_VALUE_GAME_DRAWN) {
|
||||
PRINT(0, m, "ERROR: Layer " << curState.layerNumber << " and state " << curState.stateNumber << ". setSituation() returned true, although getPossibilities() yields no possible moves.");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
// moving is possible
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shortKnotValue == SKV_VALUE_INVALID)
|
||||
{
|
||||
} else {
|
||||
if (shortKnotValue == SKV_VALUE_INVALID) {
|
||||
PRINT(0, m, "ERROR: Moved from layer " << curState.layerNumber << " and state " << curState.stateNumber << " setSituation() returned false, although getPossibilities() yields some possible moves.");
|
||||
return m->falseOrStop();
|
||||
}
|
||||
|
||||
// check each possibility
|
||||
for (curPoss = 0; curPoss < knot.numPossibilities; curPoss++)
|
||||
{
|
||||
for (curPoss = 0; curPoss < knot.numPossibilities; curPoss++) {
|
||||
|
||||
// move
|
||||
m->move(tlVars->curThreadNo, idPossibility[curPoss], knot.isOpponentLevel, &pBackup, pPossibilities);
|
||||
|
@ -541,8 +473,7 @@ DWORD MiniMax::testSetSituationThreadProc(void *pParameter, int index)
|
|||
m->undo(tlVars->curThreadNo, idPossibility[curPoss], knot.isOpponentLevel, pBackup, pPossibilities);
|
||||
|
||||
// state reached by move() must not be invalid
|
||||
if (!m->setSituation(tlVars->curThreadNo, subState.layerNumber, subState.stateNumber))
|
||||
{
|
||||
if (!m->setSituation(tlVars->curThreadNo, subState.layerNumber, subState.stateNumber)) {
|
||||
PRINT(0, m, "ERROR: Moved from layer " << curState.layerNumber << " and state " << curState.stateNumber << " to invalid situation layer " << curState.layerNumber << " and state " << curState.stateNumber);
|
||||
return m->falseOrStop();
|
||||
}
|
||||
|
@ -575,16 +506,14 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
|
|||
unsigned int i;
|
||||
|
||||
// database open?
|
||||
if (hFileShortKnotValues == nullptr || hFilePlyInfo == nullptr)
|
||||
{
|
||||
if (hFileShortKnotValues == nullptr || hFilePlyInfo == nullptr) {
|
||||
PRINT(0, this, "ERROR: Database files not open!");
|
||||
layerNumber = 0;
|
||||
goto errorInDatabase;
|
||||
}
|
||||
|
||||
// layer completed ?
|
||||
if (!layerStats[layerNumber].layerIsCompletedAndInFile)
|
||||
{
|
||||
if (!layerStats[layerNumber].layerIsCompletedAndInFile) {
|
||||
PRINT(0, this, "ERROR: Layer not in file!");
|
||||
layerNumber = 0;
|
||||
goto errorInDatabase;
|
||||
|
@ -595,8 +524,7 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
|
|||
PRINT(1, this, (getOutputInformation(layerNumber)));
|
||||
skvfHeader.completed = false;
|
||||
|
||||
for (layerInDatabase = false, stateNumber = 0; stateNumber < layerStats[layerNumber].knotsInLayer; stateNumber++)
|
||||
{
|
||||
for (layerInDatabase = false, stateNumber = 0; stateNumber < layerStats[layerNumber].knotsInLayer; stateNumber++) {
|
||||
|
||||
// output
|
||||
if (stateNumber % OUTPUT_EVERY_N_STATES == 0)
|
||||
|
@ -607,8 +535,7 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
|
|||
readPlyInfoFromDatabase(layerNumber, stateNumber, numPliesTillCurState);
|
||||
|
||||
// prepare the situation
|
||||
if (!setSituation(threadNo, layerNumber, stateNumber))
|
||||
{
|
||||
if (!setSituation(threadNo, layerNumber, stateNumber)) {
|
||||
|
||||
// when situation cannot be constructed then state must be marked as invalid in database
|
||||
if (shortValueInDatabase != SKV_VALUE_INVALID || numPliesTillCurState != PLYINFO_VALUE_INVALID)
|
||||
|
@ -621,14 +548,12 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
|
|||
getSymStateNumWithDoubles(threadNo, &numSymmetricStates, &symStateNumbers);
|
||||
|
||||
// save value for all symmetric states
|
||||
for (i = 0; i < numSymmetricStates; i++)
|
||||
{
|
||||
for (i = 0; i < numSymmetricStates; i++) {
|
||||
|
||||
readKnotValueFromDatabase(layerNumber, symStateNumbers[i], shortValueOfSymState);
|
||||
readPlyInfoFromDatabase(layerNumber, symStateNumbers[i], numPliesTillSymState);
|
||||
|
||||
if (shortValueOfSymState != shortValueInDatabase || numPliesTillCurState != numPliesTillSymState)
|
||||
{
|
||||
if (shortValueOfSymState != shortValueInDatabase || numPliesTillCurState != numPliesTillSymState) {
|
||||
|
||||
PRINT(2, this, "current tested state " << stateNumber << " has value " << (int)shortValueInDatabase);
|
||||
setSituation(threadNo, layerNumber, stateNumber);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -62,12 +62,9 @@ void Position::beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int c
|
|||
initialField.createBoard();
|
||||
|
||||
// calc beginning player
|
||||
if (currentPlayer == field.playerOne || currentPlayer == field.playerTwo)
|
||||
{
|
||||
if (currentPlayer == field.playerOne || currentPlayer == field.playerTwo) {
|
||||
beginningPlayer = currentPlayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
beginningPlayer = (rand() % 2) ? field.playerOne : field.playerTwo;
|
||||
}
|
||||
field.curPlayer->id = beginningPlayer;
|
||||
|
@ -106,10 +103,8 @@ void Position::setUpCalcPossibleMoves(Player *player)
|
|||
// locals
|
||||
unsigned int i, j, k, movingDirection;
|
||||
|
||||
for (player->numPossibleMoves = 0, i = 0; i < fieldStruct::size; i++)
|
||||
{
|
||||
for (j = 0; j < fieldStruct::size; j++)
|
||||
{
|
||||
for (player->numPossibleMoves = 0, i = 0; i < fieldStruct::size; i++) {
|
||||
for (j = 0; j < fieldStruct::size; j++) {
|
||||
|
||||
// is stone from player ?
|
||||
if (field.board[i] != player->id)
|
||||
|
@ -120,8 +115,7 @@ void Position::setUpCalcPossibleMoves(Player *player)
|
|||
continue;
|
||||
|
||||
// when current player has only 3 stones he is allowed to spring his stone
|
||||
if (player->numStones > 3 || field.settingPhase)
|
||||
{
|
||||
if (player->numStones > 3 || field.settingPhase) {
|
||||
|
||||
// determine moving direction
|
||||
for (k = 0, movingDirection = 4; k < 4; k++)
|
||||
|
@ -149,8 +143,7 @@ void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeig
|
|||
int rowOwner = field.board[stone];
|
||||
|
||||
// mill closed ?
|
||||
if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner)
|
||||
{
|
||||
if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner) {
|
||||
|
||||
field.stonePartOfMill[stone]++;
|
||||
field.stonePartOfMill[firstNeighbour]++;
|
||||
|
@ -195,8 +188,7 @@ bool Position::put_piece(unsigned int pos, int player)
|
|||
field.stonePartOfMill[i] = 0;
|
||||
|
||||
// go in every direction
|
||||
for (i = 0; i < fieldStruct::size; i++)
|
||||
{
|
||||
for (i = 0; i < fieldStruct::size; i++) {
|
||||
setUpSetWarningAndMill(i, field.neighbour[i][0][0], field.neighbour[i][0][1]);
|
||||
setUpSetWarningAndMill(i, field.neighbour[i][1][0], field.neighbour[i][1][1]);
|
||||
}
|
||||
|
@ -206,8 +198,7 @@ bool Position::put_piece(unsigned int pos, int player)
|
|||
field.stonePartOfMill[i] /= 3;
|
||||
|
||||
// count completed mills
|
||||
for (i = 0; i < fieldStruct::size; i++)
|
||||
{
|
||||
for (i = 0; i < fieldStruct::size; i++) {
|
||||
if (field.board[i] == field.curPlayer->id)
|
||||
numberOfMillsCurrentPlayer += field.stonePartOfMill[i];
|
||||
else
|
||||
|
@ -217,15 +208,12 @@ bool Position::put_piece(unsigned int pos, int player)
|
|||
numberOfMillsOpponentPlayer /= 3;
|
||||
|
||||
// stonesSet & numStonesMissing
|
||||
if (field.settingPhase)
|
||||
{
|
||||
if (field.settingPhase) {
|
||||
// ... This calculation is not correct! It is possible that some mills did not cause a stone removal.
|
||||
field.curPlayer->numStonesMissing = numberOfMillsOpponentPlayer;
|
||||
field.oppPlayer->numStonesMissing = numberOfMillsCurrentPlayer - field.stoneMustBeRemoved;
|
||||
field.stonesSet = field.curPlayer->numStones + field.oppPlayer->numStones + field.curPlayer->numStonesMissing + field.oppPlayer->numStonesMissing;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
field.stonesSet = 18;
|
||||
field.curPlayer->numStonesMissing = 9 - field.curPlayer->numStones;
|
||||
field.oppPlayer->numStonesMissing = 9 - field.oppPlayer->numStones;
|
||||
|
@ -269,8 +257,7 @@ bool Position::getField(int *pField)
|
|||
if (moveLogFrom == nullptr)
|
||||
return false;
|
||||
|
||||
for (index = 0; index < field.size; index++)
|
||||
{
|
||||
for (index = 0; index < field.size; index++) {
|
||||
if (field.warnings[index] != field.noWarning)
|
||||
pField[index] = (int)field.warnings[index];
|
||||
else
|
||||
|
@ -290,8 +277,7 @@ void Position::getLog(unsigned int &numMovesDone, unsigned int *from, unsigned i
|
|||
|
||||
numMovesDone = movesDone;
|
||||
|
||||
for (index = 0; index < movesDone; index++)
|
||||
{
|
||||
for (index = 0; index < movesDone; index++) {
|
||||
from[index] = moveLogFrom[index];
|
||||
to[index] = moveLogTo[index];
|
||||
}
|
||||
|
@ -340,12 +326,10 @@ bool Position::isOpponentPlayerHuman()
|
|||
//-----------------------------------------------------------------------------
|
||||
void Position::setAI(int player, MillAI *AI)
|
||||
{
|
||||
if (player == field.playerOne)
|
||||
{
|
||||
if (player == field.playerOne) {
|
||||
playerOneAI = AI;
|
||||
}
|
||||
if (player == field.playerTwo)
|
||||
{
|
||||
if (player == field.playerTwo) {
|
||||
playerTwoAI = AI;
|
||||
}
|
||||
}
|
||||
|
@ -378,15 +362,11 @@ void Position::getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo)
|
|||
theField.createBoard();
|
||||
field.copyBoard(&theField);
|
||||
|
||||
if ((field.settingPhase || field.curPlayer->numPossibleMoves > 0) && winner == 0)
|
||||
{
|
||||
if (field.curPlayer->id == field.playerOne)
|
||||
{
|
||||
if ((field.settingPhase || field.curPlayer->numPossibleMoves > 0) && winner == 0) {
|
||||
if (field.curPlayer->id == field.playerOne) {
|
||||
if (playerOneAI != nullptr)
|
||||
playerOneAI->play(&theField, pushFrom, pushTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (playerTwoAI != nullptr)
|
||||
playerTwoAI->play(&theField, pushFrom, pushTo);
|
||||
}
|
||||
|
@ -419,8 +399,7 @@ bool Position::isNormalMovePossible(unsigned int from, unsigned int to, Player *
|
|||
return false;
|
||||
|
||||
// when current player has only 3 stones he is allowed to spring his stone
|
||||
if (player->numStones > 3 || field.settingPhase)
|
||||
{
|
||||
if (player->numStones > 3 || field.settingPhase) {
|
||||
|
||||
// determine moving direction
|
||||
for (i = 0, movingDirection = 4; i < 4; i++)
|
||||
|
@ -452,12 +431,9 @@ void Position::calcPossibleMoves(Player *player)
|
|||
player->posFrom[i] = field.size;
|
||||
|
||||
// calc
|
||||
for (player->numPossibleMoves = 0, i = 0; i < field.size; i++)
|
||||
{
|
||||
for (j = 0; j < field.size; j++)
|
||||
{
|
||||
if (isNormalMovePossible(i, j, player))
|
||||
{
|
||||
for (player->numPossibleMoves = 0, i = 0; i < field.size; i++) {
|
||||
for (j = 0; j < field.size; j++) {
|
||||
if (isNormalMovePossible(i, j, player)) {
|
||||
player->posFrom[player->numPossibleMoves] = i;
|
||||
player->posTo[player->numPossibleMoves] = j;
|
||||
player->numPossibleMoves++;
|
||||
|
@ -466,10 +442,8 @@ void Position::calcPossibleMoves(Player *player)
|
|||
}
|
||||
|
||||
// stoneMoveAble
|
||||
for (i = 0; i < field.size; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < field.size; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (field.board[i] == player->id)
|
||||
field.stoneMoveAble[i][j] = isNormalMovePossible(i, field.connectedSquare[i][j], player);
|
||||
else
|
||||
|
@ -489,8 +463,7 @@ void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour
|
|||
unsigned int rowOwnerWarning = (rowOwner == field.playerOne) ? field.playerOneWarning : field.playerTwoWarning;
|
||||
|
||||
// mill closed ?
|
||||
if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner)
|
||||
{
|
||||
if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner) {
|
||||
|
||||
field.stonePartOfMill[stone]++;
|
||||
field.stonePartOfMill[firstNeighbour]++;
|
||||
|
@ -524,8 +497,7 @@ void Position::updateMillsAndWarnings(unsigned int newStone)
|
|||
field.stoneMustBeRemoved = 0;
|
||||
|
||||
// go in every direction
|
||||
for (i = 0; i < field.size; i++)
|
||||
{
|
||||
for (i = 0; i < field.size; i++) {
|
||||
|
||||
setWarningAndMill(i, field.neighbour[i][0][0], field.neighbour[i][0][1], i == newStone);
|
||||
setWarningAndMill(i, field.neighbour[i][1][0], field.neighbour[i][1][1], i == newStone);
|
||||
|
@ -558,8 +530,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
|
|||
return false;
|
||||
|
||||
// handle the remove of a stone
|
||||
if (field.stoneMustBeRemoved)
|
||||
{
|
||||
if (field.stoneMustBeRemoved) {
|
||||
|
||||
// parameter ok ?
|
||||
if (pushFrom >= field.size)
|
||||
|
@ -605,9 +576,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
|
|||
return true;
|
||||
|
||||
// handle setting phase
|
||||
}
|
||||
else if (field.settingPhase)
|
||||
{
|
||||
} else if (field.settingPhase) {
|
||||
|
||||
// parameter ok ?
|
||||
if (pushTo >= field.size)
|
||||
|
@ -648,9 +617,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
|
|||
return true;
|
||||
|
||||
// normal move
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
// is move possible ?
|
||||
if (!isNormalMovePossible(pushFrom, pushTo, field.curPlayer))
|
||||
|
@ -713,63 +680,51 @@ bool Position::compareWithField(fieldStruct *compareField)
|
|||
unsigned int i, j;
|
||||
bool ret = true;
|
||||
|
||||
if (!comparePlayers(field.curPlayer, compareField->curPlayer))
|
||||
{
|
||||
if (!comparePlayers(field.curPlayer, compareField->curPlayer)) {
|
||||
cout << "error - curPlayer differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (!comparePlayers(field.oppPlayer, compareField->oppPlayer))
|
||||
{
|
||||
if (!comparePlayers(field.oppPlayer, compareField->oppPlayer)) {
|
||||
cout << "error - oppPlayer differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (field.stonesSet != compareField->stonesSet)
|
||||
{
|
||||
if (field.stonesSet != compareField->stonesSet) {
|
||||
cout << "error - stonesSet differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (field.settingPhase != compareField->settingPhase)
|
||||
{
|
||||
if (field.settingPhase != compareField->settingPhase) {
|
||||
cout << "error - settingPhase differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (field.stoneMustBeRemoved != compareField->stoneMustBeRemoved)
|
||||
{
|
||||
if (field.stoneMustBeRemoved != compareField->stoneMustBeRemoved) {
|
||||
cout << "error - stoneMustBeRemoved differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
for (i = 0; i < field.size; i++)
|
||||
{
|
||||
for (i = 0; i < field.size; i++) {
|
||||
|
||||
if (field.board[i] != compareField->board[i])
|
||||
{
|
||||
if (field.board[i] != compareField->board[i]) {
|
||||
cout << "error - board[] differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (field.warnings[i] != compareField->warnings[i])
|
||||
{
|
||||
if (field.warnings[i] != compareField->warnings[i]) {
|
||||
cout << "error - warnings[] differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (field.stonePartOfMill[i] != compareField->stonePartOfMill[i])
|
||||
{
|
||||
if (field.stonePartOfMill[i] != compareField->stonePartOfMill[i]) {
|
||||
cout << "error - stonePart[] differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (j = 0; j < 4; j++) {
|
||||
|
||||
if (field.connectedSquare[i][j] != compareField->connectedSquare[i][j])
|
||||
{
|
||||
if (field.connectedSquare[i][j] != compareField->connectedSquare[i][j]) {
|
||||
cout << "error - connectedSquare[] differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
// if (board.stoneMoveAble[i][j] != compareField->stoneMoveAble[i][j]) { cout << "error - stoneMoveAble differs!" << endl; ret = false; }
|
||||
if (field.neighbour[i][j / 2][j % 2] != compareField->neighbour[i][j / 2][j % 2])
|
||||
{
|
||||
if (field.neighbour[i][j / 2][j % 2] != compareField->neighbour[i][j / 2][j % 2]) {
|
||||
cout << "error - neighbour differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
|
@ -788,28 +743,23 @@ bool Position::comparePlayers(Player *playerA, Player *playerB)
|
|||
// unsigned int i;
|
||||
bool ret = true;
|
||||
|
||||
if (playerA->numStonesMissing != playerB->numStonesMissing)
|
||||
{
|
||||
if (playerA->numStonesMissing != playerB->numStonesMissing) {
|
||||
cout << "error - numStonesMissing differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (playerA->numStones != playerB->numStones)
|
||||
{
|
||||
if (playerA->numStones != playerB->numStones) {
|
||||
cout << "error - numStones differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (playerA->id != playerB->id)
|
||||
{
|
||||
if (playerA->id != playerB->id) {
|
||||
cout << "error - id differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (playerA->warning != playerB->warning)
|
||||
{
|
||||
if (playerA->warning != playerB->warning) {
|
||||
cout << "error - warning differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
if (playerA->numPossibleMoves != playerB->numPossibleMoves)
|
||||
{
|
||||
if (playerA->numPossibleMoves != playerB->numPossibleMoves) {
|
||||
cout << "error - numPossibleMoves differs!" << endl;
|
||||
ret = false;
|
||||
}
|
||||
|
@ -843,12 +793,10 @@ void Position::undo_move(void)
|
|||
unsigned int i;
|
||||
|
||||
// at least one move must be done
|
||||
if (movesDone)
|
||||
{
|
||||
if (movesDone) {
|
||||
|
||||
// make backup of log
|
||||
for (i = 0; i < movesDone; i++)
|
||||
{
|
||||
for (i = 0; i < movesDone; i++) {
|
||||
moveLogFrom_bak[i] = moveLogFrom[i];
|
||||
moveLogTo_bak[i] = moveLogTo[i];
|
||||
}
|
||||
|
@ -859,8 +807,7 @@ void Position::undo_move(void)
|
|||
movesDone = 0;
|
||||
|
||||
// and play again
|
||||
for (i = 0; i < movesDone_bak - 1; i++)
|
||||
{
|
||||
for (i = 0; i < movesDone_bak - 1; i++) {
|
||||
do_move(moveLogFrom_bak[i], moveLogTo_bak[i]);
|
||||
}
|
||||
}
|
||||
|
@ -876,13 +823,10 @@ void Position::undo_move(void)
|
|||
//-----------------------------------------------------------------------------
|
||||
void Position::calcNumberOfRestingStones(int &numWhiteStonesResting, int &numBlackStonesResting)
|
||||
{
|
||||
if (getCurrentPlayer() == fieldStruct::playerTwo)
|
||||
{
|
||||
if (getCurrentPlayer() == fieldStruct::playerTwo) {
|
||||
numWhiteStonesResting = fieldStruct::numStonesPerPlayer - field.curPlayer->numStonesMissing - field.curPlayer->numStones;
|
||||
numBlackStonesResting = fieldStruct::numStonesPerPlayer - field.oppPlayer->numStonesMissing - field.oppPlayer->numStones;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
numWhiteStonesResting = fieldStruct::numStonesPerPlayer - field.oppPlayer->numStonesMissing - field.oppPlayer->numStones;
|
||||
numBlackStonesResting = fieldStruct::numStonesPerPlayer - field.curPlayer->numStonesMissing - field.curPlayer->numStones;
|
||||
}
|
||||
|
|
|
@ -38,55 +38,41 @@ void RandomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
|
|||
bool allowedToSpring = (theField->curPlayer->numStones == 3) ? true : false;
|
||||
|
||||
// must stone be removed ?
|
||||
if (theField->stoneMustBeRemoved)
|
||||
{
|
||||
if (theField->stoneMustBeRemoved) {
|
||||
|
||||
// search a stone from the enemy
|
||||
do
|
||||
{
|
||||
do {
|
||||
from = rand() % theField->size;
|
||||
to = theField->size;
|
||||
} while (theField->board[from] != theField->oppPlayer->id || theField->stonePartOfMill[from]);
|
||||
|
||||
// still in setting phase ?
|
||||
}
|
||||
else if (theField->settingPhase)
|
||||
{
|
||||
} else if (theField->settingPhase) {
|
||||
|
||||
// search a free square
|
||||
do
|
||||
{
|
||||
do {
|
||||
from = theField->size;
|
||||
to = rand() % theField->size;
|
||||
} while (theField->board[to] != theField->squareIsFree);
|
||||
|
||||
// try to push randomly
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
// search an own stone
|
||||
do
|
||||
{
|
||||
do {
|
||||
from = rand() % theField->size;
|
||||
} while (theField->board[from] != theField->curPlayer->id);
|
||||
|
||||
// select a free square
|
||||
if (allowedToSpring)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (allowedToSpring) {
|
||||
do {
|
||||
to = rand() % theField->size;
|
||||
} while (theField->board[to] != theField->squareIsFree);
|
||||
|
||||
// select a connected square
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
} else {
|
||||
do {
|
||||
direction = rand() % 4;
|
||||
to = theField->connectedSquare[from][direction];
|
||||
} while (to == theField->size);
|
||||
|
|
|
@ -54,13 +54,11 @@ MyString::MyString(const WCHAR *cStr)
|
|||
//-----------------------------------------------------------------------------
|
||||
MyString::~MyString()
|
||||
{
|
||||
if (strA != nullptr)
|
||||
{
|
||||
if (strA != nullptr) {
|
||||
delete[] strA;
|
||||
strA = nullptr;
|
||||
}
|
||||
if (strW != nullptr)
|
||||
{
|
||||
if (strW != nullptr) {
|
||||
delete[] strW;
|
||||
strW = nullptr;
|
||||
}
|
||||
|
@ -180,12 +178,10 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
|
|||
0.0000000001 };
|
||||
|
||||
// read each value
|
||||
do
|
||||
{
|
||||
do {
|
||||
|
||||
// read from buffer if necessary
|
||||
if (curBufferPos >= bufferSize - maxValueLengthInBytes)
|
||||
{
|
||||
if (curBufferPos >= bufferSize - maxValueLengthInBytes) {
|
||||
memcpy(&buffer[0], &buffer[curBufferPos], bufferSize - curBufferPos);
|
||||
ReadFile(hFile, &buffer[bufferSize - curBufferPos], curBufferPos, &dwBytesRead, nullptr);
|
||||
actualBufferSize = bufferSize - curBufferPos + dwBytesRead;
|
||||
|
@ -194,15 +190,11 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
|
|||
}
|
||||
|
||||
// process current byte
|
||||
switch (*curByte)
|
||||
{
|
||||
switch (*curByte) {
|
||||
case '-':
|
||||
if (exponent)
|
||||
{
|
||||
if (exponent) {
|
||||
expIsNegativ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
valIsNegativ = true;
|
||||
}
|
||||
break;
|
||||
|
@ -214,213 +206,156 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
|
|||
decimalPlace = false;
|
||||
break;
|
||||
case '0':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 0;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 0;
|
||||
}
|
||||
break;
|
||||
case '1':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 1;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 1;
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 2;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 2;
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 3;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 3;
|
||||
}
|
||||
break;
|
||||
case '4':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 4;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 4;
|
||||
}
|
||||
break;
|
||||
case '5':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 5;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 5;
|
||||
}
|
||||
break;
|
||||
case '6':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 6;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 6;
|
||||
}
|
||||
break;
|
||||
case '7':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 7;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 7;
|
||||
}
|
||||
break;
|
||||
case '8':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 8;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 8;
|
||||
}
|
||||
break;
|
||||
case '9':
|
||||
if (decimalPlace)
|
||||
{
|
||||
if (decimalPlace) {
|
||||
fractionalValue *= 10;
|
||||
fractionalValue += 9;
|
||||
decimalPos++;
|
||||
}
|
||||
else if (exponent)
|
||||
{
|
||||
} else if (exponent) {
|
||||
exponentialValue *= 10;
|
||||
exponentialValue += 9;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
integralValue *= 10;
|
||||
integralValue += 9;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (*curByte == decimalSeperator)
|
||||
{
|
||||
if (*curByte == decimalSeperator) {
|
||||
decimalPlace = true;
|
||||
exponent = false;
|
||||
}
|
||||
else if (*curByte == columnSeparator)
|
||||
{
|
||||
} else if (*curByte == columnSeparator) {
|
||||
|
||||
// everything ok?
|
||||
if (decimalPos > 8)
|
||||
{
|
||||
if (decimalPos > 8) {
|
||||
cout << "ERROR in function readAsciiData(): Too many digits on decimal place. Maximum is 8 !" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// calc final value
|
||||
(*pData) = integralValue;
|
||||
if (decimalPos)
|
||||
{
|
||||
if (decimalPos) {
|
||||
(*pData) += fractionalValue * fractionalFactor[decimalPos];
|
||||
}
|
||||
if (valIsNegativ)
|
||||
{
|
||||
if (valIsNegativ) {
|
||||
(*pData) *= -1;
|
||||
}
|
||||
if (exponent)
|
||||
{
|
||||
if (exponent) {
|
||||
(*pData) *= pow(10, expIsNegativ ? -1 * exponentialValue : 1);
|
||||
}
|
||||
|
||||
|
@ -437,9 +372,7 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
|
|||
// save value
|
||||
pData++;
|
||||
curReadValue++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -32,8 +32,7 @@ ThreadManager::ThreadManager()
|
|||
InitializeCriticalSection(&csBarrier);
|
||||
hEventBarrierPassedByEveryBody = CreateEvent(nullptr, true, false, nullptr);
|
||||
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
hThread[curThreadNo] = nullptr;
|
||||
threadId[curThreadNo] = 0;
|
||||
hBarrier[curThreadNo] = CreateEvent(nullptr, false, false, nullptr);
|
||||
|
@ -49,8 +48,7 @@ ThreadManager::~ThreadManager()
|
|||
// locals
|
||||
unsigned int curThreadNo;
|
||||
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
CloseHandle(hBarrier[curThreadNo]);
|
||||
}
|
||||
|
||||
|
@ -76,8 +74,7 @@ void ThreadManager::waitForOtherThreads(unsigned int threadNo)
|
|||
{
|
||||
// wait if other threads are still waiting at the barrier
|
||||
//cout << endl << "thread=" << threadNo << ", numThreadsPassedBarrier= " << numThreadsPassedBarrier << ": " << "while (numThreadsPassedBarrier>0)";
|
||||
if (numThreadsPassedBarrier > 0)
|
||||
{
|
||||
if (numThreadsPassedBarrier > 0) {
|
||||
WaitForSingleObject(hEventBarrierPassedByEveryBody, INFINITE);
|
||||
}
|
||||
|
||||
|
@ -92,8 +89,7 @@ void ThreadManager::waitForOtherThreads(unsigned int threadNo)
|
|||
EnterCriticalSection(&csBarrier);
|
||||
|
||||
// if the first one which entered, then wait until other threads
|
||||
if (numThreadsPassedBarrier == 0)
|
||||
{
|
||||
if (numThreadsPassedBarrier == 0) {
|
||||
//cout << endl << "thread=" << threadNo << ", numThreadsPassedBarrier= " << numThreadsPassedBarrier << ": " << "WaitForMultipleObjects()";
|
||||
WaitForMultipleObjects(numThreads, hBarrier, TRUE, INFINITE);
|
||||
ResetEvent(hEventBarrierPassedByEveryBody);
|
||||
|
@ -105,8 +101,7 @@ void ThreadManager::waitForOtherThreads(unsigned int threadNo)
|
|||
|
||||
// the last one closes the door
|
||||
//cout << endl << "thread=" << threadNo << ", numThreadsPassedBarrier= " << numThreadsPassedBarrier << ": " << "if (numThreadsPassedBarrier == numThreads) numThreadsPassedBarrier = 0";
|
||||
if (numThreadsPassedBarrier == numThreads)
|
||||
{
|
||||
if (numThreadsPassedBarrier == numThreads) {
|
||||
numThreadsPassedBarrier = 0;
|
||||
SetEvent(hEventBarrierPassedByEveryBody);
|
||||
}
|
||||
|
@ -132,18 +127,15 @@ bool ThreadManager::setNumThreads(unsigned int newNumThreads)
|
|||
{
|
||||
// cancel if any thread running
|
||||
EnterCriticalSection(&csBarrier);
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
if (hThread[curThreadNo])
|
||||
return false;
|
||||
}
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
CloseHandle(hBarrier[curThreadNo]);
|
||||
}
|
||||
numThreads = newNumThreads;
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
hBarrier[curThreadNo] = CreateEvent(nullptr, false, false, nullptr);
|
||||
}
|
||||
LeaveCriticalSection(&csBarrier);
|
||||
|
@ -156,17 +148,13 @@ bool ThreadManager::setNumThreads(unsigned int newNumThreads)
|
|||
//-----------------------------------------------------------------------------
|
||||
void ThreadManager::pauseExecution()
|
||||
{
|
||||
for (unsigned int curThread = 0; curThread < numThreads; curThread++)
|
||||
{
|
||||
for (unsigned int curThread = 0; curThread < numThreads; curThread++) {
|
||||
|
||||
// unsuspend all threads
|
||||
if (!executionPaused)
|
||||
{
|
||||
if (!executionPaused) {
|
||||
SuspendThread(hThread[curThread]);
|
||||
// suspend all threads
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ResumeThread(hThread[curThread]);
|
||||
}
|
||||
}
|
||||
|
@ -182,8 +170,7 @@ void ThreadManager::cancelExecution()
|
|||
{
|
||||
termineAllThreads = true;
|
||||
executionCancelled = true;
|
||||
if (executionPaused)
|
||||
{
|
||||
if (executionPaused) {
|
||||
pauseExecution();
|
||||
}
|
||||
}
|
||||
|
@ -216,10 +203,8 @@ unsigned int ThreadManager::getThreadNumber()
|
|||
DWORD curThreadId = GetCurrentThreadId();
|
||||
unsigned int curThreadNo;
|
||||
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
if (curThreadId == threadId[curThreadNo])
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
if (curThreadId == threadId[curThreadNo]) {
|
||||
return curThreadNo;
|
||||
}
|
||||
}
|
||||
|
@ -244,16 +229,13 @@ unsigned int ThreadManager::executeInParallel(DWORD threadProc(void *pParameter)
|
|||
termineAllThreads = false;
|
||||
|
||||
// create threads
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
|
||||
hThread[curThreadNo] = CreateThread(nullptr, dwStackSize, (LPTHREAD_START_ROUTINE)threadProc, (void *)(((char *)pParameter) + curThreadNo * parameterStructSize), CREATE_SUSPENDED, &threadId[curThreadNo]);
|
||||
SetThreadPriority(hThread[curThreadNo], THREAD_PRIORITY_BELOW_NORMAL);
|
||||
|
||||
if (hThread[curThreadNo] == nullptr)
|
||||
{
|
||||
for (curThreadNo; curThreadNo > 0; curThreadNo--)
|
||||
{
|
||||
if (hThread[curThreadNo] == nullptr) {
|
||||
for (curThreadNo; curThreadNo > 0; curThreadNo--) {
|
||||
CloseHandle(hThread[curThreadNo - 1]);
|
||||
hThread[curThreadNo - 1] = nullptr;
|
||||
}
|
||||
|
@ -262,8 +244,7 @@ unsigned int ThreadManager::executeInParallel(DWORD threadProc(void *pParameter)
|
|||
}
|
||||
|
||||
// start threads
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
if (!executionPaused)
|
||||
ResumeThread(hThread[curThreadNo]);
|
||||
}
|
||||
|
@ -272,20 +253,16 @@ unsigned int ThreadManager::executeInParallel(DWORD threadProc(void *pParameter)
|
|||
WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);
|
||||
|
||||
// Close all thread handles upon completion.
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
CloseHandle(hThread[curThreadNo]);
|
||||
hThread[curThreadNo] = nullptr;
|
||||
threadId[curThreadNo] = 0;
|
||||
}
|
||||
|
||||
// everything ok
|
||||
if (executionCancelled)
|
||||
{
|
||||
if (executionCancelled) {
|
||||
return TM_RETURN_VALUE_EXECUTION_CANCELLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return TM_RETURN_VALUE_OK;
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +304,7 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
termineAllThreads = false;
|
||||
|
||||
// create threads
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
|
||||
forLoopParameters[curThreadNo].pParameter = (pParameter != nullptr ? (void *)(((char *)pParameter) + curThreadNo * parameterStructSize) : nullptr);
|
||||
forLoopParameters[curThreadNo].threadManager = this;
|
||||
|
@ -336,16 +312,12 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
forLoopParameters[curThreadNo].inkrement = inkrement;
|
||||
forLoopParameters[curThreadNo].scheduleType = scheduleType;
|
||||
|
||||
switch (scheduleType)
|
||||
{
|
||||
switch (scheduleType) {
|
||||
case TM_SCHEDULE_STATIC:
|
||||
chunkSize = numIterations / numThreads + (curThreadNo < numIterations %numThreads ? 1 : 0);
|
||||
if (curThreadNo == 0)
|
||||
{
|
||||
if (curThreadNo == 0) {
|
||||
forLoopParameters[curThreadNo].initialValue = initialValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
forLoopParameters[curThreadNo].initialValue = forLoopParameters[curThreadNo - 1].finalValue + 1;
|
||||
}
|
||||
forLoopParameters[curThreadNo].finalValue = forLoopParameters[curThreadNo].initialValue + chunkSize - 1;
|
||||
|
@ -364,10 +336,8 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
// create suspended thread
|
||||
hThread[curThreadNo] = CreateThread(nullptr, dwStackSize, threadForLoop, (LPVOID)(&forLoopParameters[curThreadNo]), CREATE_SUSPENDED, &threadId[curThreadNo]);
|
||||
SetThreadPriority(hThread[curThreadNo], THREAD_PRIORITY_BELOW_NORMAL);
|
||||
if (hThread[curThreadNo] == nullptr)
|
||||
{
|
||||
for (curThreadNo; curThreadNo > 0; curThreadNo--)
|
||||
{
|
||||
if (hThread[curThreadNo] == nullptr) {
|
||||
for (curThreadNo; curThreadNo > 0; curThreadNo--) {
|
||||
CloseHandle(hThread[curThreadNo - 1]);
|
||||
hThread[curThreadNo - 1] = nullptr;
|
||||
}
|
||||
|
@ -378,8 +348,7 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
}
|
||||
|
||||
// start threads, but don't resume if in pause mode
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
if (!executionPaused)
|
||||
ResumeThread(hThread[curThreadNo]);
|
||||
}
|
||||
|
@ -388,8 +357,7 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);
|
||||
|
||||
// Close all thread handles upon completion.
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++)
|
||||
{
|
||||
for (curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
|
||||
CloseHandle(hThread[curThreadNo]);
|
||||
hThread[curThreadNo] = nullptr;
|
||||
threadId[curThreadNo] = 0;
|
||||
|
@ -397,12 +365,9 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
|
|||
delete[] forLoopParameters;
|
||||
|
||||
// everything ok
|
||||
if (executionCancelled)
|
||||
{
|
||||
if (executionCancelled) {
|
||||
return TM_RETURN_VALUE_EXECUTION_CANCELLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return TM_RETURN_VALUE_OK;
|
||||
}
|
||||
}
|
||||
|
@ -417,13 +382,10 @@ DWORD WINAPI ThreadManager::threadForLoop(LPVOID lpParameter)
|
|||
ForLoop *forLoopParameters = (ForLoop *)lpParameter;
|
||||
int index;
|
||||
|
||||
switch (forLoopParameters->scheduleType)
|
||||
{
|
||||
switch (forLoopParameters->scheduleType) {
|
||||
case TM_SCHEDULE_STATIC:
|
||||
for (index = forLoopParameters->initialValue; (forLoopParameters->inkrement < 0) ? index >= forLoopParameters->finalValue : index <= forLoopParameters->finalValue; index += forLoopParameters->inkrement)
|
||||
{
|
||||
switch (forLoopParameters->threadProc(forLoopParameters->pParameter, index))
|
||||
{
|
||||
for (index = forLoopParameters->initialValue; (forLoopParameters->inkrement < 0) ? index >= forLoopParameters->finalValue : index <= forLoopParameters->finalValue; index += forLoopParameters->inkrement) {
|
||||
switch (forLoopParameters->threadProc(forLoopParameters->pParameter, index)) {
|
||||
case TM_RETURN_VALUE_OK:
|
||||
break;
|
||||
case TM_RETURN_VALUE_TERMINATE_ALL_THREADS:
|
||||
|
|
|
@ -75,9 +75,15 @@ public:
|
|||
public:
|
||||
unsigned int curThreadNo;
|
||||
|
||||
virtual void initializeElement(){};
|
||||
virtual void destroyElement(){};
|
||||
virtual void reduce(){};
|
||||
virtual void initializeElement()
|
||||
{
|
||||
};
|
||||
virtual void destroyElement()
|
||||
{
|
||||
};
|
||||
virtual void reduce()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
template <class varType>
|
||||
|
@ -92,8 +98,7 @@ public:
|
|||
this->numberOfThreads = numberOfThreads;
|
||||
this->item = new varType[numberOfThreads];
|
||||
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++)
|
||||
{
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++) {
|
||||
item[threadCounter].curThreadNo = threadCounter;
|
||||
item[threadCounter].initializeElement(master);
|
||||
item[threadCounter].curThreadNo = threadCounter; // if 'curThreadNo' is overwritten in 'initializeElement()'
|
||||
|
@ -102,8 +107,7 @@ public:
|
|||
|
||||
~ThreadVarsArray()
|
||||
{
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++)
|
||||
{
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++) {
|
||||
item[threadCounter].destroyElement();
|
||||
}
|
||||
delete[] item;
|
||||
|
@ -121,8 +125,7 @@ public:
|
|||
|
||||
void reduce()
|
||||
{
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++)
|
||||
{
|
||||
for (unsigned int threadCounter = 0; threadCounter < numberOfThreads; threadCounter++) {
|
||||
item[threadCounter].reduce();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue