/*Wrapper function, adds legal Pawn Moves from Location to Linked List*/ int getPawnMoves(Game *game, Location *loc, ListNode *temp){ int flag = 0; if (canMoveUK(game->board, loc, 1) && isEmpty(game->board[loc->column][loc->row + shiftUp(game->board, loc)])){ Move *move = setMove(loc, setLocation(loc->column, loc->row + shiftUp(game->board, loc)), NONETYPE); if (isValidMove(game, move)){ getPawnSingleMove(game->board, loc, temp, move); flag = 1; } else{ freeMove(move); } } if (canMoveULK(game->board, loc, 1) && isOpposite(game->board[loc->column + shiftLeft(game->board, loc)][loc->row + shiftUp(game->board, loc)], game->board, loc)){ Move *move = setMove(loc, setLocation(loc->column + shiftLeft(game->board, loc), loc->row + shiftUp(game->board, loc)), NONETYPE); if (isValidMove(game, move)){ getPawnSingleMove(game->board, loc, temp, move); flag = 1; } else{ freeMove(move); } } if (canMoveURK(game->board, loc, 1) && isOpposite(game->board[loc->column + shiftRight(game->board, loc)][loc->row + shiftUp(game->board, loc)], game->board, loc)){ Move *move = setMove(loc, setLocation(loc->column + shiftRight(game->board, loc), loc->row + shiftUp(game->board, loc)), NONETYPE); if (isValidMove(game, move)){ getPawnSingleMove(game->board, loc, temp, move); flag = 1; } else{ freeMove(move); } } return flag; }
/*Add legal Moves for Bishop/Rook/Queen/King at Location to Linked List*/ int getBRQKMoves(Game *game, Location *loc, ListNode *temp){ int killflag, blockedflag, i, j, dist, len; int flag = 0; MoveType type; MoveType *list = getMoveTypeList(game->board, loc); len = getMoveTypeListLength(game->board, loc); for (i = 0; i < len; i++){ killflag = 0; blockedflag = 0; type = list[i]; dist = distFrom(game->board, loc, type); if (isKing(game->board, loc) && dist>0){ dist = 1; } for (j = 1; j <= dist&&!killflag&&!blockedflag; j++){ Location *tLoc = setLocation(loc->column + shiftCol(game->board, loc, type)*j, loc->row + shiftRow(game->board, loc, type)*j); if (legalMoveToKing(game, loc, tLoc)){ Move *move = setMove(loc, tLoc, NONETYPE); if (isValidMove(game, move)){ addMoveToList(temp, move); flag = 1; } else{ freeMove(move); } } else{ free(tLoc); } } } return flag; }
void freeMoves(MoveList* list) { MoveList* head = list; while(head){ MoveList* next = head->next; freeMove(head->data); free(head); head = next; } }
/*Add legal Moves for Knight at Location to Linked List*/ int getKnightSingleMove(Game *game, Location *loc, ListNode *temp, MoveType type){ MoveType col; MoveType row; char c; int flag = 0; switch (type) { case UR:col = R; row = U; break; case UL:col = L; row = U; break; case DL:col = L; row = D; break; case DR:col = R; row = D; break; case U:row = U; case D:row = D; case L:col = L; case R:row = R; } if (canMoveK(game->board, loc, 1, col) && canMoveK(game->board, loc, 2, row)){ c = game->board[loc->column + shiftCol(game->board, loc, col)][loc->row + shiftRow(game->board, loc, row) * 2]; if (isEmpty(c) || isOpposite(c, game->board, loc)){ Move *move = setMove(loc, setLocation(loc->column + shiftCol(game->board, loc, col), loc->row + shiftRow(game->board, loc, row) * 2), NONETYPE); if (isValidMove(game, move)){ addMoveToList(temp, move); flag = 1; } else{ freeMove(move); } } } if (canMoveK(game->board, loc, 2, col) && canMoveK(game->board, loc, 1, row)){ c = game->board[loc->column + shiftCol(game->board, loc, col) * 2][loc->row + shiftRow(game->board, loc, row)]; if (isEmpty(c) || isOpposite(c, game->board, loc)){ Move *move = setMove(loc, setLocation(loc->column + shiftCol(game->board, loc, col) * 2, loc->row + shiftRow(game->board, loc, row)), NONETYPE); if (isValidMove(game, move)){ addMoveToList(temp, move); flag = 1; } else{ freeMove(move); } } } return flag; }
/*Get Computer Move and Update Board*/ int getComputerMove(Game *game) { Move *move = getMinimaxMove(game, oppositeCol(getUserColorBit(game->settings))); int res; printf("%s", COMPUTER_MOVE); printMove(move); updateBoard(game, move); freeMove(move); res = gameOver(game, getUserColorBit(game->settings)); return res; }
void TickCache::dropOldest() { AssertFatal(mTickCacheHead->oldest,"Popping off too many tick cache entries"); TickCacheEntry * oldest = mTickCacheHead->oldest; mTickCacheHead->oldest = oldest->next; if (oldest->move) freeMove(oldest->move); freeEntry(oldest); mTickCacheHead->numEntry--; if (mTickCacheHead->numEntry < 2) mTickCacheHead->newest = mTickCacheHead->oldest; }
void TickCache::dropNextOldest() { AssertFatal(mTickCacheHead->oldest && mTickCacheHead->numEntry>1,"Popping off too many tick cache entries"); TickCacheEntry * oldest = mTickCacheHead->oldest; TickCacheEntry * nextoldest = mTickCacheHead->oldest->next; oldest->next = nextoldest->next; if (nextoldest->move) freeMove(nextoldest->move); freeEntry(nextoldest); mTickCacheHead->numEntry--; if (mTickCacheHead->numEntry==1) mTickCacheHead->newest = mTickCacheHead->oldest; }
/*Add legal Moves for Pawn at Location to Linked List*/ void getPawnSingleMove(char board[BOARD_SIZE][BOARD_SIZE], Location *loc, ListNode *temp, Move *move){ int i; if (loc->row + shiftUp(board, loc) == topLimit(board, loc)){ for (i = 0; i < sizeof(PROMOTIONS) / sizeof(Type); i++){ Move *newMove = copyMove(move); newMove->promotion = PROMOTIONS[i]; addMoveToList(temp, newMove); } freeMove(move); } else{ addMoveToList(temp, move); } }
/*Build Minimax Tree of fixed depth via DFS*/ MinimaxNode *getMinimaxTreeFixedDepth(Game *game, int depth, Move *move, Color uCol) { MinimaxNode *curr = (MinimaxNode*)malloc(sizeof(MinimaxNode)); if (curr == NULL) exitOnError("malloc"); curr->game = (Game*)malloc(sizeof(Game)); if (curr->game == NULL) exitOnError("malloc"); struct ListNode *moves; int i = 0; curr->depth = depth; copyGame(game, curr->game); curr->sons = NULL; curr->sonsK = 0; if (move != NULL) { updateBoard(curr->game, move); } if (depth == 1) { curr->move = move; } else { freeMove(move); curr->move = NULL; } if (depth == game->difficulty) { return curr; } if ((depth % 2 == 0 && uCol == WHITE) || (depth % 2 == 1 && uCol == BLACK)) { moves = getMoves(curr->game, WHITE); } else { moves = getMoves(curr->game, BLACK); } int size = listSize(moves); curr->sonsK = size; if (!size) { free(moves); return curr; } else { curr->sons = (MinimaxNode**)malloc(sizeof(MinimaxNode)*size); if (curr->sons == NULL) exitOnError("malloc"); struct ListNode *temp = moves; for (i = 0; i < size; i++) { Move* tMove = copyMove(temp->move); curr->sons[i] = getMinimaxTreeFixedDepth(curr->game, depth + 1, tMove, uCol); temp = temp->next; } freeList(moves); } return curr; }
/*Build Minimax Tree for Best Difficulty using BFS Algorithm*/ MinimaxNode *getMinimaxTreeBestDepth(Game *game, Color uCol) { MinimaxNode *root = (MinimaxNode*)malloc(sizeof(MinimaxNode)); if (root == NULL)exitOnError("malloc"); root->game = (Game*)malloc(sizeof(Game)); if (root->game == NULL) exitOnError("malloc"); root->val = 0; MinimaxNode *curr; ListNode *moves; int i; int leavesLocal = 1; Queue *q = setQueue(); /*Create empty Queue for BFS Traversing*/ int size = 0; root->depth = 0; root->move = NULL; copyGame(game, root->game); root->sons = NULL; root->sonsK = 0; enqueue(q, root); /*While Queue is not empty and there are less than MAX_BOARDS_TO_EVAL Leaves in Tree*/ while (q->size&&leavesLocal + size <= MAX_BOARDS_TO_EVAL) { curr = dequeue(q); /*Pop from Queue*/ if (curr->depth % 2 == 0)moves = getMoves(curr->game, uCol); /*Get possible Moves at current Board state*/ else moves = getMoves(curr->game, oppositeCol(uCol)); size = listSize(moves); if (!size) { free(moves); continue; } curr->sons = (MinimaxNode**)malloc(sizeof(MinimaxNode)*size); if (curr->sons == NULL) exitOnError("malloc"); curr->sonsK = size; ListNode *temp = moves; for (i = 0; i < size; i++) { /*Add Nodes for each possible Move*/ curr->sons[i] = (MinimaxNode*)malloc(sizeof(MinimaxNode)); if (curr->sons[i] == NULL) exitOnError("malloc"); curr->sons[i]->game = (Game*)malloc(sizeof(Game)); if (curr->sons[i]->game == NULL) exitOnError("malloc"); curr->sons[i]->val = 0; copyGame(curr->game, curr->sons[i]->game); Move* tMove = copyMove(temp->move); updateBoard(curr->sons[i]->game, tMove); curr->sons[i]->depth = curr->depth + 1; if (curr->sons[i]->depth == 1) { curr->sons[i]->move = tMove; } else { freeMove(tMove); curr->sons[i]->move = NULL; } curr->sons[i]->sons = NULL; curr->sons[i]->sonsK = 0; enqueue(q, curr->sons[i]); /*Push to Queue*/ temp = temp->next; } /*Update amount of Leaves in Tree*/ freeList(moves); leavesLocal += size; if (size) leavesLocal--; } freeQueue(q); return root; }
void Camera::mouseMove(int x, int y) { //rMessage() << "mousemove... "; freeMove(-x, -y); m_update(); GlobalCamera().movedNotify(); }