coursework-1/ai.h

161 lines
3.9 KiB
C

#include "structure.h"
// #define AI_DEBUG
#define AI_NAIVE 1
#define AI_NOT_NAIVE 0
int AI_NAIVE_MODE = ; // switches 'naive mode'
#define AI_DEPTH_EASY 3
#define AI_DEPTH_MEDIUM 3
#define AI_DEPTH_HARD 5
#define AI_DEPTH_SUPERHARD 9
int AI_DEPTH = 3;
int miniMaxHandler(struct GAME* game, int turn, int maxDepth)
{
struct GAME game_copy = *game;
}
int miniMaxField(struct FIELD field, int turn, int maxDepth, int curDepth, int* retX, int* retY) // default curdepth = 1
{
int result = 0;
if (curDepth > maxDepth)
{
return 0;
}
if (field.winner != 0)
{
return field.winner;
}
#ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("=== minimax on depth %d, Turn: %d\n\n", curDepth, turn);
#endif
int peakScore = turn * (-3);
// cord's of the best score
int peakX = 1;
int peakY = 1;
int lastX, lastY;
for (int i = 0; i < MAP_SIZE; i++)
{
for (int j = 0; j < MAP_SIZE; j++)
{
if (field.fieldCells[i][j] != 0)
{
continue;
}
// remember the last empty cell for ai if it is not
// enough deep for making smart turn
lastX = i; lastY = j;
#ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("=== %d %d ===\n", i, j);
#endif
struct FIELD tmpField = field; // temporary field for calculating best move
tmpField.fieldCells[i][j] = turn; // making turn
tmpField.FUpdateFieldScore(&tmpField);
tmpField.winner = FCheckFieldWin(&tmpField);
result = miniMaxField(tmpField, turn * (-1), maxDepth, curDepth + 1, NULL, NULL);
if (result == 0)
{
printf("DRAW!\n");
}
if (curDepth == 1)
{
printf("res (%d %d): %d\n", i, j, result);
}
// find desired score
if ((turn < 0 && result < peakScore) || (turn > 0 && result > peakScore))
{
if (result == 0 || result == MAP_SIZE || result == MAP_SIZE * (-1))
{
peakScore = result;
peakX = i; peakY = j;
if (curDepth == 1)
printf("writtern peek: %d %d : %d\n", turn, result, peakScore);
}
}
else
{
if (curDepth == 1)
printf("nope... peek: %d %d : %d\n", turn, result, peakScore);
continue;
}
#ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("Peak : %d\n", peakScore);
#endif
}
}
#ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("Abs.Local Peak : %d\n", peakScore);
#endif
if (curDepth == 1)
{
if (field.fieldCells[peakX][peakY] != 0)
{
// #ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("%d %d -- LAST\n", peakX, peakY);
// #endif
peakX = lastX;
peakY = lastY;
}
#ifdef AI_DEBUG
for (int ts = 1; ts < curDepth; ts++) printf("\t");
printf("MOVE: %d %d\n", peakX, peakY);
#endif
if (retX != NULL && retY != NULL)
{
*retX = peakX;
*retY = peakY;
}
}
if (!NAIVE_MODE)
{
if (FCheckFieldDraw(&field) && FCheckFieldWin(&field) == 0)
{
return 0;
}
}
return peakScore;
}
int AIMakeMove(struct GAME* game)
{
if (game->locked)
{
int retX, retY;
miniMaxField(game->gameMap.FMap[game->lockedX][game->lockedY],
game->turn, AI_DEPTH, &retX, &retY);
GMakeMove(game, game->lockedX, game->lockedY, retX, retY, game->turn);
}
else
{
printf("TBD!\n");
return EXIT_FAILURE;
}
}