perfect: Change field->field to field->board

This commit is contained in:
Calcitem 2021-01-20 00:56:03 +08:00
parent 840c412e6a
commit 315bbf2a8a
11 changed files with 191 additions and 191 deletions

View File

@ -68,7 +68,7 @@ int main(void)
// play // play
do { do {
// print field // print board
cout << "\n\n\n\n\n\n\n\n\n\n\n"; cout << "\n\n\n\n\n\n\n\n\n\n\n";
myGame->getComputersChoice(&pushFrom, &pushTo); myGame->getComputersChoice(&pushFrom, &pushTo);
cout << "\n\n"; cout << "\n\n";
@ -111,7 +111,7 @@ int main(void)
} while (!((myGame->getCurrentPlayer() == fieldStruct::playerOne && playerOneHuman) } while (!((myGame->getCurrentPlayer() == fieldStruct::playerOne && playerOneHuman)
|| (myGame->getCurrentPlayer() == fieldStruct::playerTwo && playerTwoHuman))); || (myGame->getCurrentPlayer() == fieldStruct::playerTwo && playerTwoHuman)));
// reprint field // reprint board
break; break;
} }

View File

@ -20,7 +20,7 @@ void fieldStruct::printField()
unsigned int index; unsigned int index;
char c[fieldStruct::size]; char c[fieldStruct::size];
for (index = 0; index < fieldStruct::size; index++) c[index] = GetCharFromStone(this->field[index]); for (index = 0; index < fieldStruct::size; index++) c[index] = GetCharFromStone(this->board[index]);
cout << "current player : " << GetCharFromStone(this->curPlayer->id) << " has " << this->curPlayer->numStones << " stones\n"; cout << "current player : " << GetCharFromStone(this->curPlayer->id) << " has " << this->curPlayer->numStones << " stones\n";
cout << "opponent player : " << GetCharFromStone(this->oppPlayer->id) << " has " << this->oppPlayer->numStones << " stones\n"; cout << "opponent player : " << GetCharFromStone(this->oppPlayer->id) << " has " << this->oppPlayer->numStones << " stones\n";
@ -77,7 +77,7 @@ void fieldStruct::copyField(fieldStruct *destination)
for (i = 0; i < this->size; i++) { for (i = 0; i < this->size; i++) {
destination->field[i] = this->field[i]; destination->board[i] = this->board[i];
destination->warnings[i] = this->warnings[i]; destination->warnings[i] = this->warnings[i];
destination->stonePartOfMill[i] = this->stonePartOfMill[i]; destination->stonePartOfMill[i] = this->stonePartOfMill[i];
@ -111,7 +111,7 @@ void playerStruct::copyPlayer(playerStruct *destination)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: createField() // Name: createField()
// Desc: Creates, but doesn't initialize, the arrays of the of the passed field structure. // Desc: Creates, but doesn't initialize, the arrays of the of the passed board structure.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void fieldStruct::createField() void fieldStruct::createField()
{ {
@ -137,7 +137,7 @@ void fieldStruct::createField()
// zero // zero
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
field[i] = squareIsFree; board[i] = squareIsFree;
warnings[i] = noWarning; warnings[i] = noWarning;
stonePartOfMill[i] = 0; stonePartOfMill[i] = 0;
stoneMoveAble[i][0] = false; stoneMoveAble[i][0] = false;

View File

@ -25,11 +25,11 @@ class playerStruct
public: public:
int id; // static int id; // static
unsigned int warning; // static unsigned int warning; // static
unsigned int numStones; // number of stones of this player on the field unsigned int numStones; // number of stones of this player on the board
unsigned int numStonesMissing; // number of stones, which where stolen by the opponent unsigned int numStonesMissing; // number of stones, which where stolen by the opponent
unsigned int numPossibleMoves; // amount of possible moves unsigned int numPossibleMoves; // amount of possible moves
unsigned int posTo[MAX_NUM_POS_MOVES]; // target field position of a possible move unsigned int posTo[MAX_NUM_POS_MOVES]; // target board position of a possible move
unsigned int posFrom[MAX_NUM_POS_MOVES]; // source field position of a possible move unsigned int posFrom[MAX_NUM_POS_MOVES]; // source board position of a possible move
void copyPlayer(playerStruct *destination); void copyPlayer(playerStruct *destination);
}; };
@ -52,8 +52,8 @@ public:
static const int gameDrawn = 3; // only a nonzero value static const int gameDrawn = 3; // only a nonzero value
// variables // variables
int field[size]; // one of the values above for each field position int board[size]; // one of the values above for each board position
unsigned int warnings[size]; // array containing the warnings for each field position unsigned int warnings[size]; // array containing the warnings for each board position
bool stoneMoveAble[size][4]; // true if stone can be moved in this direction bool stoneMoveAble[size][4]; // true if stone can be moved in this direction
unsigned int stonePartOfMill[size]; // the number of mills, of which this stone is part of unsigned int stonePartOfMill[size]; // the number of mills, of which this stone is part of
unsigned int connectedSquare[size][4]; // static array containg the index of the neighbour or "size" unsigned int connectedSquare[size][4]; // static array containg the index of the neighbour or "size"

View File

@ -112,7 +112,7 @@ unsigned int *miniMaxAI::getPossSettingPhase(unsigned int *numPossibilities, voi
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) { for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
// move possible ? // move possible ?
if (field->field[i] == field->squareIsFree) { if (field->board[i] == field->squareIsFree) {
idPossibility[*numPossibilities] = i; idPossibility[*numPossibilities] = i;
(*numPossibilities)++; (*numPossibilities)++;
@ -146,7 +146,7 @@ unsigned int *miniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
to = field->connectedSquare[from][dir]; to = field->connectedSquare[from][dir];
// move possible ? // move possible ?
if (to < field->size && field->field[from] == field->curPlayer->id && field->field[to] == field->squareIsFree) { if (to < field->size && field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree) {
// stone is moveable // stone is moveable
idPossibility[*numPossibilities] = *numPossibilities; idPossibility[*numPossibilities] = *numPossibilities;
@ -164,7 +164,7 @@ unsigned int *miniMaxAI::getPossNormalMove(unsigned int *numPossibilities, void
for (to = 0; to < field->size; to++) { for (to = 0; to < field->size; to++) {
// move possible ? // move possible ?
if (field->field[from] == field->curPlayer->id && field->field[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES) { if (field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES) {
// stone is moveable // stone is moveable
idPossibility[*numPossibilities] = *numPossibilities; idPossibility[*numPossibilities] = *numPossibilities;
@ -196,7 +196,7 @@ unsigned int *miniMaxAI::getPossStoneRemove(unsigned int *numPossibilities, void
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) { for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
// move possible ? // move possible ?
if (field->field[i] == field->oppPlayer->id && !field->stonePartOfMill[i]) { if (field->board[i] == field->oppPlayer->id && !field->stonePartOfMill[i]) {
idPossibility[*numPossibilities] = i; idPossibility[*numPossibilities] = i;
(*numPossibilities)++; (*numPossibilities)++;
@ -273,8 +273,8 @@ void miniMaxAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
field->settingPhase = oldState->settingPhase; field->settingPhase = oldState->settingPhase;
field->stonesSet = oldState->stonesSet; field->stonesSet = oldState->stonesSet;
field->stoneMustBeRemoved = oldState->stoneMustBeRemoved; field->stoneMustBeRemoved = oldState->stoneMustBeRemoved;
field->field[oldState->from] = oldState->fieldFrom; field->board[oldState->from] = oldState->fieldFrom;
field->field[oldState->to] = oldState->fieldTo; field->board[oldState->to] = oldState->fieldTo;
// very expensive // very expensive
for (int i = 0; i < field->size; i++) { for (int i = 0; i < field->size; i++) {
@ -290,7 +290,7 @@ void miniMaxAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
inline void miniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo, unsigned int stoneThree) inline void miniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo, unsigned int stoneThree)
{ {
// if all 3 fields are occupied by current player than he closed a mill // if all 3 fields are occupied by current player than he closed a mill
if (field->field[stoneOne] == field->curPlayer->id && field->field[stoneTwo] == field->curPlayer->id && field->field[stoneThree] == field->curPlayer->id) { if (field->board[stoneOne] == field->curPlayer->id && field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id) {
field->stonePartOfMill[stoneOne]++; field->stonePartOfMill[stoneOne]++;
field->stonePartOfMill[stoneTwo]++; field->stonePartOfMill[stoneTwo]++;
@ -299,7 +299,7 @@ inline void miniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
} }
// is a mill destroyed ? // is a mill destroyed ?
if (field->field[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree]) { if (field->board[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree]) {
field->stonePartOfMill[stoneOne]--; field->stonePartOfMill[stoneOne]--;
field->stonePartOfMill[stoneTwo]--; field->stonePartOfMill[stoneTwo]--;
@ -307,39 +307,39 @@ inline void miniMaxAI::setWarning(unsigned int stoneOne, unsigned int stoneTwo,
} }
// stone was set // stone was set
if (field->field[stoneOne] == field->curPlayer->id) { if (field->board[stoneOne] == field->curPlayer->id) {
// a warnig was destroyed // a warnig was destroyed
field->warnings[stoneOne] = field->noWarning; field->warnings[stoneOne] = field->noWarning;
// a warning is created // a warning is created
if (field->field[stoneTwo] == field->curPlayer->id && field->field[stoneThree] == field->squareIsFree) field->warnings[stoneThree] |= field->curPlayer->warning; if (field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->squareIsFree) field->warnings[stoneThree] |= field->curPlayer->warning;
if (field->field[stoneThree] == field->curPlayer->id && field->field[stoneTwo] == field->squareIsFree) field->warnings[stoneTwo] |= field->curPlayer->warning; if (field->board[stoneThree] == field->curPlayer->id && field->board[stoneTwo] == field->squareIsFree) field->warnings[stoneTwo] |= field->curPlayer->warning;
// stone was removed // stone was removed
} else if (field->field[stoneOne] == field->squareIsFree) { } else if (field->board[stoneOne] == field->squareIsFree) {
// a warning is created // a warning is created
if (field->field[stoneTwo] == field->curPlayer->id && field->field[stoneThree] == field->curPlayer->id) field->warnings[stoneOne] |= field->curPlayer->warning; if (field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id) field->warnings[stoneOne] |= field->curPlayer->warning;
if (field->field[stoneTwo] == field->oppPlayer->id && field->field[stoneThree] == field->oppPlayer->id) field->warnings[stoneOne] |= field->oppPlayer->warning; if (field->board[stoneTwo] == field->oppPlayer->id && field->board[stoneThree] == field->oppPlayer->id) field->warnings[stoneOne] |= field->oppPlayer->warning;
// a warning is destroyed // a warning is destroyed
if (field->warnings[stoneTwo] && field->field[stoneThree] != field->squareIsFree) { if (field->warnings[stoneTwo] && field->board[stoneThree] != field->squareIsFree) {
// reset warning if necessary // reset warning if necessary
if (field->field[field->neighbour[stoneTwo][0][0]] == field->curPlayer->id && field->field[field->neighbour[stoneTwo][0][1]] == field->curPlayer->id) field->warnings[stoneTwo] = field->curPlayer->warning; if (field->board[field->neighbour[stoneTwo][0][0]] == field->curPlayer->id && field->board[field->neighbour[stoneTwo][0][1]] == field->curPlayer->id) field->warnings[stoneTwo] = field->curPlayer->warning;
else if (field->field[field->neighbour[stoneTwo][1][0]] == field->curPlayer->id && field->field[field->neighbour[stoneTwo][1][1]] == field->curPlayer->id) field->warnings[stoneTwo] = field->curPlayer->warning; else if (field->board[field->neighbour[stoneTwo][1][0]] == field->curPlayer->id && field->board[field->neighbour[stoneTwo][1][1]] == field->curPlayer->id) field->warnings[stoneTwo] = field->curPlayer->warning;
else if (field->field[field->neighbour[stoneTwo][0][0]] == field->oppPlayer->id && field->field[field->neighbour[stoneTwo][0][1]] == field->oppPlayer->id) field->warnings[stoneTwo] = field->oppPlayer->warning; else if (field->board[field->neighbour[stoneTwo][0][0]] == field->oppPlayer->id && field->board[field->neighbour[stoneTwo][0][1]] == field->oppPlayer->id) field->warnings[stoneTwo] = field->oppPlayer->warning;
else if (field->field[field->neighbour[stoneTwo][1][0]] == field->oppPlayer->id && field->field[field->neighbour[stoneTwo][1][1]] == field->oppPlayer->id) field->warnings[stoneTwo] = field->oppPlayer->warning; else if (field->board[field->neighbour[stoneTwo][1][0]] == field->oppPlayer->id && field->board[field->neighbour[stoneTwo][1][1]] == field->oppPlayer->id) field->warnings[stoneTwo] = field->oppPlayer->warning;
else field->warnings[stoneTwo] = field->noWarning; else field->warnings[stoneTwo] = field->noWarning;
} else if (field->warnings[stoneThree] && field->field[stoneTwo] != field->squareIsFree) { } else if (field->warnings[stoneThree] && field->board[stoneTwo] != field->squareIsFree) {
// reset warning if necessary // reset warning if necessary
if (field->field[field->neighbour[stoneThree][0][0]] == field->curPlayer->id && field->field[field->neighbour[stoneThree][0][1]] == field->curPlayer->id) field->warnings[stoneThree] = field->curPlayer->warning; if (field->board[field->neighbour[stoneThree][0][0]] == field->curPlayer->id && field->board[field->neighbour[stoneThree][0][1]] == field->curPlayer->id) field->warnings[stoneThree] = field->curPlayer->warning;
else if (field->field[field->neighbour[stoneThree][1][0]] == field->curPlayer->id && field->field[field->neighbour[stoneThree][1][1]] == field->curPlayer->id) field->warnings[stoneThree] = field->curPlayer->warning; else if (field->board[field->neighbour[stoneThree][1][0]] == field->curPlayer->id && field->board[field->neighbour[stoneThree][1][1]] == field->curPlayer->id) field->warnings[stoneThree] = field->curPlayer->warning;
else if (field->field[field->neighbour[stoneThree][0][0]] == field->oppPlayer->id && field->field[field->neighbour[stoneThree][0][1]] == field->oppPlayer->id) field->warnings[stoneThree] = field->oppPlayer->warning; else if (field->board[field->neighbour[stoneThree][0][0]] == field->oppPlayer->id && field->board[field->neighbour[stoneThree][0][1]] == field->oppPlayer->id) field->warnings[stoneThree] = field->oppPlayer->warning;
else if (field->field[field->neighbour[stoneThree][1][0]] == field->oppPlayer->id && field->field[field->neighbour[stoneThree][1][1]] == field->oppPlayer->id) field->warnings[stoneThree] = field->oppPlayer->warning; else if (field->board[field->neighbour[stoneThree][1][0]] == field->oppPlayer->id && field->board[field->neighbour[stoneThree][1][1]] == field->oppPlayer->id) field->warnings[stoneThree] = field->oppPlayer->warning;
else field->warnings[stoneThree] = field->noWarning; else field->warnings[stoneThree] = field->noWarning;
} }
} }
@ -361,7 +361,7 @@ 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) for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->field[i] == field->oppPlayer->id) { if (field->stoneMustBeRemoved) for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->board[i] == field->oppPlayer->id) {
atLeastOneStoneRemoveAble = true; break; atLeastOneStoneRemoveAble = true; break;
} }
if (!atLeastOneStoneRemoveAble) field->stoneMustBeRemoved = 0; if (!atLeastOneStoneRemoveAble) field->stoneMustBeRemoved = 0;
@ -388,13 +388,13 @@ inline void miniMaxAI::updatePossibleMoves(unsigned int stone, playerStruct *sto
if (ignoreStone == neighbor) continue; if (ignoreStone == neighbor) 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->field[neighbor] == field->squareIsFree) { if (field->board[neighbor] == field->squareIsFree) {
if (stoneRemoved) stoneOwner->numPossibleMoves--; if (stoneRemoved) stoneOwner->numPossibleMoves--;
else stoneOwner->numPossibleMoves++; else stoneOwner->numPossibleMoves++;
// 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->field[neighbor] == field->curPlayer->id) { } else if (field->board[neighbor] == field->curPlayer->id) {
if (stoneRemoved) field->curPlayer->numPossibleMoves++; if (stoneRemoved) field->curPlayer->numPossibleMoves++;
else field->curPlayer->numPossibleMoves--; else field->curPlayer->numPossibleMoves--;
@ -422,10 +422,10 @@ inline void miniMaxAI::setStone(unsigned int to, backupStruct *backup)
backup->from = field->size; backup->from = field->size;
backup->to = to; backup->to = to;
backup->fieldFrom = field->size; backup->fieldFrom = field->size;
backup->fieldTo = field->field[to]; backup->fieldTo = field->board[to];
// set stone into field // set stone into board
field->field[to] = field->curPlayer->id; field->board[to] = field->curPlayer->id;
field->curPlayer->numStones++; field->curPlayer->numStones++;
field->stonesSet++; field->stonesSet++;
@ -448,12 +448,12 @@ inline void miniMaxAI::normalMove(unsigned int from, unsigned int to, backupStru
// backup // backup
backup->from = from; backup->from = from;
backup->to = to; backup->to = to;
backup->fieldFrom = field->field[from]; backup->fieldFrom = field->board[from];
backup->fieldTo = field->field[to]; backup->fieldTo = field->board[to];
// set stone into field // set stone into board
field->field[from] = field->squareIsFree; field->board[from] = field->squareIsFree;
field->field[to] = field->curPlayer->id; field->board[to] = field->curPlayer->id;
// update possible moves // update possible moves
updatePossibleMoves(from, field->curPlayer, true, to); updatePossibleMoves(from, field->curPlayer, true, to);
@ -472,11 +472,11 @@ inline void miniMaxAI::removeStone(unsigned int from, backupStruct *backup)
// backup // backup
backup->from = from; backup->from = from;
backup->to = field->size; backup->to = field->size;
backup->fieldFrom = field->field[from]; backup->fieldFrom = field->board[from];
backup->fieldTo = field->size; backup->fieldTo = field->size;
// remove stone // remove stone
field->field[from] = field->squareIsFree; field->board[from] = field->squareIsFree;
field->oppPlayer->numStones--; field->oppPlayer->numStones--;
field->oppPlayer->numStonesMissing++; field->oppPlayer->numStonesMissing++;
field->stoneMustBeRemoved--; field->stoneMustBeRemoved--;

View File

@ -30,7 +30,7 @@ using namespace std; // use standard library namespace
/*** Wiki *************************************************************************************************************************** /*** Wiki ***************************************************************************************************************************
player: player:
layer: The states are divided in layers. For example depending on number of stones on the field. layer: The states are divided in layers. For example depending on number of stones on the board.
state: A unique game state reprensiting a current game situation. state: A unique game state reprensiting a current game situation.
situation: Used as synonym to state. situation: Used as synonym to state.
knot: Each knot of the graph corresponds to a game state. The knots are connected by possible valid moves. knot: Each knot of the graph corresponds to a game state. The knots are connected by possible valid moves.

View File

@ -37,8 +37,8 @@ protected:
float value; float value;
bool gameHasFinished; bool gameHasFinished;
bool settingPhase; bool settingPhase;
int fieldFrom, fieldTo; // value of field int fieldFrom, fieldTo; // value of board
unsigned int from, to; // index of field unsigned int from, to; // index of board
unsigned int curNumStones, oppNumStones; unsigned int curNumStones, oppNumStones;
unsigned int curPosMoves, oppPosMoves; unsigned int curPosMoves, oppPosMoves;
unsigned int curMissStones, oppMissStones; unsigned int curMissStones, oppMissStones;
@ -50,9 +50,9 @@ protected:
}; };
// Variables // Variables
fieldStruct *field; // pointer of the current field [changed by move()] fieldStruct *field; // pointer of the current board [changed by move()]
float currentValue; // value of current situation for field->currentPlayer float currentValue; // value of current situation for board->currentPlayer
bool gameHasFinished; // someone has won or current field is full bool gameHasFinished; // someone has won or current board is full
int ownId; // id of the player who called the play()-function int ownId; // id of the player who called the play()-function
unsigned int curSearchDepth; // current level unsigned int curSearchDepth; // current level

View File

@ -365,10 +365,10 @@ perfectAI::perfectAI(const char *directory)
// new state ? // new state ?
if (indexAB[stateAB] == NOT_INDEXED) { if (indexAB[stateAB] == NOT_INDEXED) {
// zero field // zero board
for (i = 0; i < fieldStruct::size; i++) myField[i] = FREE_SQUARE; for (i = 0; i < fieldStruct::size; i++) myField[i] = FREE_SQUARE;
// make field // make board
myField[squareIndexGroupA[0]] = (stateAB / powerOfThree[7]) % 3; myField[squareIndexGroupA[0]] = (stateAB / powerOfThree[7]) % 3;
myField[squareIndexGroupA[1]] = (stateAB / powerOfThree[6]) % 3; myField[squareIndexGroupA[1]] = (stateAB / powerOfThree[6]) % 3;
myField[squareIndexGroupA[2]] = (stateAB / powerOfThree[5]) % 3; myField[squareIndexGroupA[2]] = (stateAB / powerOfThree[5]) % 3;
@ -413,10 +413,10 @@ perfectAI::perfectAI(const char *directory)
// new state ? // new state ?
if (indexCD[stateCD] == NOT_INDEXED) { if (indexCD[stateCD] == NOT_INDEXED) {
// zero field // zero board
for (i = 0; i < fieldStruct::size; i++) myField[i] = FREE_SQUARE; for (i = 0; i < fieldStruct::size; i++) myField[i] = FREE_SQUARE;
// make field // make board
myField[squareIndexGroupC[0]] = (stateCD / powerOfThree[15]) % 3; myField[squareIndexGroupC[0]] = (stateCD / powerOfThree[15]) % 3;
myField[squareIndexGroupC[1]] = (stateCD / powerOfThree[14]) % 3; myField[squareIndexGroupC[1]] = (stateCD / powerOfThree[14]) % 3;
myField[squareIndexGroupC[2]] = (stateCD / powerOfThree[13]) % 3; myField[squareIndexGroupC[2]] = (stateCD / powerOfThree[13]) % 3;
@ -708,7 +708,7 @@ void perfectAI::prepareDatabaseCalculation()
// only prepare layers? // only prepare layers?
unsigned int curThread; unsigned int curThread;
// create a temporary field // create a temporary board
for (curThread = 0; curThread < getNumThreads(); curThread++) { for (curThread = 0; curThread < getNumThreads(); curThread++) {
threadVars[curThread].field = new fieldStruct(); threadVars[curThread].field = new fieldStruct();
threadVars[curThread].field->createField(); threadVars[curThread].field->createField();
@ -821,7 +821,7 @@ unsigned int *perfectAI::threadVarsStruct::getPossSettingPhase(unsigned int *num
// check if an opponent stone can be removed // check if an opponent stone can be removed
for (stoneCanBeRemoved = false, i = 0; i < field->size; i++) { for (stoneCanBeRemoved = false, i = 0; i < field->size; i++) {
if (field->field[i] == field->oppPlayer->id && field->stonePartOfMill[i] == 0) { if (field->board[i] == field->oppPlayer->id && field->stonePartOfMill[i] == 0) {
stoneCanBeRemoved = true; stoneCanBeRemoved = true;
break; break;
} }
@ -831,12 +831,12 @@ unsigned int *perfectAI::threadVarsStruct::getPossSettingPhase(unsigned int *num
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) { for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
// move possible ? // move possible ?
if (field->field[i] == field->squareIsFree) { if (field->board[i] == field->squareIsFree) {
// check if a mill is beeing closed // check if a mill is beeing closed
numberOfMillsBeeingClosed = 0; numberOfMillsBeeingClosed = 0;
if (field->curPlayer->id == field->field[field->neighbour[i][0][0]] && field->curPlayer->id == field->field[field->neighbour[i][0][1]]) numberOfMillsBeeingClosed++; if (field->curPlayer->id == field->board[field->neighbour[i][0][0]] && field->curPlayer->id == field->board[field->neighbour[i][0][1]]) numberOfMillsBeeingClosed++;
if (field->curPlayer->id == field->field[field->neighbour[i][1][0]] && field->curPlayer->id == field->field[field->neighbour[i][1][1]]) numberOfMillsBeeingClosed++; if (field->curPlayer->id == field->board[field->neighbour[i][1][0]] && field->curPlayer->id == field->board[field->neighbour[i][1][1]]) numberOfMillsBeeingClosed++;
// Version 15: don't allow to close two mills at once // Version 15: don't allow to close two mills at once
// Version 25: don't allow to close a mill, although no stone can be removed from the opponent // Version 25: don't allow to close a mill, although no stone can be removed from the opponent
@ -875,7 +875,7 @@ unsigned int *perfectAI::threadVarsStruct::getPossNormalMove(unsigned int *numPo
to = field->connectedSquare[from][dir]; to = field->connectedSquare[from][dir];
// move possible ? // move possible ?
if (to < field->size && field->field[from] == field->curPlayer->id && field->field[to] == field->squareIsFree) { if (to < field->size && field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree) {
// stone is moveable // stone is moveable
idPossibility[*numPossibilities] = *numPossibilities; idPossibility[*numPossibilities] = *numPossibilities;
@ -893,7 +893,7 @@ unsigned int *perfectAI::threadVarsStruct::getPossNormalMove(unsigned int *numPo
for (to = 0; to < field->size; to++) { for (to = 0; to < field->size; to++) {
// move possible ? // move possible ?
if (field->field[from] == field->curPlayer->id && field->field[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES) { if (field->board[from] == field->curPlayer->id && field->board[to] == field->squareIsFree && *numPossibilities < MAX_NUM_POS_MOVES) {
// stone is moveable // stone is moveable
idPossibility[*numPossibilities] = *numPossibilities; idPossibility[*numPossibilities] = *numPossibilities;
@ -927,7 +927,7 @@ unsigned int *perfectAI::threadVarsStruct::getPossStoneRemove(unsigned int *numP
for ((*numPossibilities) = 0, i = 0; i < field->size; i++) { for ((*numPossibilities) = 0, i = 0; i < field->size; i++) {
// move possible ? // move possible ?
if (field->field[i] == field->oppPlayer->id && !field->stonePartOfMill[i]) { if (field->board[i] == field->oppPlayer->id && !field->stonePartOfMill[i]) {
idPossibility[*numPossibilities] = i; idPossibility[*numPossibilities] = i;
(*numPossibilities)++; (*numPossibilities)++;
@ -958,9 +958,9 @@ unsigned int *perfectAI::getPossibilities(unsigned int threadNo, unsigned int *n
// count completed mills // count completed mills
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (tv->field->field[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i]; if (tv->field->board[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i];
else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i]; else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i];
if (tv->field->stonePartOfMill[i] == 0 && tv->field->field[i] == tv->field->curPlayer->id) aStoneCanBeRemovedFromCurPlayer = true; if (tv->field->stonePartOfMill[i] == 0 && tv->field->board[i] == tv->field->curPlayer->id) aStoneCanBeRemovedFromCurPlayer = true;
} }
numberOfMillsCurrentPlayer /= 3; numberOfMillsCurrentPlayer /= 3;
numberOfMillsOpponentPlayer /= 3; numberOfMillsOpponentPlayer /= 3;
@ -1023,8 +1023,8 @@ void perfectAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
tv->field->settingPhase = oldState->settingPhase; tv->field->settingPhase = oldState->settingPhase;
tv->field->stonesSet = oldState->stonesSet; tv->field->stonesSet = oldState->stonesSet;
tv->field->stoneMustBeRemoved = oldState->stoneMustBeRemoved; tv->field->stoneMustBeRemoved = oldState->stoneMustBeRemoved;
tv->field->field[oldState->from] = oldState->fieldFrom; tv->field->board[oldState->from] = oldState->fieldFrom;
tv->field->field[oldState->to] = oldState->fieldTo; tv->field->board[oldState->to] = oldState->fieldTo;
// very expensive // very expensive
for (int i = 0; i < tv->field->size; i++) { for (int i = 0; i < tv->field->size; i++) {
@ -1039,7 +1039,7 @@ void perfectAI::undo(unsigned int threadNo, unsigned int idPossibility, bool opp
inline void perfectAI::threadVarsStruct::setWarning(unsigned int stoneOne, unsigned int stoneTwo, unsigned int stoneThree) inline void perfectAI::threadVarsStruct::setWarning(unsigned int stoneOne, unsigned int stoneTwo, unsigned int stoneThree)
{ {
// if all 3 fields are occupied by current player than he closed a mill // if all 3 fields are occupied by current player than he closed a mill
if (field->field[stoneOne] == field->curPlayer->id && field->field[stoneTwo] == field->curPlayer->id && field->field[stoneThree] == field->curPlayer->id) { if (field->board[stoneOne] == field->curPlayer->id && field->board[stoneTwo] == field->curPlayer->id && field->board[stoneThree] == field->curPlayer->id) {
field->stonePartOfMill[stoneOne]++; field->stonePartOfMill[stoneOne]++;
field->stonePartOfMill[stoneTwo]++; field->stonePartOfMill[stoneTwo]++;
field->stonePartOfMill[stoneThree]++; field->stonePartOfMill[stoneThree]++;
@ -1047,7 +1047,7 @@ inline void perfectAI::threadVarsStruct::setWarning(unsigned int stoneOne, unsig
} }
// is a mill destroyed ? // is a mill destroyed ?
if (field->field[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree]) { if (field->board[stoneOne] == field->squareIsFree && field->stonePartOfMill[stoneOne] && field->stonePartOfMill[stoneTwo] && field->stonePartOfMill[stoneThree]) {
field->stonePartOfMill[stoneOne]--; field->stonePartOfMill[stoneOne]--;
field->stonePartOfMill[stoneTwo]--; field->stonePartOfMill[stoneTwo]--;
field->stonePartOfMill[stoneThree]--; field->stonePartOfMill[stoneThree]--;
@ -1070,7 +1070,7 @@ inline void perfectAI::threadVarsStruct::updateWarning(unsigned int firstStone,
// 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) for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->field[i] == field->oppPlayer->id) { if (field->stoneMustBeRemoved) for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->board[i] == field->oppPlayer->id) {
atLeastOneStoneRemoveAble = true; break; atLeastOneStoneRemoveAble = true; break;
} }
if (!atLeastOneStoneRemoveAble) field->stoneMustBeRemoved = 0; if (!atLeastOneStoneRemoveAble) field->stoneMustBeRemoved = 0;
@ -1097,13 +1097,13 @@ inline void perfectAI::threadVarsStruct::updatePossibleMoves(unsigned int stone,
if (ignoreStone == neighbor) continue; if (ignoreStone == neighbor) 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->field[neighbor] == field->squareIsFree) { if (field->board[neighbor] == field->squareIsFree) {
if (stoneRemoved) stoneOwner->numPossibleMoves--; if (stoneRemoved) stoneOwner->numPossibleMoves--;
else stoneOwner->numPossibleMoves++; else stoneOwner->numPossibleMoves++;
// 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->field[neighbor] == field->curPlayer->id) { } else if (field->board[neighbor] == field->curPlayer->id) {
if (stoneRemoved) field->curPlayer->numPossibleMoves++; if (stoneRemoved) field->curPlayer->numPossibleMoves++;
else field->curPlayer->numPossibleMoves--; else field->curPlayer->numPossibleMoves--;
@ -1131,10 +1131,10 @@ inline void perfectAI::threadVarsStruct::setStone(unsigned int to, backupStruct
backup->from = field->size; backup->from = field->size;
backup->to = to; backup->to = to;
backup->fieldFrom = field->size; backup->fieldFrom = field->size;
backup->fieldTo = field->field[to]; backup->fieldTo = field->board[to];
// set stone into field // set stone into board
field->field[to] = field->curPlayer->id; field->board[to] = field->curPlayer->id;
field->curPlayer->numStones++; field->curPlayer->numStones++;
field->stonesSet++; field->stonesSet++;
@ -1157,12 +1157,12 @@ inline void perfectAI::threadVarsStruct::normalMove(unsigned int from, unsigned
// backup // backup
backup->from = from; backup->from = from;
backup->to = to; backup->to = to;
backup->fieldFrom = field->field[from]; backup->fieldFrom = field->board[from];
backup->fieldTo = field->field[to]; backup->fieldTo = field->board[to];
// set stone into field // set stone into board
field->field[from] = field->squareIsFree; field->board[from] = field->squareIsFree;
field->field[to] = field->curPlayer->id; field->board[to] = field->curPlayer->id;
// update possible moves // update possible moves
updatePossibleMoves(from, field->curPlayer, true, to); updatePossibleMoves(from, field->curPlayer, true, to);
@ -1181,11 +1181,11 @@ inline void perfectAI::threadVarsStruct::removeStone(unsigned int from, backupSt
// backup // backup
backup->from = from; backup->from = from;
backup->to = field->size; backup->to = field->size;
backup->fieldFrom = field->field[from]; backup->fieldFrom = field->board[from];
backup->fieldTo = field->size; backup->fieldTo = field->size;
// remove stone // remove stone
field->field[from] = field->squareIsFree; field->board[from] = field->squareIsFree;
field->oppPlayer->numStones--; field->oppPlayer->numStones--;
field->oppPlayer->numStonesMissing++; field->oppPlayer->numStonesMissing++;
field->stoneMustBeRemoved--; field->stoneMustBeRemoved--;
@ -1523,9 +1523,9 @@ unsigned int perfectAI::threadVarsStruct::getLayerAndStateNumber(unsigned int &l
// make white and black fields // make white and black fields
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (field->field[i] == fieldStruct::squareIsFree) { if (field->board[i] == fieldStruct::squareIsFree) {
myField[i] = FREE_SQUARE; myField[i] = FREE_SQUARE;
} else if (field->field[i] == field->curPlayer->id) { } else if (field->board[i] == field->curPlayer->id) {
myField[i] = WHITE_STONE; myField[i] = WHITE_STONE;
if (fieldPosIsOfGroup[i] == GROUP_C) wCD++; if (fieldPosIsOfGroup[i] == GROUP_C) wCD++;
if (fieldPosIsOfGroup[i] == GROUP_D) wCD++; if (fieldPosIsOfGroup[i] == GROUP_D) wCD++;
@ -1626,7 +1626,7 @@ bool perfectAI::setSituation(unsigned int threadNo, unsigned int layerNum, unsig
tv->field->curPlayer->numStones = numWhiteStones; tv->field->curPlayer->numStones = numWhiteStones;
tv->field->oppPlayer->numStones = numBlackStones; tv->field->oppPlayer->numStones = numBlackStones;
// reconstruct field->field[] // reconstruct board->board[]
stateNumberWithInSubLayer = (stateNumber / MAX_NUM_STONES_REMOVED_MINUS_1) - layer[layerNum].subLayer[layer[layerNum].subLayerIndexCD[wCD][bCD]].minIndex; stateNumberWithInSubLayer = (stateNumber / MAX_NUM_STONES_REMOVED_MINUS_1) - layer[layerNum].subLayer[layer[layerNum].subLayerIndexCD[wCD][bCD]].minIndex;
stateNumberWithInAB = stateNumberWithInSubLayer / anzahlStellungenCD[wCD][bCD]; stateNumberWithInAB = stateNumberWithInSubLayer / anzahlStellungenCD[wCD][bCD];
stateNumberWithInCD = stateNumberWithInSubLayer % anzahlStellungenCD[wCD][bCD]; stateNumberWithInCD = stateNumberWithInSubLayer % anzahlStellungenCD[wCD][bCD];
@ -1665,11 +1665,11 @@ bool perfectAI::setSituation(unsigned int threadNo, unsigned int layerNum, unsig
// apply symmetry operation on group A&B // apply symmetry operation on group A&B
applySymmetrieOperationOnField(reverseSymOperation[symmetryOperationCD[stateCD]], myField, symField); applySymmetrieOperationOnField(reverseSymOperation[symmetryOperationCD[stateCD]], myField, symField);
// translate symField[] to field->field[] // translate symField[] to board->board[]
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (symField[i] == FREE_SQUARE) tv->field->field[i] = fieldStruct::squareIsFree; if (symField[i] == FREE_SQUARE) tv->field->board[i] = fieldStruct::squareIsFree;
else if (symField[i] == WHITE_STONE) tv->field->field[i] = tv->field->curPlayer->id; else if (symField[i] == WHITE_STONE) tv->field->board[i] = tv->field->curPlayer->id;
else tv->field->field[i] = tv->field->oppPlayer->id; else tv->field->board[i] = tv->field->oppPlayer->id;
} }
// calc possible moves // calc possible moves
@ -1692,7 +1692,7 @@ bool perfectAI::setSituation(unsigned int threadNo, unsigned int layerNum, unsig
// count completed mills // count completed mills
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (tv->field->field[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i]; if (tv->field->board[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i];
else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i]; else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i];
} }
@ -1726,13 +1726,13 @@ bool perfectAI::setSituation(unsigned int threadNo, unsigned int layerNum, unsig
// precalc aStoneCanBeRemovedFromCurPlayer // precalc aStoneCanBeRemovedFromCurPlayer
for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) { for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) {
if (tv->field->stonePartOfMill[i] == 0 && tv->field->field[i] == tv->field->curPlayer->id) { if (tv->field->stonePartOfMill[i] == 0 && tv->field->board[i] == tv->field->curPlayer->id) {
aStoneCanBeRemovedFromCurPlayer = true; aStoneCanBeRemovedFromCurPlayer = true;
break; break;
} }
} }
// test if field is ok // test if board is ok
return tv->fieldIntegrityOK(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, aStoneCanBeRemovedFromCurPlayer); return tv->fieldIntegrityOK(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, aStoneCanBeRemovedFromCurPlayer);
} }
@ -1749,10 +1749,10 @@ void perfectAI::threadVarsStruct::calcPossibleMoves(playerStruct *player)
for (j = 0; j < fieldStruct::size; j++) { for (j = 0; j < fieldStruct::size; j++) {
// is stone from player ? // is stone from player ?
if (field->field[i] != player->id) continue; if (field->board[i] != player->id) continue;
// is destination free ? // is destination free ?
if (field->field[j] != field->squareIsFree) continue; if (field->board[j] != field->squareIsFree) continue;
// when current player has only 3 stones he is allowed to spring his stone // when current player has only 3 stones he is allowed to spring his stone
if (player->numStones > 3 || field->settingPhase) { if (player->numStones > 3 || field->settingPhase) {
@ -1777,10 +1777,10 @@ void perfectAI::threadVarsStruct::calcPossibleMoves(playerStruct *player)
void perfectAI::threadVarsStruct::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour) void perfectAI::threadVarsStruct::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour)
{ {
// locals // locals
int rowOwner = field->field[stone]; int rowOwner = field->board[stone];
// mill closed ? // mill closed ?
if (rowOwner != field->squareIsFree && field->field[firstNeighbour] == rowOwner && field->field[secondNeighbour] == rowOwner) { if (rowOwner != field->squareIsFree && field->board[firstNeighbour] == rowOwner && field->board[secondNeighbour] == rowOwner) {
field->stonePartOfMill[stone]++; field->stonePartOfMill[stone]++;
field->stonePartOfMill[firstNeighbour]++; field->stonePartOfMill[firstNeighbour]++;
@ -1925,9 +1925,9 @@ void perfectAI::getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *n
*numSymmetricStates = 0; *numSymmetricStates = 0;
*symStateNumbers = symmetricStateNumberArray; *symStateNumbers = symmetricStateNumberArray;
// save current field // save current board
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
originalField[i] = tv->field->field[i]; originalField[i] = tv->field->board[i];
originalPartOfMill[i] = tv->field->stonePartOfMill[i]; originalPartOfMill[i] = tv->field->stonePartOfMill[i];
} }
@ -1935,7 +1935,7 @@ void perfectAI::getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *n
for (symmetryOperation = 0; symmetryOperation < NUM_SYM_OPERATIONS; symmetryOperation++) { for (symmetryOperation = 0; symmetryOperation < NUM_SYM_OPERATIONS; symmetryOperation++) {
// appy symmetry operation // appy symmetry operation
applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalField, (unsigned int *)tv->field->field); applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalField, (unsigned int *)tv->field->board);
applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalPartOfMill, (unsigned int *)tv->field->stonePartOfMill); applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalPartOfMill, (unsigned int *)tv->field->stonePartOfMill);
getLayerAndStateNumber(threadNo, layerNum, stateNum); getLayerAndStateNumber(threadNo, layerNum, stateNum);
@ -1943,9 +1943,9 @@ void perfectAI::getSymStateNumWithDoubles(unsigned int threadNo, unsigned int *n
(*numSymmetricStates)++; (*numSymmetricStates)++;
} }
// restore original field // restore original board
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
tv->field->field[i] = originalField[i]; tv->field->board[i] = originalField[i];
tv->field->stonePartOfMill[i] = originalPartOfMill[i]; tv->field->stonePartOfMill[i] = originalPartOfMill[i];
} }
} }
@ -1962,7 +1962,7 @@ bool perfectAI::threadVarsStruct::fieldIntegrityOK(unsigned int numberOfMillsCur
// when stone is going to be removed than at least one opponent stone mustn't be part of a mill // when stone is going to be removed than at least one opponent stone mustn't be part of a mill
if (numberOfMillsOpponentPlayer > 0 && field->stoneMustBeRemoved) { if (numberOfMillsOpponentPlayer > 0 && field->stoneMustBeRemoved) {
for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->oppPlayer->id == field->field[i]) break; for (i = 0; i < field->size; i++) if (field->stonePartOfMill[i] == 0 && field->oppPlayer->id == field->board[i]) break;
if (i == field->size) return false; if (i == field->size) return false;
} }
@ -2039,8 +2039,8 @@ void perfectAI::threadVarsStruct::storePredecessor(unsigned int numberOfMillsCur
// store only if state is valid // store only if state is valid
if (fieldIntegrityOK(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, false)) { if (fieldIntegrityOK(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, false)) {
// save current field // save current board
for (i = 0; i < fieldStruct::size; i++) originalField[i] = field->field[i]; for (i = 0; i < fieldStruct::size; i++) originalField[i] = field->board[i];
// add all symmetric states // add all symmetric states
for (symmetryOperation = 0; symmetryOperation < NUM_SYM_OPERATIONS; symmetryOperation++) { for (symmetryOperation = 0; symmetryOperation < NUM_SYM_OPERATIONS; symmetryOperation++) {
@ -2049,7 +2049,7 @@ void perfectAI::threadVarsStruct::storePredecessor(unsigned int numberOfMillsCur
if (symmetryOperation == SO_DO_NOTHING || parent->isSymOperationInvariantOnGroupCD(symmetryOperation, originalField)) { if (symmetryOperation == SO_DO_NOTHING || parent->isSymOperationInvariantOnGroupCD(symmetryOperation, originalField)) {
// appy symmetry operation // appy symmetry operation
parent->applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalField, (unsigned int *)field->field); parent->applySymmetrieOperationOnField(symmetryOperation, (unsigned int *)originalField, (unsigned int *)field->board);
symOpApplied = getLayerAndStateNumber(predLayerNum, predStateNum); symOpApplied = getLayerAndStateNumber(predLayerNum, predStateNum);
predVars[*amountOfPred].predSymOperation = parent->concSymOperation[symmetryOperation][symOpApplied]; predVars[*amountOfPred].predSymOperation = parent->concSymOperation[symmetryOperation][symOpApplied];
@ -2063,8 +2063,8 @@ void perfectAI::threadVarsStruct::storePredecessor(unsigned int numberOfMillsCur
} }
} }
// restore original field // restore original board
for (i = 0; i < fieldStruct::size; i++) field->field[i] = originalField[i]; for (i = 0; i < fieldStruct::size; i++) field->board[i] = originalField[i];
} }
} }
@ -2076,12 +2076,12 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
{ {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// the important variables, which much be updated for the getLayerAndStateNumber function are the following ones: // the important variables, which much be updated for the getLayerAndStateNumber function are the following ones:
// - field->curPlayer->numStones // - board->curPlayer->numStones
// - field->oppPlayer->numStones // - board->oppPlayer->numStones
// - field->curPlayer->id // - board->curPlayer->id
// - field->field // - board->board
// - field->stoneMustBeRemoved // - board->stoneMustBeRemoved
// - field->settingPhase // - board->settingPhase
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// locals // locals
@ -2098,7 +2098,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
// count completed mills // count completed mills
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (tv->field->field[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i]; if (tv->field->board[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i];
else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i]; else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i];
} }
@ -2107,7 +2107,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
// precalc aStoneCanBeRemovedFromCurPlayer // precalc aStoneCanBeRemovedFromCurPlayer
for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) { for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) {
if (tv->field->stonePartOfMill[i] == 0 && tv->field->field[i] == tv->field->curPlayer->id) { if (tv->field->stonePartOfMill[i] == 0 && tv->field->board[i] == tv->field->curPlayer->id) {
aStoneCanBeRemovedFromCurPlayer = true; aStoneCanBeRemovedFromCurPlayer = true;
break; break;
} }
@ -2131,7 +2131,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
for (to = 0; to < tv->field->size; to++) { for (to = 0; to < tv->field->size; to++) {
// was opponent player stone owner? // was opponent player stone owner?
if (tv->field->field[to] != (tv->field->stoneMustBeRemoved ? tv->field->curPlayer->id : tv->field->oppPlayer->id)) continue; if (tv->field->board[to] != (tv->field->stoneMustBeRemoved ? tv->field->curPlayer->id : tv->field->oppPlayer->id)) continue;
// when stone is going to be removed than a mill must be closed // when stone is going to be removed than a mill must be closed
if (tv->field->stoneMustBeRemoved && tv->field->stonePartOfMill[to] == 0) continue; if (tv->field->stoneMustBeRemoved && tv->field->stonePartOfMill[to] == 0) continue;
@ -2146,7 +2146,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
from = tv->field->connectedSquare[to][dir]; from = tv->field->connectedSquare[to][dir];
// move possible ? // move possible ?
if (from < tv->field->size && tv->field->field[from] == tv->field->squareIsFree) { if (from < tv->field->size && tv->field->board[from] == tv->field->squareIsFree) {
if (millWasClosed) { if (millWasClosed) {
numberOfMillsCurrentPlayer -= tv->field->stonePartOfMill[to]; numberOfMillsCurrentPlayer -= tv->field->stonePartOfMill[to];
@ -2164,15 +2164,15 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
} }
// make move // make move
tv->field->field[from] = tv->field->field[to]; tv->field->board[from] = tv->field->board[to];
tv->field->field[to] = tv->field->squareIsFree; tv->field->board[to] = tv->field->squareIsFree;
// store predecessor // store predecessor
tv->storePredecessor(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, amountOfPred, predVars); tv->storePredecessor(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, amountOfPred, predVars);
// undo move // undo move
tv->field->field[to] = tv->field->field[from]; tv->field->board[to] = tv->field->board[from];
tv->field->field[from] = tv->field->squareIsFree; tv->field->board[from] = tv->field->squareIsFree;
if (millWasClosed) { if (millWasClosed) {
numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[to]; numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[to];
@ -2198,7 +2198,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
for (to = 0; to < tv->field->size; to++) { for (to = 0; to < tv->field->size; to++) {
// when stone must be removed than current player closed a mill, otherwise the opponent did a common spring move // when stone must be removed than current player closed a mill, otherwise the opponent did a common spring move
if (tv->field->field[to] != (tv->field->stoneMustBeRemoved ? tv->field->curPlayer->id : tv->field->oppPlayer->id)) continue; if (tv->field->board[to] != (tv->field->stoneMustBeRemoved ? tv->field->curPlayer->id : tv->field->oppPlayer->id)) continue;
// when stone is going to be removed than a mill must be closed // when stone is going to be removed than a mill must be closed
if (tv->field->stoneMustBeRemoved && tv->field->stonePartOfMill[to] == 0) continue; if (tv->field->stoneMustBeRemoved && tv->field->stonePartOfMill[to] == 0) continue;
@ -2210,7 +2210,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
for (from = 0; from < tv->field->size; from++) { for (from = 0; from < tv->field->size; from++) {
// move possible ? // move possible ?
if (tv->field->field[from] == tv->field->squareIsFree) { if (tv->field->board[from] == tv->field->squareIsFree) {
// was a mill closed? // was a mill closed?
if (millWasClosed) { if (millWasClosed) {
@ -2229,15 +2229,15 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
} }
// make move // make move
tv->field->field[from] = tv->field->field[to]; tv->field->board[from] = tv->field->board[to];
tv->field->field[to] = tv->field->squareIsFree; tv->field->board[to] = tv->field->squareIsFree;
// store predecessor // store predecessor
tv->storePredecessor(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, amountOfPred, predVars); tv->storePredecessor(numberOfMillsCurrentPlayer, numberOfMillsOpponentPlayer, amountOfPred, predVars);
// undo move // undo move
tv->field->field[to] = tv->field->field[from]; tv->field->board[to] = tv->field->board[from];
tv->field->field[from] = tv->field->squareIsFree; tv->field->board[from] = tv->field->squareIsFree;
if (millWasClosed) { if (millWasClosed) {
numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[to]; numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[to];
@ -2267,15 +2267,15 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
for (from = 0; from < tv->field->size; from++) { for (from = 0; from < tv->field->size; from++) {
// square free? // square free?
if (tv->field->field[from] == tv->field->squareIsFree) { if (tv->field->board[from] == tv->field->squareIsFree) {
// stone mustn't be part of mill // stone mustn't be part of mill
if ((!(tv->field->field[tv->field->neighbour[from][0][0]] == tv->field->curPlayer->id && tv->field->field[tv->field->neighbour[from][0][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->field[tv->field->neighbour[from][1][0]] == tv->field->curPlayer->id && tv->field->field[tv->field->neighbour[from][1][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->field[from] = tv->field->curPlayer->id; tv->field->board[from] = tv->field->curPlayer->id;
tv->field->curPlayer->numStones++; tv->field->curPlayer->numStones++;
tv->field->curPlayer->numStonesMissing--; tv->field->curPlayer->numStonesMissing--;
@ -2294,7 +2294,7 @@ void perfectAI::getPredecessors(unsigned int threadNo, unsigned int *amountOfPre
// remove stone again // remove stone again
tv->field->stoneMustBeRemoved = 0; tv->field->stoneMustBeRemoved = 0;
tv->field->field[from] = tv->field->squareIsFree; tv->field->board[from] = tv->field->squareIsFree;
tv->field->curPlayer->numStones--; tv->field->curPlayer->numStones--;
tv->field->curPlayer->numStonesMissing++; tv->field->curPlayer->numStonesMissing++;
} }
@ -2352,7 +2352,7 @@ bool perfectAI::checkMoveAndSetSituation()
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->field[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i]; if (tv->field->board[i] == tv->field->curPlayer->id) numberOfMillsCurrentPlayer += tv->field->stonePartOfMill[i];
else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i]; else numberOfMillsOpponentPlayer += tv->field->stonePartOfMill[i];
} }
numberOfMillsCurrentPlayer /= 3; numberOfMillsCurrentPlayer /= 3;
@ -2360,7 +2360,7 @@ bool perfectAI::checkMoveAndSetSituation()
// precalc aStoneCanBeRemovedFromCurPlayer // precalc aStoneCanBeRemovedFromCurPlayer
for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) { for (aStoneCanBeRemovedFromCurPlayer = false, i = 0; i < tv->field->size; i++) {
if (tv->field->stonePartOfMill[i] == 0 && tv->field->field[i] == tv->field->curPlayer->id) { if (tv->field->stonePartOfMill[i] == 0 && tv->field->board[i] == tv->field->curPlayer->id) {
aStoneCanBeRemovedFromCurPlayer = true; aStoneCanBeRemovedFromCurPlayer = true;
break; break;
} }
@ -2509,7 +2509,7 @@ bool perfectAI::checkGetPredThanGetPoss()
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
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->field[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->field); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->board[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; 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;
@ -2518,7 +2518,7 @@ 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++) tv->field->field[k] = -1 * tv->field->field[k]; for (k = 0; k < tv->field->size; 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);
@ -2529,13 +2529,13 @@ bool perfectAI::checkGetPredThanGetPoss()
} }
// regard used symmetry operation // regard used symmetry operation
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->field[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->field); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->board[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; 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;
tv->field->oppPlayer->id = k; tv->field->oppPlayer->id = k;
for (k = 0; k < tv->field->size; k++) tv->field->field[k] = -1 * tv->field->field[k]; for (k = 0; k < tv->field->size; k++) tv->field->board[k] = -1 * tv->field->board[k];
} }
// get all possible moves // get all possible moves
@ -2565,7 +2565,7 @@ 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
setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers); setSituation(threadNo, predVars[j].predLayerNumbers, predVars[j].predStateNumbers);
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->field[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->field); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->board[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; 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;
@ -2574,7 +2574,7 @@ 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++) tv->field->field[k] = -1 * tv->field->field[k]; for (k = 0; k < tv->field->size; 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);
@ -2586,9 +2586,9 @@ 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++) tv->field->field[k] = -1 * tv->field->field[k]; for (k = 0; k < tv->field->size; 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++) symField[k] = tv->field->field[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->field); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->board[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->board);
for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill); for (k = 0; k < tv->field->size; k++) symField[k] = tv->field->stonePartOfMill[k]; applySymmetrieOperationOnField(reverseSymOperation[predVars[j].predSymOperation], (unsigned int *)symField, (unsigned int *)tv->field->stonePartOfMill);
printField(threadNo, 0); printField(threadNo, 0);
idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities); idPossibility = getPossibilities(threadNo, &numPossibilities, &isOpponentLevel, &pPossibilities);

View File

@ -37,7 +37,7 @@
#define NUM_STONES_PER_PLAYER 9 #define NUM_STONES_PER_PLAYER 9
#define NUM_STONES_PER_PLAYER_PLUS_ONE 10 #define NUM_STONES_PER_PLAYER_PLUS_ONE 10
// The Four Groups (the field position is divided in four groups A,B,C,D) // The Four Groups (the board position is divided in four groups A,B,C,D)
#define numSquaresGroupA 4 #define numSquaresGroupA 4
#define numSquaresGroupB 4 #define numSquaresGroupB 4
#define numSquaresGroupC 8 #define numSquaresGroupC 8
@ -110,8 +110,8 @@ protected:
twoBit shortValue; twoBit shortValue;
bool gameHasFinished; bool gameHasFinished;
bool settingPhase; bool settingPhase;
int fieldFrom, fieldTo; // value of field int fieldFrom, fieldTo; // value of board
unsigned int from, to; // index of field unsigned int from, to; // index of board
unsigned int curNumStones, oppNumStones; unsigned int curNumStones, oppNumStones;
unsigned int curPosMoves, oppPosMoves; unsigned int curPosMoves, oppPosMoves;
unsigned int curMissStones, oppMissStones; unsigned int curMissStones, oppMissStones;
@ -152,10 +152,10 @@ protected:
class threadVarsStruct class threadVarsStruct
{ {
public: public:
fieldStruct *field; // pointer of the current field [changed by move()] fieldStruct *field; // pointer of the current board [changed by move()]
float floatValue; // value of current situation for field->currentPlayer float floatValue; // value of current situation for board->currentPlayer
twoBit shortValue; // '' twoBit shortValue; // ''
bool gameHasFinished; // someone has won or current field is full bool gameHasFinished; // someone has won or current board is full
int ownId; // id of the player who called the play()-function int ownId; // id of the player who called the play()-function
unsigned int curSearchDepth; // current level unsigned int curSearchDepth; // current level
unsigned int depthOfFullTree; // search depth where the whole tree is explored unsigned int depthOfFullTree; // search depth where the whole tree is explored

View File

@ -96,7 +96,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 'field' 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(playerStruct *player) void Position::setUpCalcPossibleMoves(playerStruct *player)
{ {
@ -107,11 +107,11 @@ void Position::setUpCalcPossibleMoves(playerStruct *player)
for (j = 0; j < fieldStruct::size; j++) { for (j = 0; j < fieldStruct::size; j++) {
// is stone from player ? // is stone from player ?
if (field.field[i] != player->id) if (field.board[i] != player->id)
continue; continue;
// is destination free ? // is destination free ?
if (field.field[j] != field.squareIsFree) if (field.board[j] != field.squareIsFree)
continue; continue;
// when current player has only 3 stones he is allowed to spring his stone // when current player has only 3 stones he is allowed to spring his stone
@ -140,10 +140,10 @@ void Position::setUpCalcPossibleMoves(playerStruct *player)
void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour) void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour)
{ {
// locals // locals
int rowOwner = field.field[stone]; int rowOwner = field.board[stone];
// mill closed ? // mill closed ?
if (rowOwner != field.squareIsFree && field.field[firstNeighbour] == rowOwner && field.field[secondNeighbour] == rowOwner) { if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner) {
field.stonePartOfMill[stone]++; field.stonePartOfMill[stone]++;
field.stonePartOfMill[firstNeighbour]++; field.stonePartOfMill[firstNeighbour]++;
@ -153,7 +153,7 @@ void Position::setUpSetWarningAndMill(unsigned int stone, unsigned int firstNeig
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: put_piece() // Name: put_piece()
// Desc: Put a stone onto the field 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 Position::put_piece(unsigned int pos, int player)
{ {
@ -165,10 +165,10 @@ bool Position::put_piece(unsigned int pos, int player)
// check parameters // check parameters
if (player != fieldStruct::playerOne && player != fieldStruct::playerTwo) return false; if (player != fieldStruct::playerOne && player != fieldStruct::playerTwo) return false;
if (pos >= fieldStruct::size) return false; if (pos >= fieldStruct::size) return false;
if (field.field[pos] != field.squareIsFree) return false; if (field.board[pos] != field.squareIsFree) return false;
// set stone // set stone
field.field[pos] = player; field.board[pos] = player;
myPlayer->numStones++; myPlayer->numStones++;
field.stonesSet++; field.stonesSet++;
@ -193,7 +193,7 @@ bool Position::put_piece(unsigned int pos, int player)
// count completed mills // count completed mills
for (i = 0; i < fieldStruct::size; i++) { for (i = 0; i < fieldStruct::size; i++) {
if (field.field[i] == field.curPlayer->id) numberOfMillsCurrentPlayer += field.stonePartOfMill[i]; if (field.board[i] == field.curPlayer->id) numberOfMillsCurrentPlayer += field.stonePartOfMill[i];
else numberOfMillsOpponentPlayer += field.stonePartOfMill[i]; else numberOfMillsOpponentPlayer += field.stonePartOfMill[i];
} }
numberOfMillsCurrentPlayer /= 3; numberOfMillsCurrentPlayer /= 3;
@ -236,18 +236,18 @@ bool Position::settingPhaseHasFinished()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: getField() // Name: getField()
// Desc: Copy the current field state into the array 'pField'. // Desc: Copy the current board state into the array 'pField'.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Position::getField(int *pField) bool Position::getField(int *pField)
{ {
unsigned int index; unsigned int index;
// if no log is available than no game is in progress and field is invalid // if no log is available than no game is in progress and board is invalid
if (moveLogFrom == nullptr) return false; if (moveLogFrom == nullptr) return false;
for (index = 0; index < field.size; index++) { for (index = 0; index < field.size; index++) {
if (field.warnings[index] != field.noWarning) pField[index] = (int)field.warnings[index]; if (field.warnings[index] != field.noWarning) pField[index] = (int)field.warnings[index];
else pField[index] = field.field[index]; else pField[index] = field.board[index];
} }
return true; return true;
@ -271,7 +271,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 field struct. // Desc: Current player and opponent player are switched in the board struct.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::setNextPlayer() void Position::setNextPlayer()
{ {
@ -368,10 +368,10 @@ bool Position::isNormalMovePossible(unsigned int from, unsigned int to, playerSt
if (to >= field.size) return false; if (to >= field.size) return false;
// is stone from player ? // is stone from player ?
if (field.field[from] != player->id) return false; if (field.board[from] != player->id) return false;
// is destination free ? // is destination free ?
if (field.field[to] != field.squareIsFree) return false; if (field.board[to] != field.squareIsFree) return false;
// when current player has only 3 stones he is allowed to spring his stone // when current player has only 3 stones he is allowed to spring his stone
if (player->numStones > 3 || field.settingPhase) { if (player->numStones > 3 || field.settingPhase) {
@ -414,7 +414,7 @@ void Position::calcPossibleMoves(playerStruct *player)
// stoneMoveAble // stoneMoveAble
for (i = 0; i < field.size; i++) { for (i = 0; i < field.size; i++) {
for (j = 0; j < 4; j++) { for (j = 0; j < 4; j++) {
if (field.field[i] == player->id) field.stoneMoveAble[i][j] = isNormalMovePossible(i, field.connectedSquare[i][j], player); if (field.board[i] == player->id) field.stoneMoveAble[i][j] = isNormalMovePossible(i, field.connectedSquare[i][j], player);
else field.stoneMoveAble[i][j] = false; else field.stoneMoveAble[i][j] = false;
} }
} }
@ -427,11 +427,11 @@ void Position::calcPossibleMoves(playerStruct *player)
void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour, bool isNewStone) void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour, unsigned int secondNeighbour, bool isNewStone)
{ {
// locals // locals
int rowOwner = field.field[stone]; int rowOwner = field.board[stone];
unsigned int rowOwnerWarning = (rowOwner == field.playerOne) ? field.playerOneWarning : field.playerTwoWarning; unsigned int rowOwnerWarning = (rowOwner == field.playerOne) ? field.playerOneWarning : field.playerTwoWarning;
// mill closed ? // mill closed ?
if (rowOwner != field.squareIsFree && field.field[firstNeighbour] == rowOwner && field.field[secondNeighbour] == rowOwner) { if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == rowOwner && field.board[secondNeighbour] == rowOwner) {
field.stonePartOfMill[stone]++; field.stonePartOfMill[stone]++;
field.stonePartOfMill[firstNeighbour]++; field.stonePartOfMill[firstNeighbour]++;
@ -440,8 +440,8 @@ void Position::setWarningAndMill(unsigned int stone, unsigned int firstNeighbour
} }
//warning ? //warning ?
if (rowOwner != field.squareIsFree && field.field[firstNeighbour] == field.squareIsFree && field.field[secondNeighbour] == rowOwner) field.warnings[firstNeighbour] |= rowOwnerWarning; if (rowOwner != field.squareIsFree && field.board[firstNeighbour] == field.squareIsFree && field.board[secondNeighbour] == rowOwner) field.warnings[firstNeighbour] |= rowOwnerWarning;
if (rowOwner != field.squareIsFree && field.field[secondNeighbour] == field.squareIsFree && field.field[firstNeighbour] == rowOwner) field.warnings[secondNeighbour] |= rowOwnerWarning; if (rowOwner != field.squareIsFree && field.board[secondNeighbour] == field.squareIsFree && field.board[firstNeighbour] == rowOwner) field.warnings[secondNeighbour] |= rowOwnerWarning;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -470,7 +470,7 @@ void Position::updateMillsAndWarnings(unsigned int newStone)
for (i = 0; i < field.size; i++) field.stonePartOfMill[i] /= 3; for (i = 0; i < field.size; i++) field.stonePartOfMill[i] /= 3;
// no stone must be removed if each belongs to a mill // no stone must be removed if each belongs to a mill
for (atLeastOneStoneRemoveAble = false, i = 0; i < field.size; i++) if (field.stonePartOfMill[i] == 0 && field.field[i] == field.oppPlayer->id) atLeastOneStoneRemoveAble = true; for (atLeastOneStoneRemoveAble = false, i = 0; i < field.size; i++) if (field.stonePartOfMill[i] == 0 && field.board[i] == field.oppPlayer->id) atLeastOneStoneRemoveAble = true;
if (!atLeastOneStoneRemoveAble) field.stoneMustBeRemoved = 0; if (!atLeastOneStoneRemoveAble) field.stoneMustBeRemoved = 0;
} }
@ -496,7 +496,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
return false; return false;
// is it stone from the opponent ? // is it stone from the opponent ?
if (field.field[pushFrom] != field.oppPlayer->id) if (field.board[pushFrom] != field.oppPlayer->id)
return false; return false;
// is stone not part of mill? // is stone not part of mill?
@ -506,7 +506,7 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
// remove stone // remove stone
moveLogFrom[movesDone] = pushFrom; moveLogFrom[movesDone] = pushFrom;
moveLogTo[movesDone] = field.size; moveLogTo[movesDone] = field.size;
field.field[pushFrom] = field.squareIsFree; field.board[pushFrom] = field.squareIsFree;
field.oppPlayer->numStonesMissing++; field.oppPlayer->numStonesMissing++;
field.oppPlayer->numStones--; field.oppPlayer->numStones--;
field.stoneMustBeRemoved--; field.stoneMustBeRemoved--;
@ -539,13 +539,13 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
return false; return false;
// is destination free ? // is destination free ?
if (field.field[pushTo] != field.squareIsFree) if (field.board[pushTo] != field.squareIsFree)
return false; return false;
// set stone // set stone
moveLogFrom[movesDone] = field.size; moveLogFrom[movesDone] = field.size;
moveLogTo[movesDone] = pushTo; moveLogTo[movesDone] = pushTo;
field.field[pushTo] = field.curPlayer->id; field.board[pushTo] = field.curPlayer->id;
field.curPlayer->numStones++; field.curPlayer->numStones++;
field.stonesSet++; field.stonesSet++;
movesDone++; movesDone++;
@ -579,8 +579,8 @@ bool Position::do_move(unsigned int pushFrom, unsigned int pushTo)
// move stone // move stone
moveLogFrom[movesDone] = pushFrom; moveLogFrom[movesDone] = pushFrom;
moveLogTo[movesDone] = pushTo; moveLogTo[movesDone] = pushTo;
field.field[pushFrom] = field.squareIsFree; field.board[pushFrom] = field.squareIsFree;
field.field[pushTo] = field.curPlayer->id; field.board[pushTo] = field.curPlayer->id;
movesDone++; movesDone++;
// update warnings & mills // update warnings & mills
@ -621,7 +621,7 @@ bool Position::setCurrentGameState(fieldStruct *curState)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: compareWithField() // Name: compareWithField()
// Desc: Compares the current 'field' 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 Position::compareWithField(fieldStruct *compareField)
{ {
@ -647,8 +647,8 @@ bool Position::compareWithField(fieldStruct *compareField)
for (i = 0; i < field.size; i++) { for (i = 0; i < field.size; i++) {
if (field.field[i] != compareField->field[i]) { if (field.board[i] != compareField->board[i]) {
cout << "error - field[] differs!" << endl; ret = false; cout << "error - board[] differs!" << endl; ret = false;
} }
if (field.warnings[i] != compareField->warnings[i]) { if (field.warnings[i] != compareField->warnings[i]) {
cout << "error - warnings[] differs!" << endl; ret = false; cout << "error - warnings[] differs!" << endl; ret = false;
@ -662,7 +662,7 @@ bool Position::compareWithField(fieldStruct *compareField)
if (field.connectedSquare[i][j] != compareField->connectedSquare[i][j]) { if (field.connectedSquare[i][j] != compareField->connectedSquare[i][j]) {
cout << "error - connectedSquare[] differs!" << endl; ret = false; cout << "error - connectedSquare[] differs!" << endl; ret = false;
} }
// if (field.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; ret = false; cout << "error - neighbour differs!" << endl; ret = false;
} }
@ -705,7 +705,7 @@ bool Position::comparePlayers(playerStruct *playerA, playerStruct *playerB)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: printField() // Name: printField()
// Desc: Calls the printField() function of the current field. // Desc: Calls the printField() function of the current board.
// Prints the current game state on the screen. // Prints the current game state on the screen.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Position::printField() void Position::printField()
@ -715,7 +715,7 @@ void Position::printField()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Name: undo_move() // Name: undo_move()
// Desc: Sets the initial field 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 Position::undo_move(void)
{ {

View File

@ -38,8 +38,8 @@ private:
unsigned int *moveLogFrom, *moveLogTo, movesDone; // array containing the history of moves done unsigned int *moveLogFrom, *moveLogTo, movesDone; // array containing the history of moves done
millAI *playerOneAI; // class-pointer to the AI of player one millAI *playerOneAI; // class-pointer to the AI of player one
millAI *playerTwoAI; // class-pointer to the AI of player two millAI *playerTwoAI; // class-pointer to the AI of player two
fieldStruct field; // current field fieldStruct field; // current board
fieldStruct initialField; // undo of the last move is done by setting the initial field und performing all moves saved in history fieldStruct initialField; // undo of the last move is done by setting the initial board und performing all moves saved in history
int winner; // playerId of the player who has won the game. zero if game is still running. int winner; // playerId of the player who has won the game. zero if game is still running.
int beginningPlayer; // playerId of the player who makes the first move int beginningPlayer; // playerId of the player who makes the first move

View File

@ -45,7 +45,7 @@ void randomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
do { do {
from = rand() % theField->size; from = rand() % theField->size;
to = theField->size; to = theField->size;
} while (theField->field[from] != theField->oppPlayer->id || theField->stonePartOfMill[from]); } while (theField->board[from] != theField->oppPlayer->id || theField->stonePartOfMill[from]);
// still in setting phase ? // still in setting phase ?
} else if (theField->settingPhase) { } else if (theField->settingPhase) {
@ -54,7 +54,7 @@ void randomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
do { do {
from = theField->size; from = theField->size;
to = rand() % theField->size; to = rand() % theField->size;
} while (theField->field[to] != theField->squareIsFree); } while (theField->board[to] != theField->squareIsFree);
// try to push randomly // try to push randomly
} else { } else {
@ -63,13 +63,13 @@ void randomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
// search an own stone // search an own stone
do { do {
from = rand() % theField->size; from = rand() % theField->size;
} while (theField->field[from] != theField->curPlayer->id); } while (theField->board[from] != theField->curPlayer->id);
// select a free square // select a free square
if (allowedToSpring) { if (allowedToSpring) {
do { do {
to = rand() % theField->size; to = rand() % theField->size;
} while (theField->field[to] != theField->squareIsFree); } while (theField->board[to] != theField->squareIsFree);
// select a connected square // select a connected square
} else { } else {
@ -79,7 +79,7 @@ void randomAI::play(fieldStruct *theField, unsigned int *pushFrom, unsigned int
} while (to == theField->size); } while (to == theField->size);
} }
} while (theField->field[to] != theField->squareIsFree); } while (theField->board[to] != theField->squareIsFree);
} }
*pushFrom = from; *pushFrom = from;