einfacherer Algorithmus, der nur Eckzüge und gegnerische Mobilität in
Betracht zieht
This commit is contained in:
parent
88bf2f215a
commit
c0d135fae2
|
@ -22,38 +22,38 @@ send_move(int row, int col)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
//int
|
||||||
buildTree(gameTree *currentNode, cell (*field)[fieldSize], movesList *moves, int depth, char enemyc) {
|
//buildTree(gameTree *currentNode, cell (*field)[fieldSize], movesList *moves, int depth, char enemyc) {
|
||||||
if (depth == 0 || moves->movesNumber == 0)
|
// if (depth == 0 || moves->movesNumber == 0)
|
||||||
return 0;
|
// return 0;
|
||||||
currentNode->numChildMoves = moves->movesNumber;
|
// currentNode->numChildMoves = moves->movesNumber;
|
||||||
currentNode->childMove = new gameTree[maxMoves]();
|
// currentNode->childMove = new gameTree[maxMoves]();
|
||||||
//switch stone char
|
// //switch stone char
|
||||||
char ownc = getEnemyChar(enemyc);
|
// char ownc = getEnemyChar(enemyc);
|
||||||
|
//
|
||||||
//#ifdef debugprint
|
////#ifdef debugprint
|
||||||
// printf("Depth %d: enemy: %c\n", depth, enemyc);
|
//// printf("Depth %d: enemy: %c\n", depth, enemyc);
|
||||||
//#endif
|
////#endif
|
||||||
for(size_t i=0; i<moves->movesNumber; ++i)
|
// for(size_t i=0; i<moves->movesNumber; ++i)
|
||||||
{
|
// {
|
||||||
currentNode->childMove[i].nodeMove = moves->list[i];
|
// currentNode->childMove[i].nodeMove = moves->list[i];
|
||||||
size_t fieldMemSize = fieldSize*fieldSize*sizeof(cell);
|
// size_t fieldMemSize = fieldSize*fieldSize*sizeof(cell);
|
||||||
auto futureField = new cell[fieldSize][fieldSize]();
|
// auto futureField = new cell[fieldSize][fieldSize]();
|
||||||
memcpy(futureField, field, fieldMemSize);
|
// memcpy(futureField, field, fieldMemSize);
|
||||||
futureField[(moves->list[i].turnRow-1)][(moves->list[i].turnCol-1)].content=enemyc;
|
// futureField[(moves->list[i].turnRow-1)][(moves->list[i].turnCol-1)].content=enemyc;
|
||||||
movesList *futureMoves = new movesList();
|
// movesList *futureMoves = new movesList();
|
||||||
findMoves(futureField, futureMoves, enemyc);
|
// findMoves(futureField, futureMoves, enemyc);
|
||||||
buildTree(&(currentNode->childMove[i]), futureField, futureMoves, depth-1, getEnemyChar(enemyc));
|
// buildTree(&(currentNode->childMove[i]), futureField, futureMoves, depth-1, getEnemyChar(enemyc));
|
||||||
delete [] futureMoves;
|
// delete [] futureMoves;
|
||||||
delete [] futureField;
|
// delete [] futureField;
|
||||||
}
|
// }
|
||||||
return 1;
|
// return 1;
|
||||||
}
|
//}
|
||||||
|
|
||||||
move
|
move
|
||||||
maxEvalMove(std::vector<evalMove> *curMoves) {
|
maxEvalMove(std::vector<evalMove> *curMoves) {
|
||||||
evalMove maxM;
|
evalMove maxM;
|
||||||
maxM.evaluation = -9;
|
maxM.evaluation = -99;
|
||||||
for(size_t i = 0; i < curMoves->size(); ++i)
|
for(size_t i = 0; i < curMoves->size(); ++i)
|
||||||
{
|
{
|
||||||
if(curMoves->at(i).evaluation > maxM.evaluation)
|
if(curMoves->at(i).evaluation > maxM.evaluation)
|
||||||
|
@ -65,59 +65,85 @@ maxEvalMove(std::vector<evalMove> *curMoves) {
|
||||||
return maxM.m;
|
return maxM.m;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
//int
|
||||||
maxInt(std::vector<int> *evaluations) {
|
//maxInt(std::vector<int> *evaluations) {
|
||||||
int maxE = -10;
|
// int maxE = -10;
|
||||||
for(size_t i = 0; i<evaluations->size(); ++i)
|
// for(size_t i = 0; i<evaluations->size(); ++i)
|
||||||
{
|
// {
|
||||||
if(evaluations->at(i) > maxE)
|
// if(evaluations->at(i) > maxE)
|
||||||
{
|
// {
|
||||||
maxE = evaluations->at(i);
|
// maxE = evaluations->at(i);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return maxE;
|
// return maxE;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
//MiniMax Algorithmus
|
////MiniMax Algorithmus
|
||||||
int
|
//int
|
||||||
eval(gameTree *currentNode, int depth) {
|
//eval(gameTree *currentNode, int depth) {
|
||||||
if (depth == 0 || !currentNode->numChildMoves)
|
// if (depth == 0 || !currentNode->numChildMoves)
|
||||||
{
|
// {
|
||||||
//gut: hohe Mobilität, Eckzüge. Schlecht: Züge auf Felder direkt vor der Ecke
|
// //gut: hohe Mobilität, Eckzüge. Schlecht: Züge auf Felder direkt vor der Ecke
|
||||||
return (currentNode->numChildMoves + 5*isCornerField(currentNode->nodeMove) - 2*isCOrXField(currentNode->nodeMove));
|
// return (currentNode->numChildMoves + 5*isCornerField(currentNode->nodeMove) - 2*isCOrXField(currentNode->nodeMove));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
std::vector<int> curEvals;
|
// std::vector<int> curEvals;
|
||||||
for(size_t i = 0; i < currentNode->numChildMoves; ++i)
|
// for(size_t i = 0; i < currentNode->numChildMoves; ++i)
|
||||||
{
|
// {
|
||||||
int curEval = -1 * eval(&(currentNode->childMove[i]), depth-1);
|
// int curEval = -1 * eval(&(currentNode->childMove[i]), depth-1);
|
||||||
curEvals.push_back(curEval);
|
// curEvals.push_back(curEval);
|
||||||
}
|
// }
|
||||||
return maxInt(&curEvals);
|
// return maxInt(&curEvals);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//move
|
||||||
|
//findBestMove(gameTree *currentNode, int depth) {
|
||||||
|
// std::vector<evalMove> curMoves;
|
||||||
|
// for(size_t i = 0; i < currentNode->numChildMoves; ++i)
|
||||||
|
// {
|
||||||
|
// evalMove m;
|
||||||
|
// m.evaluation = -1 * eval(&(currentNode->childMove[i]), depth-1);
|
||||||
|
// m.m = currentNode->childMove[i].nodeMove;
|
||||||
|
//#ifdef debugprint
|
||||||
|
// printf("findBest %d: %d, %d\n", m.evaluation, m.m.turnRow, m.m.turnCol);
|
||||||
|
//#endif
|
||||||
|
// curMoves.push_back(m);
|
||||||
|
// }
|
||||||
|
// return maxEvalMove(&curMoves);
|
||||||
|
//}
|
||||||
|
|
||||||
move
|
move
|
||||||
findBestMove(gameTree *currentNode, int depth) {
|
nFindBestMove(cell (*field)[fieldSize], movesList *moves, char enemyc) {
|
||||||
std::vector<evalMove> curMoves;
|
std::vector<evalMove> curMoves;
|
||||||
for(size_t i = 0; i < currentNode->numChildMoves; ++i)
|
printf("NumOwnMoves: %d\n", moves->movesNumber);
|
||||||
|
for(size_t i=0; i < moves->movesNumber; ++i)
|
||||||
{
|
{
|
||||||
evalMove m;
|
|
||||||
m.evaluation = -1 * eval(&(currentNode->childMove[i]), depth-1);
|
|
||||||
m.m = currentNode->childMove[i].nodeMove;
|
|
||||||
#ifdef debugprint
|
#ifdef debugprint
|
||||||
printf("findBest %d: %d, %d\n", m.evaluation, m.m.turnRow, m.m.turnCol);
|
printf("EnemyMove %d ", i);
|
||||||
|
#endif
|
||||||
|
size_t fieldMemSize = fieldSize*fieldSize*sizeof(cell);
|
||||||
|
auto futureField = new cell[fieldSize][fieldSize]();
|
||||||
|
memcpy(futureField, field, fieldMemSize);
|
||||||
|
futureField[(moves->list[i].turnRow-1)][(moves->list[i].turnCol-1)].content=enemyc;
|
||||||
|
movesList *futureMoves = new movesList();
|
||||||
|
findMoves(futureField, futureMoves, enemyc);
|
||||||
|
evalMove m;
|
||||||
|
m.m = moves->list[i];
|
||||||
|
//gut: Eckzüge. Schlecht: hohe Mobilität des Gegners, Züge auf Felder direkt vor der Ecke
|
||||||
|
m.evaluation = 5*isCornerField(m.m) - futureMoves->movesNumber - 2*(!endgame)*isCOrXField(m.m);
|
||||||
|
#ifdef debugprint
|
||||||
|
printf("eval: %d, move: %d, %d\n", m.evaluation, m.m.turnRow, m.m.turnCol);
|
||||||
#endif
|
#endif
|
||||||
curMoves.push_back(m);
|
curMoves.push_back(m);
|
||||||
|
#ifdef debugprint
|
||||||
|
printf("m: (%d, %d) hat %d\n", m.m.turnRow, m.m.turnCol, m.evaluation);
|
||||||
|
#endif
|
||||||
|
delete [] futureMoves;
|
||||||
|
delete [] futureField;
|
||||||
}
|
}
|
||||||
return maxEvalMove(&curMoves);
|
return maxEvalMove(&curMoves);
|
||||||
}
|
}
|
||||||
|
|
||||||
//move
|
|
||||||
//nFindBestMove(cell (*field)[fieldSize], movesList *movesa) {
|
|
||||||
// std::vector<evalMove> curMoves;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
@ -177,16 +203,21 @@ int main(void)
|
||||||
printf("Nope\n");
|
printf("Nope\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
move finalMove;
|
||||||
|
if(moves->movesNumber == 1)
|
||||||
|
finalMove = moves->list[0];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
if((numX+numO)>5*fieldSize*fieldSize/6)
|
if((numX+numO)>5*fieldSize*fieldSize/6)
|
||||||
endgame = 1;
|
endgame = 1;
|
||||||
gameTree *treeRoot = new gameTree();
|
//gameTree *treeRoot = new gameTree();
|
||||||
treeRoot->nodeMove.turnRow = 0;
|
//treeRoot->nodeMove.turnRow = 0;
|
||||||
treeRoot->nodeMove.turnCol = 0;
|
//treeRoot->nodeMove.turnCol = 0;
|
||||||
buildTree(treeRoot, field, moves, 1, getEnemyChar(enemyc));
|
//buildTree(treeRoot, field, moves, 1, getEnemyChar(enemyc));
|
||||||
move finalMove = findBestMove(treeRoot, 1);
|
finalMove = nFindBestMove(field, moves, getEnemyChar(enemyc));
|
||||||
|
}
|
||||||
|
|
||||||
turn_row=finalMove.turnRow;
|
turn_row=finalMove.turnRow;
|
||||||
turn_col=finalMove.turnCol;
|
turn_col=finalMove.turnCol;
|
||||||
|
|
Loading…
Reference in a new issue