예제 #1
0
/*
 * Main function for getting all of the moves currently possible for a player. 
 *
 * @params: (player) - the player whose moves are to be put in the list
 * @return: a list of all moves currently possible for the player, or NULL if any allocation errors occurred 
 */
struct LinkedList* Board_getPossibleMoves(char** board, int player){
	struct LinkedList* possibleJumpMoves = getPossibleJumps(board, player);
	if (possibleJumpMoves == NULL){ // allocation failed
		return NULL;
	}
	if (LinkedList_length(possibleJumpMoves) != 0){ /* if jumps are possible, they are the only type of move legally possible */
		struct LinkedList* trimmedJumpMoves = trimJumpMovesList(possibleJumpMoves);
		if(trimmedJumpMoves == NULL){ // allocation failed
			LinkedList_free(possibleJumpMoves);
			return NULL;
		}
		return trimmedJumpMoves;
	}
	LinkedList_free(possibleJumpMoves);
	struct LinkedList* singleMoves = getPossibleSingleMoves(board, player);
	if (singleMoves == NULL){ // allocation failed
		return NULL;
	}
	
	return singleMoves;
}	
예제 #2
0
unsigned int RenderBatch_getDrawableCount(RenderBatch* batch)
{
    return LinkedList_length(batch->drawables);

}
예제 #3
0
/*
 * The minimax AI algorithm.
 */
int alphabeta(PossibleMove* possibleMove, int depth, int player, int alpha, int beta){
	int (*evaluationFunction)(Board*, int, int) = (maxRecursionDepth == BEST)?
				&Board_getBetterScore:
				&Board_getScore;
	int thisBoardScore = evaluationFunction(possibleMove->board, turn, player);
	// maximum depth reached or game is over or allocation error occurred in Board_getScore
	if (depth == 1 || thisBoardScore == 10000 || thisBoardScore == -10000 || thisBoardScore == -10001){
		return thisBoardScore;
	}
	
	Board* board = possibleMove->board;
	LinkedList* possibleMoves = Board_getPossibleMoves(board, player);
	if (!possibleMoves){
		return -10001;
	}
	//terminal node
	if (LinkedList_length(possibleMoves) == 0){
		LinkedList_free(possibleMoves);
		return thisBoardScore;
	}
	//single child node
	if (LinkedList_length(possibleMoves) == 1){
		PossibleMove* onlyMove = PossibleMoveList_first(possibleMoves);
		int score = evaluationFunction(onlyMove->board, turn, player);
		LinkedList_free(possibleMoves);
		return score;
	}

	int extremum = (player == turn)? INT_MIN : INT_MAX;
	Iterator iterator;
	Iterator_init(&iterator, possibleMoves);
	while (Iterator_hasNext(&iterator)) {
		PossibleMove* currentPossibleMove = (PossibleMove*)Iterator_next(&iterator);
		int score = alphabeta(currentPossibleMove, depth-1, !player, alpha, beta);
		if (score == -10001){ //allocation error occured
			extremum = score;
			break;
		}
		if (	(player != turn && score <  extremum) || 
				(player == turn && score >  extremum) || 
				(rand()%2       && score == extremum)
			){
			extremum = score;
		}
		//game over - no need to evaluate further moves
		// if (extremum == 10000 || extremum == -10000){
			// break;
		// }
		//alpha-beta pruning
		if (turn == player){
			alpha = (score > alpha)? score: alpha;
			if (alpha >= beta){
				break;
			}	
		}
		else{
			beta = (score < beta)? score: beta;
			if (beta <= alpha){
				break;
			}
		}

	}
	LinkedList_free(possibleMoves);
	return extremum;
}