prefect: Rename position to mill and add blank lines
This commit is contained in:
parent
6b610ee3d6
commit
b938e0fd66
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ public:
|
||||||
{
|
{
|
||||||
dummyField.createBoard();
|
dummyField.createBoard();
|
||||||
};
|
};
|
||||||
|
|
||||||
~MillAI()
|
~MillAI()
|
||||||
{
|
{
|
||||||
dummyField.deleteBoard();
|
dummyField.deleteBoard();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,11 @@ public:
|
||||||
virtual void initializeElement()
|
virtual void initializeElement()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void destroyElement()
|
virtual void destroyElement()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void reduce()
|
virtual void reduce()
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue