prefect: Rename position to mill and add blank lines

This commit is contained in:
Calcitem 2021-01-21 00:15:08 +08:00
parent 6b610ee3d6
commit b938e0fd66
25 changed files with 384 additions and 228 deletions

View File

@ -33,6 +33,7 @@ BufferedFile::BufferedFile(unsigned int numberOfThreads, unsigned int bufferSize
bytesInReadBuffer[curThread] = 0; bytesInReadBuffer[curThread] = 0;
bytesInWriteBuffer[curThread] = 0; bytesInWriteBuffer[curThread] = 0;
} }
InitializeCriticalSection(&csIO); InitializeCriticalSection(&csIO);
// Open Database-File (FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS) // Open Database-File (FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS)
@ -80,6 +81,7 @@ long long BufferedFile::getFileSize()
LARGE_INTEGER liFileSize; LARGE_INTEGER liFileSize;
GetFileSizeEx(hFile, &liFileSize); GetFileSizeEx(hFile, &liFileSize);
fileSize = liFileSize.QuadPart; fileSize = liFileSize.QuadPart;
return fileSize; return fileSize;
} }
@ -93,6 +95,7 @@ bool BufferedFile::flushBuffers()
writeDataToFile(hFile, curWritingPointer[threadNo] - bytesInWriteBuffer[threadNo], bytesInWriteBuffer[threadNo], &writeBuffer[threadNo * bufferSize + 0]); writeDataToFile(hFile, curWritingPointer[threadNo] - bytesInWriteBuffer[threadNo], bytesInWriteBuffer[threadNo], &writeBuffer[threadNo * bufferSize + 0]);
bytesInWriteBuffer[threadNo] = 0; bytesInWriteBuffer[threadNo] = 0;
} }
return true; return true;
} }
@ -109,9 +112,11 @@ void BufferedFile::writeDataToFile(HANDLE hFile, long long offset, unsigned int
liDistanceToMove.QuadPart = offset; liDistanceToMove.QuadPart = offset;
EnterCriticalSection(&csIO); EnterCriticalSection(&csIO);
while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN)) while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
cout << endl cout << endl
<< "SetFilePointerEx failed!"; << "SetFilePointerEx failed!";
while (restingBytes > 0) { while (restingBytes > 0) {
if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE) { if (WriteFile(hFile, pData, sizeInBytes, &dwBytesWritten, nullptr) == TRUE) {
restingBytes -= dwBytesWritten; restingBytes -= dwBytesWritten;
@ -124,6 +129,7 @@ void BufferedFile::writeDataToFile(HANDLE hFile, long long offset, unsigned int
<< "WriteFile Failed!"; << "WriteFile Failed!";
} }
} }
LeaveCriticalSection(&csIO); LeaveCriticalSection(&csIO);
} }
@ -140,9 +146,11 @@ void BufferedFile::readDataFromFile(HANDLE hFile, long long offset, unsigned int
liDistanceToMove.QuadPart = offset; liDistanceToMove.QuadPart = offset;
EnterCriticalSection(&csIO); EnterCriticalSection(&csIO);
while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN)) while (!SetFilePointerEx(hFile, liDistanceToMove, nullptr, FILE_BEGIN))
cout << endl cout << endl
<< "SetFilePointerEx failed!"; << "SetFilePointerEx failed!";
while (restingBytes > 0) { while (restingBytes > 0) {
if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE) { if (ReadFile(hFile, pData, sizeInBytes, &dwBytesRead, nullptr) == TRUE) {
restingBytes -= dwBytesRead; restingBytes -= dwBytesRead;
@ -155,6 +163,7 @@ void BufferedFile::readDataFromFile(HANDLE hFile, long long offset, unsigned int
<< "ReadFile Failed!"; << "ReadFile Failed!";
} }
} }
LeaveCriticalSection(&csIO); LeaveCriticalSection(&csIO);
} }
@ -176,6 +185,7 @@ bool BufferedFile::writeBytes(unsigned int threadNo, long long positionInFile, u
// parameters ok? // parameters ok?
if (threadNo >= numThreads) if (threadNo >= numThreads)
return false; return false;
if (pData == nullptr) if (pData == nullptr)
return false; return false;
@ -215,6 +225,7 @@ bool BufferedFile::readBytes(unsigned int threadNo, long long positionInFile, un
// parameters ok? // parameters ok?
if (threadNo >= numThreads) if (threadNo >= numThreads)
return false; return false;
if (pData == nullptr) if (pData == nullptr)
return false; return false;
@ -225,6 +236,7 @@ bool BufferedFile::readBytes(unsigned int threadNo, long long positionInFile, un
return false; return false;
readDataFromFile(hFile, positionInFile, bytesInReadBuffer[threadNo], &readBuffer[threadNo * bufferSize + bufferSize - bytesInReadBuffer[threadNo]]); readDataFromFile(hFile, positionInFile, bytesInReadBuffer[threadNo], &readBuffer[threadNo * bufferSize + bufferSize - bytesInReadBuffer[threadNo]]);
} }
memcpy(pData, &readBuffer[threadNo * bufferSize + bufferSize - bytesInReadBuffer[threadNo]], numBytes); memcpy(pData, &readBuffer[threadNo * bufferSize + bufferSize - bytesInReadBuffer[threadNo]], numBytes);
bytesInReadBuffer[threadNo] -= numBytes; bytesInReadBuffer[threadNo] -= numBytes;
curReadingPointer[threadNo] = positionInFile + numBytes; curReadingPointer[threadNo] = positionInFile + numBytes;

View File

@ -148,6 +148,7 @@ bool CyclicArray::addBytes(unsigned int numBytes, unsigned char *pData)
// set pointer to beginnig of writing block // set pointer to beginnig of writing block
curWritingPointer = writingBlock; curWritingPointer = writingBlock;
curWritingBlock = (curWritingBlock + 1) % numBlocks; curWritingBlock = (curWritingBlock + 1) % numBlocks;
if (curWritingBlock == 0) if (curWritingBlock == 0)
readWriteInSameRound = false; readWriteInSameRound = false;
} }
@ -194,7 +195,6 @@ bool CyclicArray::takeBytes(unsigned int numBytes, unsigned char *pData)
// load next block? // load next block?
if (curReadingPointer == readingBlock + blockSize) { if (curReadingPointer == readingBlock + blockSize) {
// go to next block // go to next block
curReadingBlock = (curReadingBlock + 1) % numBlocks; curReadingBlock = (curReadingBlock + 1) % numBlocks;
if (curReadingBlock == 0) if (curReadingBlock == 0)
@ -204,7 +204,6 @@ bool CyclicArray::takeBytes(unsigned int numBytes, unsigned char *pData)
if (curReadingBlock == curWritingBlock) { if (curReadingBlock == curWritingBlock) {
curReadingPointer = writingBlock; curReadingPointer = writingBlock;
} else { } else {
// set pointer to beginnig of reading block // set pointer to beginnig of reading block
curReadingPointer = readingBlock; curReadingPointer = readingBlock;
@ -269,7 +268,6 @@ bool CyclicArray::loadFile(const char *fileName, LONGLONG &numBytesLoaded)
// //
for (curBlock = 0; curBlock < numBlocksInFile - 1; curBlock++, curOffset += blockSize) { for (curBlock = 0; curBlock < numBlocksInFile - 1; curBlock++, curOffset += blockSize) {
// load data from file // load data from file
readDataFromFile(hLoadFile, curOffset, blockSize, dataInFile); readDataFromFile(hLoadFile, curOffset, blockSize, dataInFile);
@ -323,7 +321,6 @@ bool CyclicArray::saveFile(const char *fileName)
dataInFile = new unsigned char[blockSize]; dataInFile = new unsigned char[blockSize];
do { do {
// copy current block // copy current block
if (curBlock == curWritingBlock && curBlock == curReadingBlock) { if (curBlock == curWritingBlock && curBlock == curReadingBlock) {
pointer = curReadingPointer; pointer = curReadingPointer;

View File

@ -1,7 +1,7 @@
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <windows.h> #include <windows.h>
#include "position.h" #include "mill.h"
#include "miniMaxAI.h" #include "miniMaxAI.h"
#include "randomAI.h" #include "randomAI.h"
#include "perfectAI.h" #include "perfectAI.h"
@ -26,7 +26,7 @@ int main(void)
bool playerTwoHuman = false; bool playerTwoHuman = false;
char ch[100]; char ch[100];
unsigned int pushFrom, pushTo; unsigned int pushFrom, pushTo;
Position *pos = new Position(); Mill *pos = new Mill();
PerfectAI *ai = new PerfectAI(databaseDirectory); PerfectAI *ai = new PerfectAI(databaseDirectory);
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
@ -48,17 +48,20 @@ int main(void)
#endif // SELF_PLAY #endif // SELF_PLAY
if (calculateDatabase) { if (calculateDatabase) {
// calculate // calculate
ai->calculateDatabase(MAX_DEPTH_OF_TREE, false); ai->calculateDatabase(MAX_DEPTH_OF_TREE, false);
// test database // test database
cout << endl cout << endl
<< "Begin test starting from layer: "; << "Begin test starting from layer: ";
startTestFromLayer; startTestFromLayer;
cout << endl cout << endl
<< "End test at layer: "; << "End test at layer: ";
endTestAtLayer; endTestAtLayer;
ai->testLayers(startTestFromLayer, endTestAtLayer); ai->testLayers(startTestFromLayer, endTestAtLayer);
} else { } else {
@ -134,12 +137,12 @@ int main(void)
break; break;
} }
} while (pos->do_move(pushFrom, pushTo) == false); } while (pos->doMove(pushFrom, pushTo) == false);
// Computer // Computer
} else { } else {
cout << "\n"; cout << "\n";
pos->do_move(pushFrom, pushTo); pos->doMove(pushFrom, pushTo);
} }
} while (pos->getWinner() == 0); } while (pos->getWinner() == 0);

View File

@ -1,18 +1,18 @@
/********************************************************************* /*********************************************************************
Position.cpp Mill.cpp
Copyright (c) Thomas Weber. All rights reserved. Copyright (c) Thomas Weber. All rights reserved.
Copyright (C) 2021 The Sanmill developers (see AUTHORS file) Copyright (C) 2021 The Sanmill developers (see AUTHORS file)
Licensed under the MIT License. Licensed under the MIT License.
https://github.com/madweasel/madweasels-cpp https://github.com/madweasel/madweasels-cpp
\*********************************************************************/ \*********************************************************************/
#include "position.h" #include "mill.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: Position() // Name: Mill()
// Desc: Position class constructor // Desc: Mill class constructor
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Position::Position() Mill::Mill()
{ {
srand((unsigned)time(nullptr)); srand((unsigned)time(nullptr));
@ -27,19 +27,19 @@ Position::Position()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: ~Position() // Name: ~Mill()
// Desc: Position class destructor // Desc: Mill class destructor
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
Position::~Position() Mill::~Mill()
{ {
exit(); exit();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: deleteArrays() // Name: deleteArrays()
// Desc: Deletes all arrays the Position class has created. // Desc: Deletes all arrays the Mill class has created.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::exit() void Mill::exit()
{ {
SAFE_DELETE_ARRAY(moveLogFrom); SAFE_DELETE_ARRAY(moveLogFrom);
SAFE_DELETE_ARRAY(moveLogTo); SAFE_DELETE_ARRAY(moveLogTo);
@ -50,9 +50,9 @@ void Position::exit()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: beginNewGame() // Name: beginNewGame()
// Desc: Reinitializes the Position object. // Desc: Reinitializes the Mill object.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer) void Mill::beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer)
{ {
// free mem // free mem
exit(); exit();
@ -67,6 +67,7 @@ void Position::beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int c
} else { } else {
beginningPlayer = (rand() % 2) ? field.playerOne : field.playerTwo; beginningPlayer = (rand() % 2) ? field.playerOne : field.playerTwo;
} }
field.curPlayer->id = beginningPlayer; field.curPlayer->id = beginningPlayer;
field.oppPlayer->id = (field.curPlayer->id == field.playerTwo) ? field.playerOne : field.playerTwo; field.oppPlayer->id = (field.curPlayer->id == field.playerTwo) ? field.playerOne : field.playerTwo;
@ -85,7 +86,7 @@ void Position::beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int c
// Name: startSettingPhase() // Name: startSettingPhase()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::startSettingPhase(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer, bool settingPhase) bool Mill::startSettingPhase(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer, bool settingPhase)
{ {
beginNewGame(firstPlayerAI, secondPlayerAI, currentPlayer); beginNewGame(firstPlayerAI, secondPlayerAI, currentPlayer);
@ -98,7 +99,7 @@ bool Position::startSettingPhase(MillAI *firstPlayerAI, MillAI *secondPlayerAI,
// Name: setUpCalcPossibleMoves() // Name: setUpCalcPossibleMoves()
// Desc: Calculates and set the number of possible moves for the passed player considering the game state stored in the 'board' variable. // Desc: Calculates and set the number of possible moves for the passed player considering the game state stored in the 'board' variable.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setUpCalcPossibleMoves(Player *player) void Mill::setUpCalcPossibleMoves(Player *player)
{ {
// locals // locals
unsigned int i, j, k, movingDirection; unsigned int i, j, k, movingDirection;
@ -137,7 +138,7 @@ void Position::setUpCalcPossibleMoves(Player *player)
// Name: setUpSetWarningAndMill() // Name: setUpSetWarningAndMill()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour) void Mill::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour)
{ {
// locals // locals
int rowOwner = field.board[stone]; int rowOwner = field.board[stone];
@ -152,10 +153,10 @@ void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeig
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: put_piece() // Name: putPiece()
// Desc: Put a stone onto the board during the setting phase. // Desc: Put a stone onto the board during the setting phase.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::put_piece(unsigned int pos, int player) bool Mill::putPiece(unsigned int pos, int player)
{ {
// locals // locals
unsigned int i; unsigned int i;
@ -237,7 +238,7 @@ bool Position::put_piece(unsigned int pos, int player)
// Name: settingPhaseHasFinished() // Name: settingPhaseHasFinished()
// Desc: This function has to be called when the setting phase has finished. // Desc: This function has to be called when the setting phase has finished.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::settingPhaseHasFinished() bool Mill::settingPhaseHasFinished()
{ {
// remember initialField // remember initialField
field.copyBoard(&initialField); field.copyBoard(&initialField);
@ -249,7 +250,7 @@ bool Position::settingPhaseHasFinished()
// Name: getField() // Name: getField()
// Desc: Copy the current board state into the array 'pField'. // Desc: Copy the current board state into the array 'pField'.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::getField(int *pField) bool Mill::getField(int *pField)
{ {
unsigned int index; unsigned int index;
@ -271,7 +272,7 @@ bool Position::getField(int *pField)
// Name: getLog() // Name: getLog()
// Desc: Copy the whole history of moves into the passed arrays, which must be of size [MAX_NUM_MOVES]. // Desc: Copy the whole history of moves into the passed arrays, which must be of size [MAX_NUM_MOVES].
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::getLog(unsigned int &numMovesDone, unsigned int *from, unsigned int *to) void Mill::getLog(unsigned int &numMovesDone, unsigned int *from, unsigned int *to)
{ {
unsigned int index; unsigned int index;
@ -287,7 +288,7 @@ void Position::getLog(unsigned int &numMovesDone, unsigned int *from, unsigned i
// Name: setNextPlayer() // Name: setNextPlayer()
// Desc: Current player and opponent player are switched in the board struct. // Desc: Current player and opponent player are switched in the board struct.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setNextPlayer() void Mill::setNextPlayer()
{ {
Player *tmpPlayer; Player *tmpPlayer;
@ -300,7 +301,7 @@ void Position::setNextPlayer()
// Name: isCurrentPlayerHuman() // Name: isCurrentPlayerHuman()
// Desc: Returns true if the current player is not assigned to an AI. // Desc: Returns true if the current player is not assigned to an AI.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::isCurrentPlayerHuman() bool Mill::isCurrentPlayerHuman()
{ {
if (field.curPlayer->id == field.playerOne) if (field.curPlayer->id == field.playerOne)
return (playerOneAI == nullptr) ? true : false; return (playerOneAI == nullptr) ? true : false;
@ -312,7 +313,7 @@ bool Position::isCurrentPlayerHuman()
// Name: isOpponentPlayerHuman() // Name: isOpponentPlayerHuman()
// Desc: Returns true if the opponent player is not assigned to an AI. // Desc: Returns true if the opponent player is not assigned to an AI.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::isOpponentPlayerHuman() bool Mill::isOpponentPlayerHuman()
{ {
if (field.oppPlayer->id == field.playerOne) if (field.oppPlayer->id == field.playerOne)
return (playerOneAI == nullptr) ? true : false; return (playerOneAI == nullptr) ? true : false;
@ -324,7 +325,7 @@ bool Position::isOpponentPlayerHuman()
// Name: setAI() // Name: setAI()
// Desc: Assigns an AI to a player. // Desc: Assigns an AI to a player.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setAI(int player, MillAI *AI) void Mill::setAI(int player, MillAI *AI)
{ {
if (player == field.playerOne) { if (player == field.playerOne) {
playerOneAI = AI; playerOneAI = AI;
@ -338,7 +339,7 @@ void Position::setAI(int player, MillAI *AI)
// Name: getChoiceOfSpecialAI() // Name: getChoiceOfSpecialAI()
// Desc: Returns the move the passed AI would do. // Desc: Returns the move the passed AI would do.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::getChoiceOfSpecialAI(MillAI *AI, unsigned int *pushFrom, unsigned int *pushTo) void Mill::getChoiceOfSpecialAI(MillAI *AI, unsigned int *pushFrom, unsigned int *pushTo)
{ {
fieldStruct theField; fieldStruct theField;
*pushFrom = field.size; *pushFrom = field.size;
@ -354,7 +355,7 @@ void Position::getChoiceOfSpecialAI(MillAI *AI, unsigned int *pushFrom, unsigned
// Name: getComputersChoice() // Name: getComputersChoice()
// Desc: Returns the move the AI of the current player would do. // Desc: Returns the move the AI of the current player would do.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo) void Mill::getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo)
{ {
fieldStruct theField; fieldStruct theField;
*pushFrom = field.size; *pushFrom = field.size;
@ -379,7 +380,7 @@ void Position::getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo)
// Name: isNormalMovePossible() // Name: isNormalMovePossible()
// Desc: 'Normal' in this context means, by moving the stone along a connection without jumping. // Desc: 'Normal' in this context means, by moving the stone along a connection without jumping.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::isNormalMovePossible(unsigned int from, unsigned int to, Player *player) bool Mill::isNormalMovePossible(unsigned int from, unsigned int to, Player *player)
{ {
// locals // locals
unsigned int movingDirection, i; unsigned int movingDirection, i;
@ -419,7 +420,7 @@ bool Position::isNormalMovePossible(unsigned int from, unsigned int to, Player *
// Name: calcPossibleMoves() // Name: calcPossibleMoves()
// Desc: ... // Desc: ...
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::calcPossibleMoves(Player *player) void Mill::calcPossibleMoves(Player *player)
{ {
// locals // locals
unsigned int i, j; unsigned int i, j;
@ -456,7 +457,7 @@ void Position::calcPossibleMoves(Player *player)
// Name: setWarningAndMill() // Name: setWarningAndMill()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour, bool isNewStone) void Mill::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour, bool isNewStone)
{ {
// locals // locals
int rowOwner = field.board[stone]; int rowOwner = field.board[stone];
@ -483,7 +484,7 @@ void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour
// Name: updateMillsAndWarnings() // Name: updateMillsAndWarnings()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::updateMillsAndWarnings(unsigned int newStone) void Mill::updateMillsAndWarnings(unsigned int newStone)
{ {
// locals // locals
unsigned int i; unsigned int i;
@ -492,8 +493,10 @@ void Position::updateMillsAndWarnings(unsigned int newStone)
// zero // zero
for (i = 0; i < field.size; i++) for (i = 0; i < field.size; i++)
field.stonePartOfMill[i] = 0; field.stonePartOfMill[i] = 0;
for (i = 0; i < field.size; i++) for (i = 0; i < field.size; i++)
field.warnings[i] = field.noWarning; field.warnings[i] = field.noWarning;
field.stoneMustBeRemoved = 0; field.stoneMustBeRemoved = 0;
// go in every direction // go in every direction
@ -516,10 +519,10 @@ void Position::updateMillsAndWarnings(unsigned int newStone)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: do_move() // Name: doMove()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::do_move(unsigned int pushFrom, unsigned int pushTo) bool Mill::doMove(unsigned int pushFrom, unsigned int pushTo)
{ {
// avoid index override // avoid index override
if (movesDone >= MAX_NUM_MOVES) if (movesDone >= MAX_NUM_MOVES)
@ -654,7 +657,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
// Name: setCurrentGameState() // Name: setCurrentGameState()
// Desc: Set an arbitrary game state as the current one. // Desc: Set an arbitrary game state as the current one.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::setCurrentGameState(fieldStruct *curState) bool Mill::setCurrentGameState(fieldStruct *curState)
{ {
curState->copyBoard(&field); curState->copyBoard(&field);
@ -663,8 +666,10 @@ bool Position::setCurrentGameState(fieldStruct *curState)
if ((field.curPlayer->numStones < 3) && (!field.settingPhase)) if ((field.curPlayer->numStones < 3) && (!field.settingPhase))
winner = field.oppPlayer->id; winner = field.oppPlayer->id;
if ((field.oppPlayer->numStones < 3) && (!field.settingPhase)) if ((field.oppPlayer->numStones < 3) && (!field.settingPhase))
winner = field.curPlayer->id; winner = field.curPlayer->id;
if ((field.curPlayer->numPossibleMoves == 0) && (!field.settingPhase)) if ((field.curPlayer->numPossibleMoves == 0) && (!field.settingPhase))
winner = field.oppPlayer->id; winner = field.oppPlayer->id;
@ -675,7 +680,7 @@ bool Position::setCurrentGameState(fieldStruct *curState)
// Name: compareWithField() // Name: compareWithField()
// Desc: Compares the current 'board' variable with the passed one. 'stoneMoveAble[]' is ignored. // Desc: Compares the current 'board' variable with the passed one. 'stoneMoveAble[]' is ignored.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::compareWithField(fieldStruct *compareField) bool Mill::compareWithField(fieldStruct *compareField)
{ {
unsigned int i, j; unsigned int i, j;
bool ret = true; bool ret = true;
@ -684,6 +689,7 @@ bool Position::compareWithField(fieldStruct *compareField)
cout << "error - curPlayer differs!" << endl; cout << "error - curPlayer differs!" << endl;
ret = false; ret = false;
} }
if (!comparePlayers(field.oppPlayer, compareField->oppPlayer)) { if (!comparePlayers(field.oppPlayer, compareField->oppPlayer)) {
cout << "error - oppPlayer differs!" << endl; cout << "error - oppPlayer differs!" << endl;
ret = false; ret = false;
@ -693,37 +699,41 @@ bool Position::compareWithField(fieldStruct *compareField)
cout << "error - stonesSet differs!" << endl; cout << "error - stonesSet differs!" << endl;
ret = false; ret = false;
} }
if (field.settingPhase != compareField->settingPhase) { if (field.settingPhase != compareField->settingPhase) {
cout << "error - settingPhase differs!" << endl; cout << "error - settingPhase differs!" << endl;
ret = false; ret = false;
} }
if (field.stoneMustBeRemoved != compareField->stoneMustBeRemoved) { if (field.stoneMustBeRemoved != compareField->stoneMustBeRemoved) {
cout << "error - stoneMustBeRemoved differs!" << endl; cout << "error - stoneMustBeRemoved differs!" << endl;
ret = false; 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; cout << "error - board[] differs!" << endl;
ret = false; ret = false;
} }
if (field.warnings[i] != compareField->warnings[i]) { if (field.warnings[i] != compareField->warnings[i]) {
cout << "error - warnings[] differs!" << endl; cout << "error - warnings[] differs!" << endl;
ret = false; ret = false;
} }
if (field.stonePartOfMill[i] != compareField->stonePartOfMill[i]) { if (field.stonePartOfMill[i] != compareField->stonePartOfMill[i]) {
cout << "error - stonePart[] differs!" << endl; cout << "error - stonePart[] differs!" << endl;
ret = false; 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; cout << "error - connectedSquare[] differs!" << endl;
ret = false; ret = false;
} }
// if (board.stoneMoveAble[i][j] != compareField->stoneMoveAble[i][j]) { cout << "error - stoneMoveAble 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; cout << "error - neighbour differs!" << endl;
ret = false; ret = false;
@ -738,7 +748,7 @@ bool Position::compareWithField(fieldStruct *compareField)
// Name: comparePlayers() // Name: comparePlayers()
// Desc: Compares the two passed players and returns false if they differ. // Desc: Compares the two passed players and returns false if they differ.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::comparePlayers(Player *playerA, Player *playerB) bool Mill::comparePlayers(Player *playerA, Player *playerB)
{ {
// unsigned int i; // unsigned int i;
bool ret = true; bool ret = true;
@ -747,18 +757,22 @@ bool Position::comparePlayers(Player *playerA, Player *playerB)
cout << "error - numStonesMissing differs!" << endl; cout << "error - numStonesMissing differs!" << endl;
ret = false; ret = false;
} }
if (playerA->numStones != playerB->numStones) { if (playerA->numStones != playerB->numStones) {
cout << "error - numStones differs!" << endl; cout << "error - numStones differs!" << endl;
ret = false; ret = false;
} }
if (playerA->id != playerB->id) { if (playerA->id != playerB->id) {
cout << "error - id differs!" << endl; cout << "error - id differs!" << endl;
ret = false; ret = false;
} }
if (playerA->warning != playerB->warning) { if (playerA->warning != playerB->warning) {
cout << "error - warning differs!" << endl; cout << "error - warning differs!" << endl;
ret = false; ret = false;
} }
if (playerA->numPossibleMoves != playerB->numPossibleMoves) { if (playerA->numPossibleMoves != playerB->numPossibleMoves) {
cout << "error - numPossibleMoves differs!" << endl; cout << "error - numPossibleMoves differs!" << endl;
ret = false; ret = false;
@ -775,7 +789,7 @@ bool Position::comparePlayers(Player *playerA, Player *playerB)
// Desc: Calls the printBoard() function of the current board. // Desc: Calls the printBoard() function of the current board.
// Prints the current game state on the screen. // Prints the current game state on the screen.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::printBoard() void Mill::printBoard()
{ {
field.printBoard(); field.printBoard();
} }
@ -784,7 +798,7 @@ void Position::printBoard()
// Name: undo_move() // Name: undo_move()
// Desc: Sets the initial board as the current one and apply all (minus one) moves from the move history. // Desc: Sets the initial board as the current one and apply all (minus one) moves from the move history.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::undo_move(void) void Mill::undo_move(void)
{ {
// locals // locals
unsigned int *moveLogFrom_bak = new unsigned int[movesDone]; unsigned int *moveLogFrom_bak = new unsigned int[movesDone];
@ -808,7 +822,7 @@ void Position::undo_move(void)
// and play again // 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]); doMove(moveLogFrom_bak[i], moveLogTo_bak[i]);
} }
} }
@ -821,7 +835,7 @@ void Position::undo_move(void)
// Name: calcNumberOfRestingStones() // Name: calcNumberOfRestingStones()
// Desc: // Desc:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::calcNumberOfRestingStones(int &numWhiteStonesResting, int &numBlackStonesResting) void Mill::calcNumberOfRestingStones(int &numWhiteStonesResting, int &numBlackStonesResting)
{ {
if (getCurrentPlayer() == fieldStruct::playerTwo) { if (getCurrentPlayer() == fieldStruct::playerTwo) {
numWhiteStonesResting = fieldStruct::numStonesPerPlayer - field.curPlayer->numStonesMissing - field.curPlayer->numStones; numWhiteStonesResting = fieldStruct::numStonesPerPlayer - field.curPlayer->numStonesMissing - field.curPlayer->numStones;

View File

@ -1,13 +1,13 @@
/*********************************************************************\ /*********************************************************************\
Position.h Mill.h
Copyright (c) Thomas Weber. All rights reserved. Copyright (c) Thomas Weber. All rights reserved.
Copyright (C) 2021 The Sanmill developers (see AUTHORS file) Copyright (C) 2021 The Sanmill developers (see AUTHORS file)
Licensed under the MIT License. Licensed under the MIT License.
https://github.com/madweasel/madweasels-cpp https://github.com/madweasel/madweasels-cpp
\*********************************************************************/ \*********************************************************************/
#ifndef MUEHLE_H #ifndef MILL_H
#define MUEHLE_H #define MILL_H
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
@ -42,7 +42,7 @@ using namespace std;
/*** Klassen *********************************************************/ /*** Klassen *********************************************************/
class Position class Mill
{ {
private: private:
// Variables // Variables
@ -64,21 +64,21 @@ private:
public: public:
// Constructor / destructor // Constructor / destructor
Position(); Mill();
~Position(); ~Mill();
// Functions // Functions
void undo_move(); void undo_move();
void beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer); void beginNewGame(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer);
void setAI(int player, MillAI *AI); void setAI(int player, MillAI *AI);
bool do_move(unsigned int pushFrom, unsigned int pushTo); bool doMove(unsigned int pushFrom, unsigned int pushTo);
void getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo); void getComputersChoice(unsigned int *pushFrom, unsigned int *pushTo);
bool setCurrentGameState(fieldStruct *curState); bool setCurrentGameState(fieldStruct *curState);
bool compareWithField(fieldStruct *compareField); bool compareWithField(fieldStruct *compareField);
bool comparePlayers(Player *playerA, Player *playerB); bool comparePlayers(Player *playerA, Player *playerB);
void printBoard(); void printBoard();
bool startSettingPhase(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer, bool settingPhase); bool startSettingPhase(MillAI *firstPlayerAI, MillAI *secondPlayerAI, int currentPlayer, bool settingPhase);
bool put_piece(unsigned int pos, int player); bool putPiece(unsigned int pos, int player);
bool settingPhaseHasFinished(); bool settingPhaseHasFinished();
void getChoiceOfSpecialAI(MillAI *AI, unsigned int *pushFrom, unsigned int *pushTo); void getChoiceOfSpecialAI(MillAI *AI, unsigned int *pushFrom, unsigned int *pushTo);
void setUpCalcPossibleMoves(Player *player); void setUpCalcPossibleMoves(Player *player);
@ -90,46 +90,57 @@ public:
bool getField(int *pField); bool getField(int *pField);
bool isCurrentPlayerHuman(); bool isCurrentPlayerHuman();
bool isOpponentPlayerHuman(); bool isOpponentPlayerHuman();
bool inSettingPhase() bool inSettingPhase()
{ {
return field.settingPhase; return field.settingPhase;
} }
unsigned int mustStoneBeRemoved() unsigned int mustStoneBeRemoved()
{ {
return field.stoneMustBeRemoved; return field.stoneMustBeRemoved;
} }
int getWinner() int getWinner()
{ {
return winner; return winner;
} }
int getCurrentPlayer() int getCurrentPlayer()
{ {
return field.curPlayer->id; return field.curPlayer->id;
} }
unsigned int getLastMoveFrom() unsigned int getLastMoveFrom()
{ {
return (movesDone ? moveLogFrom[movesDone - 1] : field.size); return (movesDone ? moveLogFrom[movesDone - 1] : field.size);
} }
unsigned int getLastMoveTo() unsigned int getLastMoveTo()
{ {
return (movesDone ? moveLogTo[movesDone - 1] : field.size); return (movesDone ? moveLogTo[movesDone - 1] : field.size);
} }
unsigned int getMovesDone() unsigned int getMovesDone()
{ {
return movesDone; return movesDone;
} }
unsigned int getNumStonesSet() unsigned int getNumStonesSet()
{ {
return field.stonesSet; return field.stonesSet;
} }
int getBeginningPlayer() int getBeginningPlayer()
{ {
return beginningPlayer; return beginningPlayer;
} }
unsigned int getNumStonOfCurPlayer() unsigned int getNumStonOfCurPlayer()
{ {
return field.curPlayer->numStones; return field.curPlayer->numStones;
} }
unsigned int getNumStonOfOppPlayer() unsigned int getNumStonOfOppPlayer()
{ {
return field.oppPlayer->numStones; return field.oppPlayer->numStones;

View File

@ -123,6 +123,7 @@ void Player::copyPlayer(Player *destination)
for (i = 0; i < MAX_NUM_POS_MOVES; i++) for (i = 0; i < MAX_NUM_POS_MOVES; i++)
destination->posFrom[i] = this->posFrom[i]; destination->posFrom[i] = this->posFrom[i];
for (i = 0; i < MAX_NUM_POS_MOVES; i++) for (i = 0; i < MAX_NUM_POS_MOVES; i++)
destination->posTo[i] = this->posTo[i]; destination->posTo[i] = this->posTo[i];
} }

View File

@ -94,6 +94,7 @@ public:
{ {
dummyField.createBoard(); dummyField.createBoard();
}; };
~MillAI() ~MillAI()
{ {
dummyField.deleteBoard(); dummyField.deleteBoard();

View File

@ -116,7 +116,6 @@ unsigned int *MiniMaxAI::getPossSettingPhase(unsigned int *numPossibilities, voi
// possibilities with cut off // possibilities with cut off
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) { for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
// move possible ? // move possible ?
if (field->board[i] == field->squareIsFree) { if (field->board[i] == field->squareIsFree) {
@ -144,7 +143,6 @@ unsigned int *MiniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
// if he is not allowed to spring // 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 ((*numPossibilities) = 0, from = 0; from < field->size; from++) {
for (dir = 0; dir < 4; dir++) { for (dir = 0; dir < 4; dir++) {
@ -165,7 +163,6 @@ unsigned int *MiniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
} }
} }
} else { } else {
for ((*numPossibilities) = 0, from = 0; from < field->size; from++) { for ((*numPossibilities) = 0, from = 0; from < field->size; from++) {
for (to = 0; to < field->size; to++) { for (to = 0; to < field->size; to++) {
@ -387,12 +384,14 @@ inline void MiniMaxAI::updateWarning(unsigned int firstStone, unsigned int secon
// no stone must be removed if each belongs to a mill // no stone must be removed if each belongs to a mill
unsigned int i; unsigned int i;
bool atLeastOneStoneRemoveAble = false; bool atLeastOneStoneRemoveAble = false;
if (field->stoneMustBeRemoved) if (field->stoneMustBeRemoved)
for (i = 0; i < field->size; i++) 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; atLeastOneStoneRemoveAble = true;
break; break;
} }
if (!atLeastOneStoneRemoveAble) if (!atLeastOneStoneRemoveAble)
field->stoneMustBeRemoved = 0; field->stoneMustBeRemoved = 0;
} }
@ -413,14 +412,12 @@ inline void MiniMaxAI::updatePossibleMoves(unsigned int stone, Player *stoneOwne
// neighbor must exist // neighbor must exist
if (neighbor < field->size) { if (neighbor < field->size) {
// relevant when moving from one square to another connected square // relevant when moving from one square to another connected square
if (ignoreStone == neighbor) if (ignoreStone == neighbor)
continue; continue;
// if there is no neighbour stone than it only affects the actual stone // 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) if (stoneRemoved)
stoneOwner->numPossibleMoves--; stoneOwner->numPossibleMoves--;
else else
@ -428,13 +425,11 @@ inline void MiniMaxAI::updatePossibleMoves(unsigned int stone, Player *stoneOwne
// if there is a neighbour stone than it effects only this one // 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) if (stoneRemoved)
field->curPlayer->numPossibleMoves++; field->curPlayer->numPossibleMoves++;
else else
field->curPlayer->numPossibleMoves--; field->curPlayer->numPossibleMoves--;
} else { } else {
if (stoneRemoved) if (stoneRemoved)
field->oppPlayer->numPossibleMoves++; field->oppPlayer->numPossibleMoves++;
else else
@ -588,6 +583,7 @@ void MiniMaxAI::move(unsigned int threadNo, unsigned int idPossibility, bool opp
// when game has finished - perfect for the current player // when game has finished - perfect for the current player
if (gameHasFinished && !opponentsMove) if (gameHasFinished && !opponentsMove)
currentValue = VALUE_GAME_WON - curSearchDepth; currentValue = VALUE_GAME_WON - curSearchDepth;
if (gameHasFinished && opponentsMove) if (gameHasFinished && opponentsMove)
currentValue = VALUE_GAME_LOST + curSearchDepth; currentValue = VALUE_GAME_LOST + curSearchDepth;

View File

@ -44,6 +44,7 @@ MiniMax::MiniMax()
numWriteSkvOperations = 0; numWriteSkvOperations = 0;
numReadPlyOperations = 0; numReadPlyOperations = 0;
numWritePlyOperations = 0; numWritePlyOperations = 0;
if (MEASURE_ONLY_IO) { if (MEASURE_ONLY_IO) {
readSkvInterval.QuadPart = 0; readSkvInterval.QuadPart = 0;
writeSkvInterval.QuadPart = 0; writeSkvInterval.QuadPart = 0;
@ -90,6 +91,7 @@ bool MiniMax::falseOrStop()
{ {
if (stopOnCriticalError) if (stopOnCriticalError)
WaitForSingleObject(GetCurrentProcess(), INFINITE); WaitForSingleObject(GetCurrentProcess(), INFINITE);
return false; return false;
} }
@ -145,7 +147,6 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
// when database not completed then do it // when database not completed then do it
if (hFileShortKnotValues != nullptr && skvfHeader.completed == false) { if (hFileShortKnotValues != nullptr && skvfHeader.completed == false) {
// reserve memory // reserve memory
lastCalculatedLayer.clear(); lastCalculatedLayer.clear();
depthOfFullTree = maxDepthOfTree; depthOfFullTree = maxDepthOfTree;
@ -186,8 +187,8 @@ void MiniMax::calculateDatabase(unsigned int maxDepthOfTree, bool onlyPrepareLay
// don't save layer and header when only preparing layers or when // don't save layer and header when only preparing layers or when
if (onlyPrepareLayer) if (onlyPrepareLayer)
return; return;
if (!abortCalculation) {
if (!abortCalculation) {
// calc layer statistics // calc layer statistics
calcLayerStatistics("statistics.txt"); calcLayerStatistics("statistics.txt");
@ -223,7 +224,6 @@ bool MiniMax::calcLayer(unsigned int layerNumber)
// moves can be done reverse, leading to too depth searching trees // moves can be done reverse, leading to too depth searching trees
if (shallRetroAnalysisBeUsed(layerNumber)) { if (shallRetroAnalysisBeUsed(layerNumber)) {
// calc values for all states of layer // calc values for all states of layer
layersToCalculate.push_back(layerNumber); layersToCalculate.push_back(layerNumber);
if (layerNumber != layerStats[layerNumber].partnerLayer) if (layerNumber != layerStats[layerNumber].partnerLayer)

View File

@ -292,25 +292,30 @@ public:
while (true) while (true)
; ;
}; // is called once before building the tree }; // is called once before building the tree
virtual unsigned int *getPossibilities(unsigned int threadNo, unsigned int *numPossibilities, bool *opponentsMove, void **pPossibilities) virtual unsigned int *getPossibilities(unsigned int threadNo, unsigned int *numPossibilities, bool *opponentsMove, void **pPossibilities)
{ {
while (true) while (true)
; ;
return 0; return 0;
}; // returns a pointer to the possibility-IDs }; // returns a pointer to the possibility-IDs
virtual void deletePossibilities(unsigned int threadNo, void *pPossibilities) virtual void deletePossibilities(unsigned int threadNo, void *pPossibilities)
{ {
while (true) 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) virtual void move(unsigned int threadNo, unsigned int idPossibility, bool opponentsMove, void **pBackup, void *pPossibilities)
{ {
while (true) while (true)
; ;
}; };
virtual void undo(unsigned int threadNo, unsigned int idPossibility, bool opponentsMove, void *pBackup, void *pPossibilities) virtual void undo(unsigned int threadNo, unsigned int idPossibility, bool opponentsMove, void *pBackup, void *pPossibilities)
{ {
while (true) while (true)
@ -321,29 +326,34 @@ public:
{ {
return false; return false;
}; };
virtual unsigned int getNumberOfLayers() virtual unsigned int getNumberOfLayers()
{ {
while (true) while (true)
; ;
return 0; return 0;
}; };
virtual unsigned int getNumberOfKnotsInLayer(unsigned int layerNum) virtual unsigned int getNumberOfKnotsInLayer(unsigned int layerNum)
{ {
while (true) while (true)
; ;
return 0; return 0;
}; };
virtual void getSuccLayers(unsigned int layerNum, unsigned int *amountOfSuccLayers, unsigned int *succLayers) virtual void getSuccLayers(unsigned int layerNum, unsigned int *amountOfSuccLayers, unsigned int *succLayers)
{ {
while (true) while (true)
; ;
}; };
virtual unsigned int getPartnerLayer(unsigned int layerNum) virtual unsigned int getPartnerLayer(unsigned int layerNum)
{ {
while (true) while (true)
; ;
return 0; return 0;
}; };
virtual string getOutputInformation(unsigned int layerNum) virtual string getOutputInformation(unsigned int layerNum)
{ {
while (true) while (true)
@ -356,6 +366,7 @@ public:
while (true) while (true)
; ;
}; };
virtual bool setSituation(unsigned int threadNo, unsigned int layerNum, unsigned int stateNumber) virtual bool setSituation(unsigned int threadNo, unsigned int layerNum, unsigned int stateNumber)
{ {
while (true) while (true)
@ -386,11 +397,13 @@ public:
; ;
return 0; return 0;
}; };
virtual void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers) virtual void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers)
{ {
while (true) while (true)
; ;
}; };
virtual void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars) virtual void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars)
{ {
while (true) while (true)
@ -413,6 +426,7 @@ public:
while (true) while (true)
; ;
}; };
virtual void wrapUpDatabaseCalculation(bool calculationAborted) virtual void wrapUpDatabaseCalculation(bool calculationAborted)
{ {
while (true) while (true)
@ -481,6 +495,7 @@ private:
AlphaBetaDefaultThreadVars() AlphaBetaDefaultThreadVars()
{ {
}; };
AlphaBetaDefaultThreadVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber) AlphaBetaDefaultThreadVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber)
{ {
this->statesProcessed = 0; this->statesProcessed = 0;
@ -491,6 +506,7 @@ private:
this->statsValueCounter[curStateValue] = 0; this->statsValueCounter[curStateValue] = 0;
} }
}; };
void reduceDefault() void reduceDefault()
{ {
pMiniMax->numStatesProcessed += this->statesProcessed; pMiniMax->numStatesProcessed += this->statesProcessed;
@ -508,15 +524,18 @@ private:
InitAlphaBetaVars() InitAlphaBetaVars()
{ {
}; };
InitAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber) InitAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber)
{ {
this->bufferedFile = initArray; this->bufferedFile = initArray;
this->initAlreadyDone = initAlreadyDone; this->initAlreadyDone = initAlreadyDone;
}; };
void initializeElement(InitAlphaBetaVars &master) void initializeElement(InitAlphaBetaVars &master)
{ {
*this = master; *this = master;
}; };
void reduce() void reduce()
{ {
reduceDefault(); reduceDefault();
@ -532,19 +551,23 @@ private:
RunAlphaBetaVars() RunAlphaBetaVars()
{ {
}; };
RunAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber) RunAlphaBetaVars(MiniMax *pMiniMax, AlphaBetaGlobalVars *alphaBetaVars, unsigned int layerNumber) : AlphaBetaDefaultThreadVars(pMiniMax, alphaBetaVars, layerNumber)
{ {
initializeElement(*this); initializeElement(*this);
}; };
~RunAlphaBetaVars() ~RunAlphaBetaVars()
{ {
SAFE_DELETE_ARRAY(branchArray); SAFE_DELETE_ARRAY(branchArray);
SAFE_DELETE_ARRAY(freqValuesSubMovesBranchWon); SAFE_DELETE_ARRAY(freqValuesSubMovesBranchWon);
} }
void reduce() void reduce()
{ {
reduceDefault(); reduceDefault();
}; };
void initializeElement(RunAlphaBetaVars &master) void initializeElement(RunAlphaBetaVars &master)
{ {
*this = master; *this = master;
@ -592,6 +615,7 @@ private:
RetroAnalysisDefaultThreadVars() RetroAnalysisDefaultThreadVars()
{ {
}; };
RetroAnalysisDefaultThreadVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber) RetroAnalysisDefaultThreadVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber)
{ {
this->statesProcessed = 0; this->statesProcessed = 0;
@ -602,6 +626,7 @@ private:
this->statsValueCounter[curStateValue] = 0; this->statsValueCounter[curStateValue] = 0;
} }
}; };
void reduceDefault() void reduceDefault()
{ {
pMiniMax->numStatesProcessed += this->statesProcessed; pMiniMax->numStatesProcessed += this->statesProcessed;
@ -619,15 +644,18 @@ private:
InitRetroAnalysisVars() InitRetroAnalysisVars()
{ {
}; };
InitRetroAnalysisVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber) InitRetroAnalysisVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber, BufferedFile *initArray, bool initAlreadyDone) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber)
{ {
this->bufferedFile = initArray; this->bufferedFile = initArray;
this->initAlreadyDone = initAlreadyDone; this->initAlreadyDone = initAlreadyDone;
}; };
void initializeElement(InitRetroAnalysisVars &master) void initializeElement(InitRetroAnalysisVars &master)
{ {
*this = master; *this = master;
}; };
void reduce() void reduce()
{ {
reduceDefault(); reduceDefault();
@ -641,13 +669,16 @@ private:
AddNumSuccedorsVars() AddNumSuccedorsVars()
{ {
}; };
AddNumSuccedorsVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber) AddNumSuccedorsVars(MiniMax *pMiniMax, retroAnalysisGlobalVars *retroVars, unsigned int layerNumber) : RetroAnalysisDefaultThreadVars(pMiniMax, retroVars, layerNumber)
{ {
}; };
void initializeElement(AddNumSuccedorsVars &master) void initializeElement(AddNumSuccedorsVars &master)
{ {
*this = master; *this = master;
}; };
void reduce() void reduce()
{ {
reduceDefault(); reduceDefault();

View File

@ -86,52 +86,66 @@ protected:
{ {
return 0; return 0;
}; };
unsigned int getNumberOfKnotsInLayer(unsigned int layerNum) unsigned int getNumberOfKnotsInLayer(unsigned int layerNum)
{ {
return 0; 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) unsigned int getPartnerLayer(unsigned int layerNum)
{ {
return 0; return 0;
}; };
string getOutputInformation(unsigned int layerNum) string getOutputInformation(unsigned int layerNum)
{ {
return string(""); 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) bool setSituation(unsigned int threadNo, unsigned int layerNum, unsigned int stateNumber)
{ {
return false; return false;
}; };
bool getOpponentLevel(unsigned int threadNo) bool getOpponentLevel(unsigned int threadNo)
{ {
return false; return false;
}; };
unsigned int getLayerAndStateNumber(unsigned int threadNo, unsigned int &layerNum, unsigned int &stateNumber) unsigned int getLayerAndStateNumber(unsigned int threadNo, unsigned int &layerNum, unsigned int &stateNumber)
{ {
return 0; return 0;
}; };
unsigned int getLayerNumber(unsigned int threadNo) unsigned int getLayerNumber(unsigned int threadNo)
{ {
return 0; return 0;
}; };
void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers) void getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *numSymmetricStates, unsigned int **symStateNumbers)
{ {
}; };
void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars) void getPredecessors(unsigned int threadNo, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars)
{ {
}; };
void printBoard(unsigned int threadNo, unsigned char value) void printBoard(unsigned int threadNo, unsigned char value)
{ {
}; };
void prepareDatabaseCalculation() void prepareDatabaseCalculation()
{ {
}; };
void wrapUpDatabaseCalculation(bool calculationAborted) void wrapUpDatabaseCalculation(bool calculationAborted)
{ {
}; };

View File

@ -22,9 +22,11 @@ public:
virtual void setAlignment(wildWeasel::alignment &newAlignment) virtual void setAlignment(wildWeasel::alignment &newAlignment)
{ {
}; };
virtual void setVisibility(bool visible) virtual void setVisibility(bool visible)
{ {
}; };
virtual void setState(unsigned int curShowedLayer, MiniMax::StateNumberVarType curShowedState) virtual void setState(unsigned int curShowedLayer, MiniMax::StateNumberVarType curShowedState)
{ {
}; };

View File

@ -106,6 +106,7 @@ bool MiniMax::initAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
// does initialization file exist ? // does initialization file exist ?
CreateDirectoryA(ssInvArrayDirectory.str().c_str(), nullptr); CreateDirectoryA(ssInvArrayDirectory.str().c_str(), nullptr);
invalidArray = new BufferedFile(threadManager.getNumThreads(), FILE_BUFFER_SIZE, ssInvArrayFilePath.str().c_str()); 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()); PRINT(2, this, " Loading invalid states from file: " << ssInvArrayFilePath.str());
initAlreadyDone = true; initAlreadyDone = true;
@ -216,6 +217,7 @@ DWORD MiniMax::initAlphaBetaThreadProc(void *pParameter, int index)
return m->falseOrStop(); return m->falseOrStop();
} }
} }
iabVars->statsValueCounter[curStateValue]++; iabVars->statsValueCounter[curStateValue]++;
return TM_RETURN_VALUE_OK; return TM_RETURN_VALUE_OK;
@ -251,6 +253,7 @@ bool MiniMax::runAlphaBeta(AlphaBetaGlobalVars &alphaBetaVars)
case TM_RETURN_VALUE_UNEXPECTED_ERROR: case TM_RETURN_VALUE_UNEXPECTED_ERROR:
return falseOrStop(); return falseOrStop();
} }
threadManager.setNumThreads(4); threadManager.setNumThreads(4);
// reduce and delete thread specific data // reduce and delete thread specific data
@ -292,6 +295,7 @@ DWORD MiniMax::runAlphaBetaThreadProc(void *pParameter, int index)
// Version 10: state already calculated? if so leave. // Version 10: state already calculated? if so leave.
m->readPlyInfoFromDatabase(curState.layerNumber, curState.stateNumber, plyInfo); m->readPlyInfoFromDatabase(curState.layerNumber, curState.stateNumber, plyInfo);
if (plyInfo != PLYINFO_VALUE_UNCALCULATED) if (plyInfo != PLYINFO_VALUE_UNCALCULATED)
return TM_RETURN_VALUE_OK; return TM_RETURN_VALUE_OK;
@ -354,7 +358,6 @@ void MiniMax::letTheTreeGrow(Knot *knot, RunAlphaBetaVars *rabVars, unsigned int
// unable to move // unable to move
if (knot->numPossibilities == 0) { if (knot->numPossibilities == 0) {
// if unable to move a final state is reached // if unable to move a final state is reached
knot->plyInfo = 0; knot->plyInfo = 0;
getValueOfSituation(rabVars->curThreadNo, knot->floatValue, knot->shortValue); getValueOfSituation(rabVars->curThreadNo, knot->floatValue, knot->shortValue);
@ -370,7 +373,6 @@ void MiniMax::letTheTreeGrow(Knot *knot, RunAlphaBetaVars *rabVars, unsigned int
// movement is possible // movement is possible
} else { } else {
// move, letTreeGroe, undo // move, letTreeGroe, undo
alphaBetaTryPossibilites(knot, rabVars, tilLevel, idPossibility, pPossibilities, maxWonfreqValuesSubMoves, alpha, beta); alphaBetaTryPossibilites(knot, rabVars, tilLevel, idPossibility, pPossibilities, maxWonfreqValuesSubMoves, alpha, beta);
@ -407,7 +409,6 @@ bool MiniMax::alphaBetaTryDataBase(Knot *knot, RunAlphaBetaVars *rabVars, unsign
// use database ? // use database ?
if (hFilePlyInfo != nullptr && hFileShortKnotValues != nullptr && (calcDatabase || layerInDatabase)) { if (hFilePlyInfo != nullptr && hFileShortKnotValues != nullptr && (calcDatabase || layerInDatabase)) {
// situation already existend in database ? // situation already existend in database ?
readKnotValueFromDatabase(rabVars->curThreadNo, layerNumber, stateNumber, shortKnotValue, invalidLayerOrStateNumber, subLayerInDatabaseAndCompleted); readKnotValueFromDatabase(rabVars->curThreadNo, layerNumber, stateNumber, shortKnotValue, invalidLayerOrStateNumber, subLayerInDatabaseAndCompleted);
readPlyInfoFromDatabase(layerNumber, stateNumber, plyInfo); readPlyInfoFromDatabase(layerNumber, stateNumber, plyInfo);
@ -453,7 +454,6 @@ void MiniMax::alphaBetaTryPossibilites(Knot *knot, RunAlphaBetaVars *rabVars, un
unsigned int curPoss; unsigned int curPoss;
for (curPoss = 0; curPoss < knot->numPossibilities; curPoss++) { for (curPoss = 0; curPoss < knot->numPossibilities; curPoss++) {
// output // output
if (tilLevel == depthOfFullTree && !calcDatabase) { if (tilLevel == depthOfFullTree && !calcDatabase) {
printMoveInformation(rabVars->curThreadNo, idPossibility[curPoss], pPossibilities); printMoveInformation(rabVars->curThreadNo, idPossibility[curPoss], pPossibilities);
@ -491,6 +491,7 @@ void MiniMax::alphaBetaTryPossibilites(Knot *knot, RunAlphaBetaVars *rabVars, un
// don't use alpha beta if using database // don't use alpha beta if using database
if (hFileShortKnotValues != nullptr && calcDatabase) if (hFileShortKnotValues != nullptr && calcDatabase)
continue; continue;
if (hFileShortKnotValues != nullptr && tilLevel + 1 >= depthOfFullTree) if (hFileShortKnotValues != nullptr && tilLevel + 1 >= depthOfFullTree)
continue; continue;
@ -581,7 +582,6 @@ void MiniMax::alphaBetaCalcPlyInfo(Knot *knot)
// when current knot is a won state // 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 // invert knot value if necessary
@ -600,9 +600,7 @@ void MiniMax::alphaBetaCalcPlyInfo(Knot *knot)
// current state is a lost state // 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 // invert knot value if necessary
shortKnotValue = (knot->branches[i].isOpponentLevel) ? skvPerspectiveMatrix[knot->branches[i].shortValue][PL_TO_MOVE_UNCHANGED] : knot->branches[i].shortValue; shortKnotValue = (knot->branches[i].isOpponentLevel) ? skvPerspectiveMatrix[knot->branches[i].shortValue][PL_TO_MOVE_UNCHANGED] : knot->branches[i].shortValue;
@ -638,7 +636,6 @@ void MiniMax::alphaBetaChooseBestMove(Knot *knot, RunAlphaBetaVars *rabVars, uns
// select randomly one of the best moves, if they are equivalent // select randomly one of the best moves, if they are equivalent
if (tilLevel == depthOfFullTree && !calcDatabase) { if (tilLevel == depthOfFullTree && !calcDatabase) {
// check every possible move // check every possible move
for (numBestChoices = 0, i = 0; i < knot->numPossibilities; i++) { for (numBestChoices = 0, i = 0; i < knot->numPossibilities; i++) {

View File

@ -318,7 +318,6 @@ void MiniMax::openPlyInfoFile(const char *directory)
// invalid file ? // invalid file ?
if (dwBytesRead != sizeof(plyInfoHeader) || plyInfoHeader.headerCode != PLYINFO_HEADER_CODE) { if (dwBytesRead != sizeof(plyInfoHeader) || plyInfoHeader.headerCode != PLYINFO_HEADER_CODE) {
// create default header // create default header
plyInfoHeader.plyInfoCompleted = false; plyInfoHeader.plyInfoCompleted = false;
plyInfoHeader.numLayers = getNumberOfLayers(); plyInfoHeader.numLayers = getNumberOfLayers();
@ -363,6 +362,7 @@ void MiniMax::saveLayerToFile(unsigned int layerNumber)
// don't save layer and header when only preparing layers // don't save layer and header when only preparing layers
PlyInfo *myPis = &plyInfos[layerNumber]; PlyInfo *myPis = &plyInfos[layerNumber];
LayerStats *myLss = &layerStats[layerNumber]; LayerStats *myLss = &layerStats[layerNumber];
if (onlyPrepareLayer) if (onlyPrepareLayer)
return; return;
@ -472,6 +472,7 @@ void MiniMax::readKnotValueFromDatabase(unsigned int layerNumber, unsigned int s
if (!myLss->layerIsLoaded) { if (!myLss->layerIsLoaded) {
EnterCriticalSection(&csDatabase); 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 // 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]; myLss->shortKnotValueByte = new unsigned char[myLss->sizeInBytes];
@ -488,6 +489,7 @@ void MiniMax::readKnotValueFromDatabase(unsigned int layerNumber, unsigned int s
memoryUsed2 += bytesAllocated; memoryUsed2 += bytesAllocated;
PRINT(3, this, "Allocated " << bytesAllocated << " bytes in memory for knot values of layer " << layerNumber << ", which is " << (myLss->layerIsCompletedAndInFile ? "" : " NOT ") << " fully calculated, due to read operation."); PRINT(3, this, "Allocated " << bytesAllocated << " bytes in memory for knot values of layer " << layerNumber << ", which is " << (myLss->layerIsCompletedAndInFile ? "" : " NOT ") << " fully calculated, due to read operation.");
} }
LeaveCriticalSection(&csDatabase); LeaveCriticalSection(&csDatabase);
} }
@ -533,7 +535,6 @@ void MiniMax::readPlyInfoFromDatabase(unsigned int layerNumber, unsigned int sta
loadBytesFromFile(hFilePlyInfo, plyInfoHeader.headerAndPlyInfosSize + myPis->layerOffset + sizeof(PlyInfoVarType) * stateNumber, sizeof(PlyInfoVarType), &value); loadBytesFromFile(hFilePlyInfo, plyInfoHeader.headerAndPlyInfosSize + myPis->layerOffset + sizeof(PlyInfoVarType) * stateNumber, sizeof(PlyInfoVarType), &value);
LeaveCriticalSection(&csDatabase); LeaveCriticalSection(&csDatabase);
} else { } else {
// is layer already in memory? // is layer already in memory?
if (!myPis->plyInfoIsLoaded) { if (!myPis->plyInfoIsLoaded) {
EnterCriticalSection(&csDatabase); EnterCriticalSection(&csDatabase);
@ -595,7 +596,6 @@ void MiniMax::saveKnotValueInDatabase(unsigned int layerNumber, unsigned int sta
// is layer already loaded? // is layer already loaded?
if (!myLss->layerIsLoaded) { if (!myLss->layerIsLoaded) {
EnterCriticalSection(&csDatabase); EnterCriticalSection(&csDatabase);
if (!myLss->layerIsLoaded) { if (!myLss->layerIsLoaded) {
// reserve memory for this layer & create array for ply info with default value // reserve memory for this layer & create array for ply info with default value
@ -659,20 +659,23 @@ void MiniMax::savePlyInfoInDatabase(unsigned int layerNumber, unsigned int state
// is layer already loaded // is layer already loaded
if (!myPis->plyInfoIsLoaded) { if (!myPis->plyInfoIsLoaded) {
EnterCriticalSection(&csDatabase); EnterCriticalSection(&csDatabase);
if (!myPis->plyInfoIsLoaded) { if (!myPis->plyInfoIsLoaded) {
// reserve memory for this layer & create array for ply info with default value // reserve memory for this layer & create array for ply info with default value
myPis->plyInfo = new PlyInfoVarType[myPis->knotsInLayer]; myPis->plyInfo = new PlyInfoVarType[myPis->knotsInLayer];
for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++) { for (curKnot = 0; curKnot < myPis->knotsInLayer; curKnot++) {
myPis->plyInfo[curKnot] = defValue; myPis->plyInfo[curKnot] = defValue;
} }
bytesAllocated = myPis->sizeInBytes; bytesAllocated = myPis->sizeInBytes;
arrayInfos.addArray(layerNumber, ArrayInfo::arrayType_plyInfos, myPis->sizeInBytes, 0); arrayInfos.addArray(layerNumber, ArrayInfo::arrayType_plyInfos, myPis->sizeInBytes, 0);
myPis->plyInfoIsLoaded = true; myPis->plyInfoIsLoaded = true;
memoryUsed2 += bytesAllocated; memoryUsed2 += bytesAllocated;
PRINT(3, this, "Allocated " << bytesAllocated << " bytes in memory for ply info of layer " << layerNumber << " due to write operation!"); PRINT(3, this, "Allocated " << bytesAllocated << " bytes in memory for ply info of layer " << layerNumber << " due to write operation!");
} }
LeaveCriticalSection(&csDatabase); LeaveCriticalSection(&csDatabase);
} }

View File

@ -39,6 +39,7 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
retroVars.layerInitialized.resize(skvfHeader.numLayers, false); retroVars.layerInitialized.resize(skvfHeader.numLayers, false);
retroVars.layersToCalculate = layersToCalculate; retroVars.layersToCalculate = layersToCalculate;
retroVars.pMiniMax = this; 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.numKnotsToCalc += layerStats[layersToCalculate[curLayer]].knotsInLayer;
retroVars.totalNumKnots += layerStats[layersToCalculate[curLayer]].knotsInLayer; retroVars.totalNumKnots += layerStats[layersToCalculate[curLayer]].knotsInLayer;
@ -51,6 +52,7 @@ bool MiniMax::calcKnotValuesByRetroAnalysis(vector<unsigned int> &layersToCalcul
retroVars.totalNumKnots += layerStats[layerStats[layersToCalculate[curLayer]].succLayers[curSubLayer]].knotsInLayer; retroVars.totalNumKnots += layerStats[layerStats[layersToCalculate[curLayer]].succLayers[curSubLayer]].knotsInLayer;
} }
} }
retroVars.layerInitialized.assign(skvfHeader.numLayers, false); retroVars.layerInitialized.assign(skvfHeader.numLayers, false);
// output & filenames // output & filenames
@ -97,6 +99,7 @@ freeMem:
SAFE_DELETE(retroVars.thread[threadNo].statesToProcess[plyCounter]); SAFE_DELETE(retroVars.thread[threadNo].statesToProcess[plyCounter]);
} }
} }
for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++) { for (curLayer = 0; curLayer < layersToCalculate.size(); curLayer++) {
if (retroVars.countArrays[curLayer] != nullptr) { if (retroVars.countArrays[curLayer] != nullptr) {
memoryUsed2 -= layerStats[layersToCalculate[curLayer]].knotsInLayer * sizeof(CountArrayVarType); memoryUsed2 -= layerStats[layersToCalculate[curLayer]].knotsInLayer * sizeof(CountArrayVarType);
@ -104,8 +107,10 @@ freeMem:
} }
SAFE_DELETE_ARRAY(retroVars.countArrays[curLayer]); SAFE_DELETE_ARRAY(retroVars.countArrays[curLayer]);
} }
if (!abortCalculation) if (!abortCalculation)
PRINT(2, this, " Bytes in memory: " << memoryUsed2); PRINT(2, this, " Bytes in memory: " << memoryUsed2);
return !abortCalculation; return !abortCalculation;
} }
@ -125,7 +130,6 @@ bool MiniMax::initRetroAnalysis(retroAnalysisGlobalVars &retroVars)
// process each layer // process each layer
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) { for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) {
// set current processed layer number // set current processed layer number
layerNumber = retroVars.layersToCalculate[curLayerId]; layerNumber = retroVars.layersToCalculate[curLayerId];
curCalculationActionId = MM_ACTION_INIT_RETRO_ANAL; curCalculationActionId = MM_ACTION_INIT_RETRO_ANAL;
@ -178,6 +182,7 @@ bool MiniMax::initRetroAnalysis(retroAnalysisGlobalVars &retroVars)
initAlreadyDone = false; initAlreadyDone = false;
initArray->flushBuffers(); initArray->flushBuffers();
SAFE_DELETE(initArray); SAFE_DELETE(initArray);
if (numStatesProcessed < layerStats[layerNumber].knotsInLayer) if (numStatesProcessed < layerStats[layerNumber].knotsInLayer)
return falseOrStop(); return falseOrStop();
@ -225,7 +230,6 @@ DWORD MiniMax::initRetroAnalysisThreadProc(void *pParameter, int index)
// initialization not done // initialization not done
} else { } else {
// set current selected situation // 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; curStateValue = SKV_VALUE_INVALID;
@ -237,13 +241,11 @@ DWORD MiniMax::initRetroAnalysisThreadProc(void *pParameter, int index)
// save init value // save init value
if (curStateValue != SKV_VALUE_INVALID) { if (curStateValue != SKV_VALUE_INVALID) {
// save short knot value // save short knot value
m->saveKnotValueInDatabase(curState.layerNumber, curState.stateNumber, curStateValue); m->saveKnotValueInDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
// put in list if state is final // 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 // ply info
m->savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, 0); m->savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, 0);
@ -260,6 +262,7 @@ DWORD MiniMax::initRetroAnalysisThreadProc(void *pParameter, int index)
return m->falseOrStop(); return m->falseOrStop();
} }
} }
iraVars->statsValueCounter[curStateValue]++; iraVars->statsValueCounter[curStateValue]++;
return TM_RETURN_VALUE_OK; return TM_RETURN_VALUE_OK;
@ -287,6 +290,7 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
// output & filenames // output & filenames
for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++) for (curLayer = 0; curLayer < retroVars.layersToCalculate.size(); curLayer++)
ssLayers << " " << retroVars.layersToCalculate[curLayer]; ssLayers << " " << retroVars.layersToCalculate[curLayer];
ssCountArrayPath << fileDirectory << (fileDirectory.size() ? "\\" : "") << "countArray"; ssCountArrayPath << fileDirectory << (fileDirectory.size() ? "\\" : "") << "countArray";
ssCountArrayFilePath << fileDirectory << (fileDirectory.size() ? "\\" : "") << "countArray\\countArray" << ssLayers.str() << ".dat"; ssCountArrayFilePath << fileDirectory << (fileDirectory.size() ? "\\" : "") << "countArray\\countArray" << ssLayers.str() << ".dat";
PRINT(2, this, " *** Prepare count arrays for layers " << ssLayers.str() << " ***" << endl); PRINT(2, this, " *** Prepare count arrays for layers " << ssLayers.str() << " ***" << endl);
@ -294,6 +298,7 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
// prepare count arrays // prepare count arrays
CreateDirectoryA(ssCountArrayPath.str().c_str(), nullptr); 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() << "!"); PRINT(0, this, "ERROR: Could not open File " << ssCountArrayFilePath.str() << "!");
return falseOrStop(); return falseOrStop();
@ -344,6 +349,7 @@ bool MiniMax::prepareCountArrays(retroAnalysisGlobalVars &retroVars)
if (dwWritten != numKnotsInCurLayer * sizeof(CountArrayVarType)) if (dwWritten != numKnotsInCurLayer * sizeof(CountArrayVarType))
return falseOrStop(); return falseOrStop();
} }
PRINT(2, this, " Count array saved to file: " << ssCountArrayFilePath.str()); PRINT(2, this, " Count array saved to file: " << ssCountArrayFilePath.str());
} }
@ -496,7 +502,6 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
// iteration // iteration
for (curPred = 0; curPred < amountOfPred; curPred++) { for (curPred = 0; curPred < amountOfPred; curPred++) {
// current predecessor // current predecessor
predState.layerNumber = ansVars->predVars[curPred].predLayerNumbers; predState.layerNumber = ansVars->predVars[curPred].predLayerNumbers;
predState.stateNumber = ansVars->predVars[curPred].predStateNumbers; predState.stateNumber = ansVars->predVars[curPred].predStateNumbers;
@ -506,6 +511,7 @@ DWORD MiniMax::addNumSuccedorsThreadProc(void *pParameter, int index)
if (ansVars->retroVars->layersToCalculate[curLayerId] == predState.layerNumber) if (ansVars->retroVars->layersToCalculate[curLayerId] == predState.layerNumber)
break; break;
} }
if (curLayerId == numLayersToCalculate) if (curLayerId == numLayersToCalculate)
continue; continue;
@ -577,6 +583,7 @@ bool MiniMax::performRetroAnalysis(retroAnalysisGlobalVars &retroVars)
// copy drawn and invalid states to ply info // copy drawn and invalid states to ply info
PRINT(2, this, " Copy drawn and invalid states to ply info database..."); PRINT(2, this, " Copy drawn and invalid states to ply info database...");
for (curLayerId = 0; curLayerId < retroVars.layersToCalculate.size(); curLayerId++) { 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 (curState.layerNumber = retroVars.layersToCalculate[curLayerId], curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) {
readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue); readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
@ -586,6 +593,7 @@ bool MiniMax::performRetroAnalysis(retroAnalysisGlobalVars &retroVars)
savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, PLYINFO_VALUE_INVALID); savePlyInfoInDatabase(curState.layerNumber, curState.stateNumber, PLYINFO_VALUE_INVALID);
} }
} }
PRINT(1, this, " *** Iteration finished! ***"); PRINT(1, this, " *** Iteration finished! ***");
// every thing ok // every thing ok
@ -624,7 +632,6 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
// skip empty and uninitialized cyclic arrays // 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()); 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++) {
@ -633,7 +640,6 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
} }
while (threadVars->statesToProcess[curNumPlies]->takeBytes(sizeof(StateAdress), (unsigned char *)&curState)) { while (threadVars->statesToProcess[curNumPlies]->takeBytes(sizeof(StateAdress), (unsigned char *)&curState)) {
// execution cancelled by user? // 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"); PRINT(0, m, "\n****************************************\nSub-thread no. " << threadNo << ": Execution cancelled by user!\n****************************************\n");
@ -671,7 +677,6 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
// iteration // iteration
for (curPred = 0; curPred < amountOfPred; curPred++) { for (curPred = 0; curPred < amountOfPred; curPred++) {
// current predecessor // current predecessor
predState.layerNumber = predVars[curPred].predLayerNumbers; predState.layerNumber = predVars[curPred].predLayerNumbers;
predState.stateNumber = predVars[curPred].predStateNumbers; predState.stateNumber = predVars[curPred].predStateNumbers;
@ -689,7 +694,6 @@ DWORD MiniMax::performRetroAnalysisThreadProc(void *pParameter)
// only drawn states are relevant here, since the other are already calculated // 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 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->saveKnotValueInDatabase(predState.layerNumber, predState.stateNumber, SKV_VALUE_GAME_WON);
@ -780,5 +784,6 @@ bool MiniMax::addStateToProcessQueue(retroAnalysisGlobalVars &retroVars, RetroAn
// everything was fine // everything was fine
threadVars.numStatesToProcess++; threadVars.numStatesToProcess++;
return true; return true;
} }

View File

@ -141,7 +141,6 @@ void MiniMax::showLayerStats(unsigned int layerNumber)
// calc and show statistics // calc and show statistics
for (curState.layerNumber = layerNumber, curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) { for (curState.layerNumber = layerNumber, curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) {
// get state value // get state value
readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue); readKnotValueFromDatabase(curState.layerNumber, curState.stateNumber, curStateValue);
statsValueCounter[curStateValue]++; statsValueCounter[curStateValue]++;
@ -220,7 +219,6 @@ bool MiniMax::calcLayerStatistics(char *statisticsFileName)
// only calc stats of completed layers // only calc stats of completed layers
if (layerStats[curState.layerNumber].layerIsCompletedAndInFile) { if (layerStats[curState.layerNumber].layerIsCompletedAndInFile) {
for (curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) { for (curState.stateNumber = 0; curState.stateNumber < layerStats[curState.layerNumber].knotsInLayer; curState.stateNumber++) {
// get state value // get state value
@ -321,6 +319,7 @@ void MiniMax::ArrayInfoContainer::addArray(unsigned int layerNumber, unsigned in
{ {
// create new info object and add to list // create new info object and add to list
EnterCriticalSection(&c->csOsPrint); EnterCriticalSection(&c->csOsPrint);
ArrayInfo ais; ArrayInfo ais;
ais.belongsToLayer = layerNumber; ais.belongsToLayer = layerNumber;
ais.compressedSizeInBytes = compressedSize; ais.compressedSizeInBytes = compressedSize;
@ -342,6 +341,7 @@ void MiniMax::ArrayInfoContainer::addArray(unsigned int layerNumber, unsigned in
if (c->userPrintFunc != nullptr) { if (c->userPrintFunc != nullptr) {
c->userPrintFunc(c->pDataForUserPrintFunc); c->userPrintFunc(c->pDataForUserPrintFunc);
} }
LeaveCriticalSection(&c->csOsPrint); LeaveCriticalSection(&c->csOsPrint);
} }
@ -378,6 +378,7 @@ void MiniMax::ArrayInfoContainer::removeArray(unsigned int layerNumber, unsigned
if (c->userPrintFunc != nullptr) { if (c->userPrintFunc != nullptr) {
c->userPrintFunc(c->pDataForUserPrintFunc); c->userPrintFunc(c->pDataForUserPrintFunc);
} }
LeaveCriticalSection(&c->csOsPrint); LeaveCriticalSection(&c->csOsPrint);
} }
@ -395,6 +396,7 @@ void MiniMax::ArrayInfoContainer::updateArray(unsigned int layerNumber, unsigned
// notify cahnge // notify cahnge
EnterCriticalSection(&c->csOsPrint); EnterCriticalSection(&c->csOsPrint);
ArrayInfoChange aic; ArrayInfoChange aic;
aic.arrayInfo = &(*itr); aic.arrayInfo = &(*itr);
aic.itemIndex = (unsigned int)std::distance(listArrays.begin(), itr); aic.itemIndex = (unsigned int)std::distance(listArrays.begin(), itr);
@ -405,6 +407,7 @@ void MiniMax::ArrayInfoContainer::updateArray(unsigned int layerNumber, unsigned
c->userPrintFunc(c->pDataForUserPrintFunc); c->userPrintFunc(c->pDataForUserPrintFunc);
} }
itr->updateCounter = 0; itr->updateCounter = 0;
LeaveCriticalSection(&c->csOsPrint); LeaveCriticalSection(&c->csOsPrint);
} }
} }

View File

@ -35,6 +35,7 @@ bool MiniMax::testLayer(unsigned int layerNumber)
curCalculatedLayer = layerNumber; curCalculatedLayer = layerNumber;
curCalculationActionId = MM_ACTION_TESTING_LAYER; curCalculationActionId = MM_ACTION_TESTING_LAYER;
TestLayersVars *tlVars = new TestLayersVars[threadManager.getNumThreads()]; 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].curThreadNo = curThreadNo;
tlVars[curThreadNo].pMiniMax = this; tlVars[curThreadNo].pMiniMax = this;
@ -161,7 +162,6 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
goto errorInDatabase; goto errorInDatabase;
} }
} else { } else {
// check each possible move // check each possible move
for (i = 0; i < numPossibilities; i++) { for (i = 0; i < numPossibilities; i++) {
@ -194,7 +194,6 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
// value possible? // value possible?
switch (shortValueInDatabase) { switch (shortValueInDatabase) {
case SKV_VALUE_GAME_LOST: case SKV_VALUE_GAME_LOST:
// all possible moves must be lost for the current player or won for the opponent // all possible moves must be lost for the current player or won for the opponent
for (i = 0; i < numPossibilities; i++) { for (i = 0; i < numPossibilities; i++) {
if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_INVALID) { if (subValueInDatabase[i] != ((hasCurPlayerChanged[i]) ? SKV_VALUE_GAME_WON : SKV_VALUE_GAME_LOST) && subValueInDatabase[i] != SKV_VALUE_INVALID) {
@ -231,7 +230,6 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
break; break;
case SKV_VALUE_GAME_WON: case SKV_VALUE_GAME_WON:
// at least one possible move must be lost for the opponent or won for the current player // 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] == 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; }
@ -263,7 +261,6 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
break; break;
case SKV_VALUE_GAME_DRAWN: case SKV_VALUE_GAME_DRAWN:
// all possible moves must be won for the opponent, lost for the current player or 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] == 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; }
@ -306,6 +303,7 @@ DWORD MiniMax::testLayerThreadProc(void *pParameter, int index)
break; break;
} }
} }
return TM_RETURN_VALUE_OK; return TM_RETURN_VALUE_OK;
errorInDatabase: errorInDatabase:
@ -360,6 +358,7 @@ bool MiniMax::testSetSituationAndGetPoss(unsigned int layerNumber)
numStatesProcessed = 0; numStatesProcessed = 0;
curCalculationActionId = MM_ACTION_TESTING_LAYER; curCalculationActionId = MM_ACTION_TESTING_LAYER;
TestLayersVars *tlVars = new TestLayersVars[threadManager.getNumThreads()]; 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].curThreadNo = curThreadNo;
tlVars[curThreadNo].pMiniMax = this; tlVars[curThreadNo].pMiniMax = this;
@ -372,6 +371,7 @@ bool MiniMax::testSetSituationAndGetPoss(unsigned int layerNumber)
// process each state in the current layer // process each state in the current layer
returnValue = threadManager.executeParallelLoop(testSetSituationThreadProc, (void *)tlVars, sizeof(TestLayersVars), TM_SCHEDULE_STATIC, 0, layerStats[layerNumber].knotsInLayer - 1, 1); 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_OK:
case TM_RETURN_VALUE_EXECUTION_CANCELLED: case TM_RETURN_VALUE_EXECUTION_CANCELLED:
@ -430,6 +430,7 @@ DWORD MiniMax::testSetSituationThreadProc(void *pParameter, int index)
// output // output
tlVars->statesProcessed++; tlVars->statesProcessed++;
if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) { if (tlVars->statesProcessed % OUTPUT_EVERY_N_STATES == 0) {
m->numStatesProcessed += OUTPUT_EVERY_N_STATES; m->numStatesProcessed += OUTPUT_EVERY_N_STATES;
PRINT(0, m, m->numStatesProcessed << " states of " << m->layerStats[curState.layerNumber].knotsInLayer << " tested"); PRINT(0, m, m->numStatesProcessed << " states of " << m->layerStats[curState.layerNumber].knotsInLayer << " tested");
@ -481,6 +482,7 @@ DWORD MiniMax::testSetSituationThreadProc(void *pParameter, int index)
m->setSituation(tlVars->curThreadNo, curState.layerNumber, curState.stateNumber); m->setSituation(tlVars->curThreadNo, curState.layerNumber, curState.stateNumber);
} }
} }
return TM_RETURN_VALUE_OK; return TM_RETURN_VALUE_OK;
//errorInDatabase: //errorInDatabase:
@ -525,7 +527,6 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
skvfHeader.completed = false; skvfHeader.completed = false;
for (layerInDatabase = false, stateNumber = 0; stateNumber < layerStats[layerNumber].knotsInLayer; stateNumber++) { for (layerInDatabase = false, stateNumber = 0; stateNumber < layerStats[layerNumber].knotsInLayer; stateNumber++) {
// output // output
if (stateNumber % OUTPUT_EVERY_N_STATES == 0) if (stateNumber % OUTPUT_EVERY_N_STATES == 0)
PRINT(1, this, stateNumber << " states of " << layerStats[layerNumber].knotsInLayer << " tested"); PRINT(1, this, stateNumber << " states of " << layerStats[layerNumber].knotsInLayer << " tested");
@ -549,7 +550,6 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
// save value for all symmetric states // save value for all symmetric states
for (i = 0; i < numSymmetricStates; i++) { for (i = 0; i < numSymmetricStates; i++) {
readKnotValueFromDatabase(layerNumber, symStateNumbers[i], shortValueOfSymState); readKnotValueFromDatabase(layerNumber, symStateNumbers[i], shortValueOfSymState);
readPlyInfoFromDatabase(layerNumber, symStateNumbers[i], numPliesTillSymState); readPlyInfoFromDatabase(layerNumber, symStateNumbers[i], numPliesTillSymState);
@ -571,6 +571,7 @@ bool MiniMax::testIfSymStatesHaveSameValue(unsigned int layerNumber)
// layer is ok // layer is ok
PRINT(0, this, "TEST PASSED !"); PRINT(0, this, "TEST PASSED !");
return true; return true;
errorInDatabase: errorInDatabase:
@ -578,5 +579,6 @@ errorInDatabase:
// layer is not ok // layer is not ok
if (layerNumber) if (layerNumber)
PRINT(0, this, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber); PRINT(0, this, "DATABASE ERROR IN LAYER " << layerNumber << " AND STATE " << stateNumber);
return falseOrStop(); return falseOrStop();
} }

View File

@ -154,7 +154,7 @@
<ClInclude Include="miniMaxWin.h" /> <ClInclude Include="miniMaxWin.h" />
<ClInclude Include="miniMax_retroAnalysis.h" /> <ClInclude Include="miniMax_retroAnalysis.h" />
<ClInclude Include="miniMaxAI.h" /> <ClInclude Include="miniMaxAI.h" />
<ClInclude Include="position.h" /> <ClInclude Include="mill.h" />
<ClInclude Include="millAI.h" /> <ClInclude Include="millAI.h" />
<ClInclude Include="perfectAI.h" /> <ClInclude Include="perfectAI.h" />
<ClInclude Include="randomAI.h" /> <ClInclude Include="randomAI.h" />
@ -172,7 +172,7 @@
<ClCompile Include="miniMax_statistics.cpp" /> <ClCompile Include="miniMax_statistics.cpp" />
<ClCompile Include="miniMax_test.cpp" /> <ClCompile Include="miniMax_test.cpp" />
<ClCompile Include="minMaxAI.cpp" /> <ClCompile Include="minMaxAI.cpp" />
<ClCompile Include="position.cpp" /> <ClCompile Include="mill.cpp" />
<ClCompile Include="millAI.cpp" /> <ClCompile Include="millAI.cpp" />
<ClCompile Include="perfectAI.cpp" /> <ClCompile Include="perfectAI.cpp" />
<ClCompile Include="randomAI.cpp" /> <ClCompile Include="randomAI.cpp" />

View File

@ -51,7 +51,7 @@
<ClInclude Include="config.h"> <ClInclude Include="config.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="position.h"> <ClInclude Include="mill.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
@ -98,10 +98,10 @@
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="position.cpp"> <ClCompile Include="minMaxAI.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="minMaxAI.cpp"> <ClCompile Include="mill.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>

View File

@ -8,149 +8,166 @@
#include "perfectAI.h" #include "perfectAI.h"
unsigned int soTableTurnLeft[] = { unsigned int soTableTurnLeft[] = {
2, 14, 23, 2, 14, 23,
5, 13, 20, 5, 13, 20,
8, 12, 17, 8,12,17,
1, 4, 7, 16, 19, 22, 1, 4, 7, 16,19,22,
6, 11, 15, 6,11,15,
3, 10, 18, 3, 10, 18,
0, 9, 21 }; 0, 9, 21
};
unsigned int soTableDoNothing[] = { unsigned int soTableDoNothing[] = {
0, 1, 2, 0, 1, 2,
3, 4, 5, 3, 4, 5,
6, 7, 8, 6, 7, 8,
9, 10, 11, 12, 13, 14, 9,10,11, 12,13,14,
15, 16, 17, 15,16,17,
18, 19, 20, 18, 19, 20,
21, 22, 23 }; 21, 22, 23
};
unsigned int soTableMirrorHori[] = { unsigned int soTableMirrorHori[] = {
21, 22, 23, 21, 22, 23,
18, 19, 20, 18, 19, 20,
15, 16, 17, 15,16,17,
9, 10, 11, 12, 13, 14, 9,10,11, 12,13,14,
6, 7, 8, 6, 7, 8,
3, 4, 5, 3, 4, 5,
0, 1, 2 }; 0, 1, 2
};
unsigned int soTableTurn180[] = { unsigned int soTableTurn180[] = {
23, 22, 21, 23, 22, 21,
20, 19, 18, 20, 19, 18,
17, 16, 15, 17,16,15,
14, 13, 12, 11, 10, 9, 14,13,12, 11,10, 9,
8, 7, 6, 8, 7, 6,
5, 4, 3, 5, 4, 3,
2, 1, 0 }; 2, 1, 0
};
unsigned int soTableInvert[] = { unsigned int soTableInvert[] = {
6, 7, 8, 6, 7, 8,
3, 4, 5, 3, 4, 5,
0, 1, 2, 0, 1, 2,
11, 10, 9, 14, 13, 12, 11,10, 9, 14,13,12,
21, 22, 23, 21,22,23,
18, 19, 20, 18, 19, 20,
15, 16, 17 }; 15, 16, 17
};
unsigned int soTableInvMirHori[] = { unsigned int soTableInvMirHori[] = {
15, 16, 17, 15, 16, 17,
18, 19, 20, 18, 19, 20,
21, 22, 23, 21,22,23,
11, 10, 9, 14, 13, 12, 11,10, 9, 14,13,12,
0, 1, 2, 0, 1, 2,
3, 4, 5, 3, 4, 5,
6, 7, 8 }; 6, 7, 8
};
unsigned int soTableInvMirVert[] = { unsigned int soTableInvMirVert[] = {
8, 7, 6, 8, 7, 6,
5, 4, 3, 5, 4, 3,
2, 1, 0, 2, 1, 0,
12, 13, 14, 9, 10, 11, 12,13,14, 9,10,11,
23, 22, 21, 23,22,21,
20, 19, 18, 20, 19, 18,
17, 16, 15 }; 17, 16, 15
};
unsigned int soTableInvMirDiag1[] = { unsigned int soTableInvMirDiag1[] = {
17, 12, 8, 17, 12, 8,
20, 13, 5, 20, 13, 5,
23, 14, 2, 23,14, 2,
16, 19, 22, 1, 4, 7, 16,19,22, 1, 4, 7,
21, 9, 0, 21, 9, 0,
18, 10, 3, 18, 10, 3,
15, 11, 6 }; 15, 11, 6
};
unsigned int soTableInvMirDiag2[] = { unsigned int soTableInvMirDiag2[] = {
6, 11, 15, 6, 11, 15,
3, 10, 18, 3, 10, 18,
0, 9, 21, 0, 9,21,
7, 4, 1, 22, 19, 16, 7, 4, 1, 22,19,16,
2, 14, 23, 2,14,23,
5, 13, 20, 5, 13, 20,
8, 12, 17 }; 8, 12, 17
};
unsigned int soTableInvLeft[] = { unsigned int soTableInvLeft[] = {
8, 12, 17, 8, 12, 17,
5, 13, 20, 5, 13, 20,
2, 14, 23, 2,14,23,
7, 4, 1, 22, 19, 16, 7, 4, 1, 22,19,16,
0, 9, 21, 0, 9,21,
3, 10, 18, 3, 10, 18,
6, 11, 15 }; 6, 11, 15
};
unsigned int soTableInvRight[] = { unsigned int soTableInvRight[] = {
15, 11, 6, 15, 11, 6,
18, 10, 3, 18, 10, 3,
21, 9, 0, 21, 9, 0,
16, 19, 22, 1, 4, 7, 16,19,22, 1, 4, 7,
23, 14, 2, 23,14, 2,
20, 13, 5, 20, 13, 5,
17, 12, 8 }; 17, 12, 8
};
unsigned int soTableInv180[] = { unsigned int soTableInv180[] = {
17, 16, 15, 17, 16, 15,
20, 19, 18, 20, 19, 18,
23, 22, 21, 23,22,21,
12, 13, 14, 9, 10, 11, 12,13,14, 9,10,11,
2, 1, 0, 2, 1, 0,
5, 4, 3, 5, 4, 3,
8, 7, 6 }; 8, 7, 6
};
unsigned int soTableMirrorDiag1[] = { unsigned int soTableMirrorDiag1[] = {
0, 9, 21, 0, 9, 21,
3, 10, 18, 3, 10, 18,
6, 11, 15, 6,11,15,
1, 4, 7, 16, 19, 22, 1, 4, 7, 16,19,22,
8, 12, 17, 8,12,17,
5, 13, 20, 5, 13, 20,
2, 14, 23 }; 2, 14, 23
};
unsigned int soTableTurnRight[] = { unsigned int soTableTurnRight[] = {
21, 9, 0, 21, 9, 0,
18, 10, 3, 18, 10, 3,
15, 11, 6, 15,11, 6,
22, 19, 16, 7, 4, 1, 22,19,16, 7, 4, 1,
17, 12, 8, 17,12, 8,
20, 13, 5, 20, 13, 5,
23, 14, 2 }; 23, 14, 2
};
unsigned int soTableMirrorVert[] = { unsigned int soTableMirrorVert[] = {
2, 1, 0, 2, 1, 0,
5, 4, 3, 5, 4, 3,
8, 7, 6, 8, 7, 6,
14, 13, 12, 11, 10, 9, 14,13,12, 11,10, 9,
17, 16, 15, 17,16,15,
20, 19, 18, 20, 19, 18,
23, 22, 21 }; 23, 22, 21
};
unsigned int soTableMirrorDiag2[] = { unsigned int soTableMirrorDiag2[] = {
23, 14, 2, 23, 14, 2,
20, 13, 5, 20, 13, 5,
17, 12, 8, 17,12, 8,
22, 19, 16, 7, 4, 1, 22,19,16, 7, 4, 1,
15, 11, 6, 15,11, 6,
18, 10, 3, 18, 10, 3,
21, 9, 0 }; 21, 9, 0
};
// define the four groups // define the four groups
unsigned int squareIndexGroupA[] = { 3, 5, 20, 18 }; unsigned int squareIndexGroupA[] = { 3, 5, 20, 18 };
@ -187,6 +204,7 @@ PerfectAI::PerfectAI(const char *directory)
// //
threadVars = new ThreadVars[getNumThreads()]; threadVars = new ThreadVars[getNumThreads()];
for (unsigned int curThread = 0; curThread < getNumThreads(); curThread++) { for (unsigned int curThread = 0; curThread < getNumThreads(); curThread++) {
threadVars[curThread].parent = this; threadVars[curThread].parent = this;
threadVars[curThread].field = &dummyField; threadVars[curThread].field = &dummyField;
@ -199,13 +217,13 @@ PerfectAI::PerfectAI(const char *directory)
if (strlen(directory) && PathFileExistsA(directory)) { if (strlen(directory) && PathFileExistsA(directory)) {
ssPreCalcVarsFilePath << directory << "\\"; ssPreCalcVarsFilePath << directory << "\\";
} }
ssPreCalcVarsFilePath << "preCalculatedVars.dat"; ssPreCalcVarsFilePath << "preCalculatedVars.dat";
hFilePreCalcVars = CreateFileA(ssPreCalcVarsFilePath.str().c_str(), GENERIC_READ /*| GENERIC_WRITE*/, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); hFilePreCalcVars = CreateFileA(ssPreCalcVarsFilePath.str().c_str(), GENERIC_READ /*| GENERIC_WRITE*/, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
ReadFile(hFilePreCalcVars, &preCalcVarsHeader, sizeof(PreCalcedVarsFileHeader), &dwBytesRead, nullptr); ReadFile(hFilePreCalcVars, &preCalcVarsHeader, sizeof(PreCalcedVarsFileHeader), &dwBytesRead, nullptr);
// vars already stored in file? // vars already stored in file?
if (dwBytesRead) { if (dwBytesRead) {
// Read from file // Read from file
ReadFile(hFilePreCalcVars, layer, sizeof(Layer) * NUM_LAYERS, &dwBytesRead, nullptr); ReadFile(hFilePreCalcVars, layer, sizeof(Layer) * NUM_LAYERS, &dwBytesRead, nullptr);
ReadFile(hFilePreCalcVars, layerIndex, sizeof(unsigned int) * 2 * NUM_STONES_PER_PLAYER_PLUS_ONE * NUM_STONES_PER_PLAYER_PLUS_ONE, &dwBytesRead, nullptr); ReadFile(hFilePreCalcVars, layerIndex, sizeof(unsigned int) * 2 * NUM_STONES_PER_PLAYER_PLUS_ONE * NUM_STONES_PER_PLAYER_PLUS_ONE, &dwBytesRead, nullptr);
@ -308,7 +326,6 @@ PerfectAI::PerfectAI(const char *directory)
// concatenated symmetry operations // concatenated symmetry operations
for (a = 0; a < NUM_SYM_OPERATIONS; a++) { for (a = 0; a < NUM_SYM_OPERATIONS; a++) {
for (b = 0; b < NUM_SYM_OPERATIONS; b++) { for (b = 0; b < NUM_SYM_OPERATIONS; b++) {
// test each symmetry operation // test each symmetry operation
for (c = 0; c < NUM_SYM_OPERATIONS; c++) { for (c = 0; c < NUM_SYM_OPERATIONS; c++) {
@ -353,7 +370,6 @@ PerfectAI::PerfectAI(const char *directory)
indexAB[stateAB] = NOT_INDEXED; indexAB[stateAB] = NOT_INDEXED;
for (stateAB = 0; stateAB < MAX_ANZ_STELLUNGEN_A * MAX_ANZ_STELLUNGEN_B; stateAB++) { for (stateAB = 0; stateAB < MAX_ANZ_STELLUNGEN_A * MAX_ANZ_STELLUNGEN_B; stateAB++) {
// new state ? // new state ?
if (indexAB[stateAB] == NOT_INDEXED) { if (indexAB[stateAB] == NOT_INDEXED) {
@ -399,7 +415,8 @@ PerfectAI::PerfectAI(const char *directory)
for (b = 0; b <= NUM_STONES_PER_PLAYER; b++) { for (b = 0; b <= NUM_STONES_PER_PLAYER; b++) {
if (a + b > numSquaresGroupC + numSquaresGroupD) if (a + b > numSquaresGroupC + numSquaresGroupD)
continue; continue;
originalStateCD_tmp[a][b] = new unsigned int[mOverN[numSquaresGroupC + numSquaresGroupD][a] * mOverN[numSquaresGroupC + numSquaresGroupD - a][b]]; originalStateCD_tmp[a][b] =
new unsigned int[mOverN[numSquaresGroupC + numSquaresGroupD][a] * mOverN[numSquaresGroupC + numSquaresGroupD - a][b]];
anzahlStellungenCD[a][b] = 0; anzahlStellungenCD[a][b] = 0;
} }
} }
@ -408,7 +425,6 @@ PerfectAI::PerfectAI(const char *directory)
memset(indexCD, NOT_INDEXED, 4 * MAX_ANZ_STELLUNGEN_C * MAX_ANZ_STELLUNGEN_D); memset(indexCD, NOT_INDEXED, 4 * MAX_ANZ_STELLUNGEN_C * MAX_ANZ_STELLUNGEN_D);
for (stateCD = 0; stateCD < MAX_ANZ_STELLUNGEN_C * MAX_ANZ_STELLUNGEN_D; stateCD++) { for (stateCD = 0; stateCD < MAX_ANZ_STELLUNGEN_C * MAX_ANZ_STELLUNGEN_D; stateCD++) {
// new state ? // new state ?
if (indexCD[stateCD] == NOT_INDEXED) { if (indexCD[stateCD] == NOT_INDEXED) {
@ -2289,6 +2305,7 @@ void PerfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
} }
} }
} }
} else if (!tv->gameHasFinished) { } else if (!tv->gameHasFinished) {
// test each destination // test each destination
@ -2371,7 +2388,6 @@ void PerfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
// stone mustn't be part of mill // stone mustn't be part of mill
if ((!(tv->field->board[tv->field->neighbour[from][0][0]] == tv->field->curPlayer->id && tv->field->board[tv->field->neighbour[from][0][1]] == tv->field->curPlayer->id)) && (!(tv->field->board[tv->field->neighbour[from][1][0]] == tv->field->curPlayer->id && tv->field->board[tv->field->neighbour[from][1][1]] == tv->field->curPlayer->id))) { if ((!(tv->field->board[tv->field->neighbour[from][0][0]] == tv->field->curPlayer->id && tv->field->board[tv->field->neighbour[from][0][1]] == tv->field->curPlayer->id)) && (!(tv->field->board[tv->field->neighbour[from][1][0]] == tv->field->curPlayer->id && tv->field->board[tv->field->neighbour[from][1][1]] == tv->field->curPlayer->id))) {
// put back stone // put back stone
tv->field->stoneMustBeRemoved = 1; tv->field->stoneMustBeRemoved = 1;
tv->field->board[from] = tv->field->curPlayer->id; tv->field->board[from] = tv->field->curPlayer->id;
@ -2456,12 +2472,14 @@ bool PerfectAI::checkMoveAndSetSituation()
// count completed mills // count completed mills
numberOfMillsCurrentPlayer = 0; numberOfMillsCurrentPlayer = 0;
numberOfMillsOpponentPlayer = 0; numberOfMillsOpponentPlayer = 0;
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (tv->field->board[i] == tv->field->curPlayer->id) if (tv->field->board[i] == tv->field->curPlayer->id)
numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i]; numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i];
else else
numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i]; numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i];
} }
numberOfMillsCurrentPlayer /= 3; numberOfMillsCurrentPlayer /= 3;
numberOfMillsOpponentPlayer /= 3; numberOfMillsOpponentPlayer /= 3;
@ -2634,13 +2652,17 @@ bool PerfectAI::checkGetPredThanGetPoss()
// perform several commands to see in debug mode where the error occurs // perform several commands to see in debug mode where the error occurs
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->board[k]; symField[k] = tv->field->board[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->stonePartOfMill[k]; symField[k] = tv->field->stonePartOfMill[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill);
cout << "predecessor" << endl; cout << "predecessor" << endl;
cout << " layerNum: " << predVars[j].predLayerNumbers << "\tstateNum: " << predVars[j].predStateNumbers << endl; cout << " layerNum: " << predVars[j].predLayerNumbers << "\tstateNum: " << predVars[j].predStateNumbers << endl;
printBoard(threadNo, 0); printBoard(threadNo, 0);
if (predVars[j].playerToMoveChanged) { if (predVars[j].playerToMoveChanged) {
k = tv->field->curPlayer->id; k = tv->field->curPlayer->id;
tv->field->curPlayer->id = tv->field->oppPlayer->id; tv->field->curPlayer->id = tv->field->oppPlayer->id;
@ -2648,6 +2670,7 @@ bool PerfectAI::checkGetPredThanGetPoss()
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
tv->field->board[k] = -1 * tv->field->board[k]; tv->field->board[k] = -1 * tv->field->board[k];
} }
idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities); idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities);
setSituation(threadNo, layerNum, stateNum); setSituation(threadNo, layerNum, stateNum);
cout << "current state" << endl; cout << "current state" << endl;
@ -2659,10 +2682,14 @@ bool PerfectAI::checkGetPredThanGetPoss()
// regard used symmetry operation // regard used symmetry operation
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->board[k]; symField[k] = tv->field->board[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->stonePartOfMill[k]; symField[k] = tv->field->stonePartOfMill[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill);
if (predVars[j].playerToMoveChanged) { if (predVars[j].playerToMoveChanged) {
k = tv->field->curPlayer->id; k = tv->field->curPlayer->id;
tv->field->curPlayer->id = tv->field->oppPlayer->id; tv->field->curPlayer->id = tv->field->oppPlayer->id;
@ -2676,7 +2703,6 @@ bool PerfectAI::checkGetPredThanGetPoss()
// go to each successor state // go to each successor state
for (i = 0; i < numPossibilities; i++) { for (i = 0; i < numPossibilities; i++) {
// move // move
move(threadNo, idPossibility[i], isOpponentLevel, &pBackup, pPossibilities); move(threadNo, idPossibility[i], isOpponentLevel, &pBackup, pPossibilities);
@ -2693,22 +2719,28 @@ bool PerfectAI::checkGetPredThanGetPoss()
// error? // error?
if (i == numPossibilities) { if (i == numPossibilities) {
cout << endl cout << endl
<< "ERROR: Not all predecessors lead to state " << stateNum << " calling move()" << endl; << "ERROR: Not all predecessors lead to state " << stateNum << " calling move()" << endl;
//return false; //return false;
// perform several commands to see in debug mode where the error occurs // perform several commands to see in debug mode where the error occurs
setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers); setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->board[k]; symField[k] = tv->field->board[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->stonePartOfMill[k]; symField[k] = tv->field->stonePartOfMill[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill);
cout << "predecessor" << endl; cout << "predecessor" << endl;
cout << " layerNum: " << predVars[j].predLayerNumbers << "\tstateNum: " << predVars[j].predStateNumbers << endl; cout << " layerNum: " << predVars[j].predLayerNumbers << "\tstateNum: " << predVars[j].predStateNumbers << endl;
printBoard(threadNo, 0); printBoard(threadNo, 0);
if (predVars[j].playerToMoveChanged) { if (predVars[j].playerToMoveChanged) {
k = tv->field->curPlayer->id; k = tv->field->curPlayer->id;
tv->field->curPlayer->id = tv->field->oppPlayer->id; tv->field->curPlayer->id = tv->field->oppPlayer->id;
@ -2716,6 +2748,7 @@ bool PerfectAI::checkGetPredThanGetPoss()
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
tv->field->board[k] = -1 * tv->field->board[k]; tv->field->board[k] = -1 * tv->field->board[k];
} }
idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities); idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities);
setSituation(threadNo, layerNum, stateNum); setSituation(threadNo, layerNum, stateNum);
cout << "current state" << endl; cout << "current state" << endl;
@ -2726,15 +2759,22 @@ bool PerfectAI::checkGetPredThanGetPoss()
k = tv->field->curPlayer->id; k = tv->field->curPlayer->id;
tv->field->curPlayer->id = tv->field->oppPlayer->id; tv->field->curPlayer->id = tv->field->oppPlayer->id;
tv->field->oppPlayer->id = k; tv->field->oppPlayer->id = k;
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
tv->field->board[k] = -1 * tv->field->board[k]; tv->field->board[k] = -1 * tv->field->board[k];
setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers); setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->board[k]; symField[k] = tv->field->board[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) for (k = 0; k < tv->field->size; k++)
symField[k] = tv->field->stonePartOfMill[k]; symField[k] = tv->field->stonePartOfMill[k];
applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill);
printBoard(threadNo, 0); printBoard(threadNo, 0);
idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities); idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities);
move(threadNo, idPossibility[1], isOpponentLevel, &pBackup, pPossibilities); move(threadNo, idPossibility[1], isOpponentLevel, &pBackup, pPossibilities);

View File

@ -186,6 +186,7 @@ protected:
void calcPossibleMoves(Player *player); void calcPossibleMoves(Player *player);
void storePredecessor(unsigned int numberOfMillsCurrentPlayer, unsigned int numberOfMillsOpponentPlayer, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars); void storePredecessor(unsigned int numberOfMillsCurrentPlayer, unsigned int numberOfMillsOpponentPlayer, unsigned int *amountOfPred, RetroAnalysisPredVars *predVars);
}; };
ThreadVars *threadVars; ThreadVars *threadVars;
// database functions // database functions

View File

@ -39,7 +39,6 @@ void RandomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
// must stone be removed ? // must stone be removed ?
if (theField->stoneMustBeRemoved) { if (theField->stoneMustBeRemoved) {
// search a stone from the enemy // search a stone from the enemy
do { do {
from = rand() % theField->size; from = rand() % theField->size;
@ -48,7 +47,6 @@ void RandomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
// still in setting phase ? // still in setting phase ?
} else if (theField->settingPhase) { } else if (theField->settingPhase) {
// search a free square // search a free square
do { do {
from = theField->size; from = theField->size;
@ -57,7 +55,6 @@ void RandomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
// try to push randomly // try to push randomly
} else { } else {
do { do {
// search an own stone // search an own stone
do { do {

View File

@ -58,10 +58,12 @@ MyString::~MyString()
delete[] strA; delete[] strA;
strA = nullptr; strA = nullptr;
} }
if (strW != nullptr) { if (strW != nullptr) {
delete[] strW; delete[] strW;
strW = nullptr; strW = nullptr;
} }
strW = nullptr; strW = nullptr;
strA = nullptr; strA = nullptr;
length = 0; length = 0;
@ -99,8 +101,10 @@ MyString &MyString::assign(const char *cStr)
if (reserved < newReserved) if (reserved < newReserved)
this->~MyString(); this->~MyString();
if (strA == nullptr) if (strA == nullptr)
strA = new char[newReserved]; strA = new char[newReserved];
if (strW == nullptr) if (strW == nullptr)
strW = new WCHAR[newReserved]; strW = new WCHAR[newReserved];
@ -126,8 +130,10 @@ MyString &MyString::assign(const WCHAR *cStr)
if (reserved < newReserved) if (reserved < newReserved)
this->~MyString(); this->~MyString();
if (strA == nullptr) if (strA == nullptr)
strA = new char[newReserved]; strA = new char[newReserved];
if (strW == nullptr) if (strW == nullptr)
strW = new WCHAR[newReserved]; strW = new WCHAR[newReserved];
@ -179,7 +185,6 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
// read each value // read each value
do { do {
// read from buffer if necessary // read from buffer if necessary
if (curBufferPos >= bufferSize - maxValueLengthInBytes) { if (curBufferPos >= bufferSize - maxValueLengthInBytes) {
memcpy(&buffer[0], &buffer[curBufferPos], bufferSize - curBufferPos); memcpy(&buffer[0], &buffer[curBufferPos], bufferSize - curBufferPos);
@ -352,9 +357,11 @@ bool readAsciiData(HANDLE hFile, double *pData, unsigned int numValues, unsigned
if (decimalPos) { if (decimalPos) {
(*pData) += fractionalValue * fractionalFactor[decimalPos]; (*pData) += fractionalValue * fractionalFactor[decimalPos];
} }
if (valIsNegativ) { if (valIsNegativ) {
(*pData) *= -1; (*pData) *= -1;
} }
if (exponent) { if (exponent) {
(*pData) *= pow(10, expIsNegativ ? -1 * exponentialValue : 1); (*pData) *= pow(10, expIsNegativ ? -1 * exponentialValue : 1);
} }

View File

@ -58,9 +58,11 @@ ThreadManager::~ThreadManager()
if (hBarrier != nullptr) if (hBarrier != nullptr)
delete[] hBarrier; delete[] hBarrier;
hBarrier = nullptr; hBarrier = nullptr;
if (hThread != nullptr) if (hThread != nullptr)
delete[] hThread; delete[] hThread;
hThread = nullptr; hThread = nullptr;
if (threadId != nullptr) if (threadId != nullptr)
delete[] threadId; delete[] threadId;
threadId = nullptr; threadId = nullptr;
@ -127,18 +129,24 @@ bool ThreadManager::setNumThreads(unsigned int newNumThreads)
{ {
// cancel if any thread running // cancel if any thread running
EnterCriticalSection(&csBarrier); EnterCriticalSection(&csBarrier);
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) { for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
if (hThread[curThreadNo]) if (hThread[curThreadNo])
return false; return false;
} }
for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) { for (unsigned int curThreadNo = 0; curThreadNo < numThreads; curThreadNo++) {
CloseHandle(hBarrier[curThreadNo]); CloseHandle(hBarrier[curThreadNo]);
} }
numThreads = newNumThreads; 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); hBarrier[curThreadNo] = CreateEvent(nullptr, false, false, nullptr);
} }
LeaveCriticalSection(&csBarrier); LeaveCriticalSection(&csBarrier);
return true; return true;
} }
@ -149,7 +157,6 @@ bool ThreadManager::setNumThreads(unsigned int newNumThreads)
void ThreadManager::pauseExecution() void ThreadManager::pauseExecution()
{ {
for (unsigned int curThread = 0; curThread < numThreads; curThread++) { for (unsigned int curThread = 0; curThread < numThreads; curThread++) {
// unsuspend all threads // unsuspend all threads
if (!executionPaused) { if (!executionPaused) {
SuspendThread(hThread[curThread]); SuspendThread(hThread[curThread]);
@ -158,6 +165,7 @@ void ThreadManager::pauseExecution()
ResumeThread(hThread[curThread]); ResumeThread(hThread[curThread]);
} }
} }
executionPaused = (!executionPaused); executionPaused = (!executionPaused);
} }
@ -170,6 +178,7 @@ void ThreadManager::cancelExecution()
{ {
termineAllThreads = true; termineAllThreads = true;
executionCancelled = true; executionCancelled = true;
if (executionPaused) { if (executionPaused) {
pauseExecution(); pauseExecution();
} }
@ -208,6 +217,7 @@ unsigned int ThreadManager::getThreadNumber()
return curThreadNo; return curThreadNo;
} }
} }
return 0; return 0;
} }
@ -284,12 +294,16 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
// parameters ok? // parameters ok?
if (executionCancelled == true) if (executionCancelled == true)
return TM_RETURN_VALUE_EXECUTION_CANCELLED; return TM_RETURN_VALUE_EXECUTION_CANCELLED;
if (pParameter == nullptr) if (pParameter == nullptr)
return TM_RETURN_VALUE_INVALID_PARAM; return TM_RETURN_VALUE_INVALID_PARAM;
if (scheduleType >= TM_SCHEDULE_NUM_TYPES) if (scheduleType >= TM_SCHEDULE_NUM_TYPES)
return TM_RETURN_VALUE_INVALID_PARAM; return TM_RETURN_VALUE_INVALID_PARAM;
if (inkrement == 0) if (inkrement == 0)
return TM_RETURN_VALUE_INVALID_PARAM; return TM_RETURN_VALUE_INVALID_PARAM;
if (abs(finalValue - initialValue) == abs(inkrement)) if (abs(finalValue - initialValue) == abs(inkrement))
return TM_RETURN_VALUE_INVALID_PARAM; return TM_RETURN_VALUE_INVALID_PARAM;
@ -305,7 +319,6 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
// create threads // 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].pParameter = (pParameter != nullptr ? (void *)(((char *)pParameter) + curThreadNo * parameterStructSize) : nullptr);
forLoopParameters[curThreadNo].threadManager = this; forLoopParameters[curThreadNo].threadManager = this;
forLoopParameters[curThreadNo].threadProc = threadProc; forLoopParameters[curThreadNo].threadProc = threadProc;
@ -335,14 +348,18 @@ unsigned int ThreadManager::executeParallelLoop(DWORD threadProc(void *pParamete
// create suspended thread // create suspended thread
hThread[curThreadNo] = CreateThread(nullptr, dwStackSize, threadForLoop, (LPVOID)(&forLoopParameters[curThreadNo]), CREATE_SUSPENDED, &threadId[curThreadNo]); hThread[curThreadNo] = CreateThread(nullptr, dwStackSize, threadForLoop, (LPVOID)(&forLoopParameters[curThreadNo]), CREATE_SUSPENDED, &threadId[curThreadNo]);
SetThreadPriority(hThread[curThreadNo], THREAD_PRIORITY_BELOW_NORMAL); SetThreadPriority(hThread[curThreadNo], THREAD_PRIORITY_BELOW_NORMAL);
if (hThread[curThreadNo] == nullptr) { if (hThread[curThreadNo] == nullptr) {
for (curThreadNo; curThreadNo > 0; curThreadNo--) { for (curThreadNo; curThreadNo > 0; curThreadNo--) {
CloseHandle(hThread[curThreadNo - 1]); CloseHandle(hThread[curThreadNo - 1]);
hThread[curThreadNo - 1] = nullptr; hThread[curThreadNo - 1] = nullptr;
} }
return TM_RETURN_VALUE_UNEXPECTED_ERROR; return TM_RETURN_VALUE_UNEXPECTED_ERROR;
} }
//DWORD dwThreadAffinityMask = 1 << curThreadNo; //DWORD dwThreadAffinityMask = 1 << curThreadNo;
//SetThreadAffinityMask(hThread[curThreadNo], &dwThreadAffinityMask); //SetThreadAffinityMask(hThread[curThreadNo], &dwThreadAffinityMask);
} }

View File

@ -78,9 +78,11 @@ public:
virtual void initializeElement() virtual void initializeElement()
{ {
}; };
virtual void destroyElement() virtual void destroyElement()
{ {
}; };
virtual void reduce() virtual void reduce()
{ {
}; };